diff options
author | Jaymes Wilks <mjwilks@us.ibm.com> | 2019-02-18 05:35:01 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2019-03-11 17:08:46 -0500 |
commit | ff62338a569993f34032f02c04cf484a058aa9bd (patch) | |
tree | 8b79c2fa91a6972e02290dafcdade9b659ec4561 /src/usr/testcore/lib | |
parent | f5475890894b4d542f622cee27604de15b41bb4b (diff) | |
download | talos-hostboot-ff62338a569993f34032f02c04cf484a058aa9bd.tar.gz talos-hostboot-ff62338a569993f34032f02c04cf484a058aa9bd.zip |
Thread local storage: Update unit tests for thread local storage
Test cases now support TLS tests for:
- intra translation unit (already existed)
- inter translation unit, within the same module
- inter module
- trivial and non trivial constructors
- both orders of declaration and usage
Change-Id: I71681b00525bfe3e7906541e0b5b4c21a8556beb
RTC:147599
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72633
Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/testcore/lib')
-rw-r--r-- | src/usr/testcore/lib/makefile | 1 | ||||
-rw-r--r-- | src/usr/testcore/lib/tls.H | 189 |
2 files changed, 172 insertions, 18 deletions
diff --git a/src/usr/testcore/lib/makefile b/src/usr/testcore/lib/makefile index f9a9a470c..ea4b74ee4 100644 --- a/src/usr/testcore/lib/makefile +++ b/src/usr/testcore/lib/makefile @@ -30,6 +30,7 @@ MODULE = testsyslib TESTS = stltest.H #TODO RTC:204720 #TESTS += synctest.H +TESTS += tls.H SUBDIRS += runtime.d diff --git a/src/usr/testcore/lib/tls.H b/src/usr/testcore/lib/tls.H index 84f7906a0..ee9a9f423 100644 --- a/src/usr/testcore/lib/tls.H +++ b/src/usr/testcore/lib/tls.H @@ -28,18 +28,78 @@ #include <cxxtest/TestSuite.H> #include <sys/task.h> +#include "../tlsmod/nontrivialctor.H" + namespace __tls_test { - thread_local size_t foobar = 0xabcd1234; + const size_t THREADS_PER_TEST = 15; + constexpr size_t FOOBAR_INIT_VALUE = 0x4321dcba; + constexpr size_t FOOBAR_POST_VALUE = 0x4321dcbb; + + thread_local size_t foobar = FOOBAR_INIT_VALUE; + + extern thread_local NonTrivialCtor foobar_object; + + /** + * @brief Spawns a set of tasks and waits on them + * + * @param[in] i_pFnName Name of the function doing the spawning, for + * tracing + * @param[in] i_pFn Function pointer suitable for passing to a task_create + * call + */ + void spawnTasks( + const char* const i_pFnName, + void*(*i_pFn)(void*)) + { + std::vector<tid_t> tids; + for(size_t thread=0;thread<THREADS_PER_TEST;++thread) + { + const auto tid = task_create(i_pFn, nullptr); + TS_INFO("%s: created TID %d",i_pFnName,tid); + tids.push_back(tid); + } + for(const auto tid : tids) + { + int status = 0; + const auto tidWaitedOn = task_wait_tid(tid,&status,nullptr); + if(tidWaitedOn != tid) + { + TS_FAIL("%s: Failed to wait on TID %d; got return " + "value of %d",i_pFnName,tid,tidWaitedOn); + } + else if(status != TASK_STATUS_EXITED_CLEAN) + { + TS_FAIL("%s: TID %d exited with bad status of %d", + i_pFnName,tid,status); + } + else + { + TS_INFO("%s: Waited on TID %d",i_pFnName,tid); + } + + // Wait on all threads, despite any errors. + } + } + + /** + * @brief Tests that a simple thread local variable in this translation + * unit has the right initial value and right post increment value + */ void* test_tls(void* unused) { - decltype(foobar) rc; + TS_INFO(ENTER_MRK "test_tls"); - rc = foobar; - if(rc != 0xabcd1234) + do { + + decltype(foobar) rc = foobar; + if(rc != FOOBAR_INIT_VALUE) { - TS_FAIL("TLS not initialized correctly: %ld", rc); + TS_FAIL("test_tls: bad initial value; " + "expected 0x%016llX but got 0x%016llX", + FOOBAR_INIT_VALUE,rc); + break; } task_yield(); @@ -49,27 +109,120 @@ namespace __tls_test task_yield(); rc = foobar; - if(rc != 0xabcd1235) + if(rc != FOOBAR_POST_VALUE) { - TS_FAIL("TLS increment not operating correctly: %ld", rc); + TS_FAIL("test_tls: bad post value; " + "expected 0x%016llX but got 0x%016llX", + FOOBAR_POST_VALUE,rc); + break; } + } while(0); + + TS_INFO(EXIT_MRK "test_tls"); + return nullptr; } -}; -class LibcTlsTest : public CxxTest::TestSuite -{ - public: - void testTls() + /** + * @brief Tests that a complex object from another shared library + * has the right initial value and right post increment value + */ + void* test_from_other_module(void* unused) + { + TS_INFO(ENTER_MRK "test_from_other_module"); + + do { + + char* const thebytes = foobar_object.c_str(); + + if(strcmp(thebytes,foobar_object.INIT_VALUE)!=0) + { + TS_FAIL("test_from_other_module: bad initial value; " + "expected %s but got %s", foobar_object.INIT_VALUE, thebytes); + break; + } + + task_yield(); + + thebytes[0]++; + + task_yield(); + + if(strcmp(thebytes,foobar_object.POST_VALUE)!=0) { - auto t1 = task_create(__tls_test::test_tls, nullptr); - auto t2 = task_create(__tls_test::test_tls, nullptr); - auto t3 = task_create(__tls_test::test_tls, nullptr); - task_wait_tid(t1, nullptr, nullptr); - task_wait_tid(t2, nullptr, nullptr); - task_wait_tid(t3, nullptr, nullptr); + TS_FAIL("test_from_other_module: bad post value; " + "expected %s but got %s", foobar_object.POST_VALUE, thebytes); + break; } + } while (0); + + TS_INFO(EXIT_MRK "test_from_other_module"); + + return nullptr; + } + + /** + * @brief Support a remote shared library invoking a test whereby this + * shared library acts as the producer for the foobar variable + */ + void test_tls_call_other_module_producer() + { + TS_INFO(ENTER_MRK "test_tls_call_other_module_producer"); + spawnTasks("test_tls_call_other_module_producer", + __tls_test::test_tls); + TS_INFO(EXIT_MRK "test_tls_call_other_module_producer"); + } + + /** + * @brief Support a remote shared library invoking a test whereby this + * shared library acts as the consumer for the invoking library's + * variable + */ + void test_tls_call_other_module_consumer() + { + TS_INFO(ENTER_MRK "test_tls_call_other_module_consumer"); + spawnTasks("test_tls_call_other_module_consumer", + __tls_test::test_from_other_module); + TS_INFO(EXIT_MRK "test_tls_call_other_module_consumer"); + } + + /** + * @brief Return the init value for foobar + * + * @return size_t Foobar's expected init value + */ + size_t foobarInitValue() + { + return FOOBAR_INIT_VALUE; + } + + /** + * @brief Return the post value for foobar + * + * @return size_t Foobar's expected post value + */ + size_t foobarPostValue() + { + return FOOBAR_POST_VALUE; + } + +}; // End __tls_test namespace + +// Test TLS within a translation unit +class LibcTlsTest : public CxxTest::TestSuite +{ + public: + + /** + * @brief Simple test of a locally defined TLS variable + */ + void testTls() + { + TS_INFO(ENTER_MRK "testTls"); + __tls_test::spawnTasks("testTls",__tls_test::test_tls); + TS_INFO(EXIT_MRK "testTls"); + } }; #endif |