diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/makefile | 1 | ||||
-rw-r--r-- | src/usr/testcore/lib/makefile | 1 | ||||
-rw-r--r-- | src/usr/testcore/lib/tls.H | 189 | ||||
-rw-r--r-- | src/usr/testcore/makefile | 3 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/makefile | 38 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/nontrivial.C | 31 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/nontrivial.H | 103 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/nontrivialctor.H | 81 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/tlsfile.C | 36 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/tlsfile.H | 105 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/tlsmod.C | 31 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/tlsmod.H | 172 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/trivial.C | 31 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/trivial.H | 97 | ||||
-rw-r--r-- | src/usr/testcore/tlsmod/trivialctor.H | 79 |
15 files changed, 979 insertions, 19 deletions
diff --git a/src/makefile b/src/makefile index a9c918dd0..2dc4bcaa6 100644 --- a/src/makefile +++ b/src/makefile @@ -251,6 +251,7 @@ TESTCASE_MODULES += testerrl TESTCASE_MODULES += testhwas TESTCASE_MODULES += testvpd TESTCASE_MODULES += testsyslib +TESTCASE_MODULES += testtlsmod TESTCASE_MODULES += testscom TESTCASE_MODULES += $(if $(CONFIG_VPO_COMPILE),,testruntime) TESTCASE_MODULES += testintr 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 diff --git a/src/usr/testcore/makefile b/src/usr/testcore/makefile index 55b6c3831..c350d9055 100644 --- a/src/usr/testcore/makefile +++ b/src/usr/testcore/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2011,2016 +# Contributors Listed Below - COPYRIGHT 2011,2019 # [+] International Business Machines Corp. # # @@ -29,6 +29,7 @@ SUBDIRS += kernel.d SUBDIRS += rtloader.d SUBDIRS += memoize.d SUBDIRS += pir.d +SUBDIRS += tlsmod.d include ${ROOTPATH}/config.mk diff --git a/src/usr/testcore/tlsmod/makefile b/src/usr/testcore/tlsmod/makefile new file mode 100644 index 000000000..5e01aae5d --- /dev/null +++ b/src/usr/testcore/tlsmod/makefile @@ -0,0 +1,38 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/testcore/tlsmod/makefile $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2011,2019 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +ROOTPATH = ../../../.. + +MODULE = testtlsmod + +TESTS += tlsmod.H +TESTS += tlsfile.H +TESTS += nontrivial.H +TESTS += trivial.H + +OBJS += tlsfile.o +OBJS += nontrivial.o +OBJS += trivial.o +OBJS += tlsmod.o +include ${ROOTPATH}/config.mk diff --git a/src/usr/testcore/tlsmod/nontrivial.C b/src/usr/testcore/tlsmod/nontrivial.C new file mode 100644 index 000000000..58398d678 --- /dev/null +++ b/src/usr/testcore/tlsmod/nontrivial.C @@ -0,0 +1,31 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/nontrivial.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include "nontrivialctor.H" + +namespace __tls_test +{ + thread_local NonTrivialCtor tls_nontrivial; +}; diff --git a/src/usr/testcore/tlsmod/nontrivial.H b/src/usr/testcore/tlsmod/nontrivial.H new file mode 100644 index 000000000..82dfe3980 --- /dev/null +++ b/src/usr/testcore/tlsmod/nontrivial.H @@ -0,0 +1,103 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/nontrivial.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __TLSMOD_NONTRIVIAL_H +#define __TLSMOD_NONTRIVIAL_H + +#include <cxxtest/TestSuite.H> +#include <sys/task.h> +#include "nontrivialctor.H" +#include <string.h> + +namespace __tls_test +{ + + // @note: See src/usr/testcore/lib/tls.H for API definition + void spawnTasks( + const char* const i_pFnName, + void*(*i_pFn)(void*)); + + extern thread_local NonTrivialCtor tls_nontrivial; + + /** + * @brief Test which validates a non-trivial TLS variable + */ + void* test_tls_nontrivial(void* unused) + { + TS_INFO(ENTER_MRK "test_tls_nontrivial"); + + do { + + char* const thebytes = tls_nontrivial.c_str(); + + if(strcmp(thebytes,NonTrivialCtor::INIT_VALUE)!=0) + { + TS_FAIL("test_tls_nontrivial: bad initial value; " + "expected %s but got %s", + NonTrivialCtor::INIT_VALUE, thebytes); + break; + } + + task_yield(); + + thebytes[0]++; + + task_yield(); + + if(strcmp(thebytes,NonTrivialCtor::POST_VALUE)!=0) + { + TS_FAIL("test_tls_nontrivial: bad post value; " + "expected %s but got %s", + NonTrivialCtor::POST_VALUE, thebytes); + break; + } + + } while(0); + + TS_INFO(EXIT_MRK "test_tls_nontrivial"); + + return nullptr; + } + +}; // End __tls_test namespace + +// Test TLS for non trivial constructors +class LibcTlsTestNonTrivial : public CxxTest::TestSuite +{ + public: + + /** + * @brief Tests a non-trivial constructor TLS variable + */ + void testTlsNonTrivial() + { + TS_INFO(ENTER_MRK "testTlsNonTrivial"); + __tls_test::spawnTasks("testTlsNonTrivial", + __tls_test::test_tls_nontrivial); + TS_INFO(EXIT_MRK "testTlsNonTrivial"); + } +}; + +#endif // End __TLSMOD_NONTRIVIAL_H diff --git a/src/usr/testcore/tlsmod/nontrivialctor.H b/src/usr/testcore/tlsmod/nontrivialctor.H new file mode 100644 index 000000000..c051c8900 --- /dev/null +++ b/src/usr/testcore/tlsmod/nontrivialctor.H @@ -0,0 +1,81 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/nontrivialctor.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __TLSMOD_NONTRIVIALCTOR_H +#define __TLSMOD_NONTRIVIALCTOR_H + +#include <string.h> + +namespace __tls_test +{ + +class NonTrivialCtor +{ + char* bytes; + + public: + + static constexpr const char* const INIT_VALUE = "0123456789ABCDE"; + static constexpr const char* const POST_VALUE = "1123456789ABCDE"; + static constexpr const size_t NULL_SIZE = 1; + + /** + * @brief Build an object that allocates heap memory + */ + NonTrivialCtor() + { + bytes = new char[strlen(INIT_VALUE)+NULL_SIZE](); + strcpy(bytes,INIT_VALUE); + } + + /** + * @brief Return the object's string storage, allowing updates to it + * + * @return char* Pointer to the internal string + */ + char* c_str() const + { + return bytes; + } + + /** + * @brief Destructor + */ + ~NonTrivialCtor() + { + delete bytes; + bytes = nullptr; + } + + // Delete the copy/assignment (and move equivalents) constructors/operators + NonTrivialCtor(const NonTrivialCtor&) = delete; + NonTrivialCtor& operator=(const NonTrivialCtor&) = delete; + NonTrivialCtor(NonTrivialCtor&&) = delete; + NonTrivialCtor& operator=(NonTrivialCtor&&) = delete; +}; + +}; // End __tls_test namespace + +#endif // __TLSMOD_NONTRIVIALCTOR_H diff --git a/src/usr/testcore/tlsmod/tlsfile.C b/src/usr/testcore/tlsmod/tlsfile.C new file mode 100644 index 000000000..68d20aa5e --- /dev/null +++ b/src/usr/testcore/tlsmod/tlsfile.C @@ -0,0 +1,36 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/tlsfile.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <cxxtest/TestSuite.H> +#include <sys/task.h> + +namespace __tls_test +{ + extern constexpr size_t INTERFILE_INIT_VALUE = 0xabcd1234; + extern constexpr size_t INTERFILE_POST_VALUE = 0xabcd1235; + + thread_local size_t tls_interfile = 0xabcd1234; +}; + diff --git a/src/usr/testcore/tlsmod/tlsfile.H b/src/usr/testcore/tlsmod/tlsfile.H new file mode 100644 index 000000000..37102aacc --- /dev/null +++ b/src/usr/testcore/tlsmod/tlsfile.H @@ -0,0 +1,105 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/tlsfile.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __TLSMOD_TLSFILE_H +#define __TLSMOD_TLSFILE_H + +#include <cxxtest/TestSuite.H> +#include <sys/task.h> + +namespace __tls_test +{ + +// @note: see src/usr/testcore/lib/tls.H for API definition +void spawnTasks( + const char* const i_pFnName, + void*(*i_pFn)(void*)); + +extern size_t INTERFILE_INIT_VALUE; +extern size_t INTERFILE_POST_VALUE; + +extern thread_local size_t tls_interfile; + +/** + * @brief Test a TLS variable defined in a different file + */ +void* test_tls_interfile(void* unused) +{ + TS_INFO(ENTER_MRK "test_tls_interfile"); + + do { + + decltype(tls_interfile) rc = tls_interfile; + if(rc != INTERFILE_INIT_VALUE) + { + TS_FAIL("test_tls_interfile: bad initial value; " + "expected 0x%016llX but got 0x%016llX", + INTERFILE_INIT_VALUE,rc); + break; + } + + task_yield(); + + tls_interfile++; + + task_yield(); + + rc = tls_interfile; + if(rc != INTERFILE_POST_VALUE) + { + TS_FAIL("test_tls_interfile: bad post value; " + "expected 0x%016llX but got 0x%016llX", + INTERFILE_POST_VALUE,rc); + break; + } + + } while(0); + + TS_INFO(EXIT_MRK "test_tls_interfile"); + + return nullptr; +} + +}; // End __tls_test namespace + +// Test TLS between translation units (i.e. between files) +class LibcTlsTestFile : public CxxTest::TestSuite +{ + public: + + /** + * @brief Test as bunch of TLS vars in a different file + */ + void testTlsInterfile() + { + TS_INFO(ENTER_MRK "testTlsInterfile"); + __tls_test::spawnTasks("testTlsInterfile", + __tls_test::test_tls_interfile); + TS_INFO(EXIT_MRK "testTlsInterfile"); + } + +}; + +#endif // End __TLSMOD_TLSFILE_H diff --git a/src/usr/testcore/tlsmod/tlsmod.C b/src/usr/testcore/tlsmod/tlsmod.C new file mode 100644 index 000000000..8010cac44 --- /dev/null +++ b/src/usr/testcore/tlsmod/tlsmod.C @@ -0,0 +1,31 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/tlsmod.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include "nontrivialctor.H" + +namespace __tls_test +{ + thread_local NonTrivialCtor foobar_object; +}; diff --git a/src/usr/testcore/tlsmod/tlsmod.H b/src/usr/testcore/tlsmod/tlsmod.H new file mode 100644 index 000000000..a9ee3efef --- /dev/null +++ b/src/usr/testcore/tlsmod/tlsmod.H @@ -0,0 +1,172 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/tlsmod.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __TLSMOD_TLSMOD_H +#define __TLSMOD_TLSMOD_H + +#include <cxxtest/TestSuite.H> +#include <sys/task.h> +#include "nontrivialctor.H" + +namespace __tls_test +{ + +// @note: See src/usr/testcore/lib/tls.H for API definition +void spawnTasks( + const char* const i_pFnName, + void*(*i_pFn)(void*)); + +extern const size_t FOOBAR_INIT_VALUE; +extern const size_t FOOBAR_POST_VALUE; + +extern thread_local size_t foobar; + +extern thread_local NonTrivialCtor foobar_object; + +size_t foobarInitValue(); + +size_t foobarPostValue(); + +void test_tls_call_other_module_producer(); + +void test_tls_call_other_module_consumer(); + +/*** + * @brief Test to consume a TLS var from a different library + */ +void* test_tls_module_cons(void* unused) +{ + TS_INFO(ENTER_MRK "test_tls_module_cons"); + + do { + + decltype(foobar) rc = foobar; + if(rc != foobarInitValue()) + { + TS_FAIL("test_tls_module_cons: bad initial value; " + "expected 0x%016llX but got 0x%016llX", + foobarInitValue(),rc); + break; + } + + task_yield(); + + foobar++; + + task_yield(); + + rc = foobar; + if(rc != foobarPostValue()) + { + TS_FAIL("test_tls_module_cons: bad post value; " + "expected 0x%016llX but got 0x%016llX", + foobarPostValue(),rc); + break; + } + + } while(0); + + TS_INFO(EXIT_MRK "test_tls_module_cons"); + + return nullptr; +} + +/*** + * @brief Test to consume a TLS var from same library + */ +void* test_tls_module_prod(void* unused) +{ + TS_INFO(ENTER_MRK "test_tls_module_prod"); + + do { + + char* const thebytes = foobar_object.c_str(); + + if(strcmp(thebytes,NonTrivialCtor::INIT_VALUE)!=0) + { + TS_FAIL("test_tls_module_prod: bad initial value; " + "expected %s but got %s", foobar_object.INIT_VALUE, thebytes); + break; + } + + task_yield(); + + thebytes[0]++; + + task_yield(); + + if(strcmp(thebytes,NonTrivialCtor::POST_VALUE)!=0) + { + TS_FAIL("test_tls_module_prod: bad post value; " + "expected %s but got %s", foobar_object.POST_VALUE, thebytes); + break; + } + + } while(0); + + TS_INFO(EXIT_MRK "test_tls_module_prod"); + + return nullptr; +} + +}; // End __tls_test namespace + +// Test TLS between modules +class LibcTlsTestMod : public CxxTest::TestSuite +{ + public: + + /** + * @brief Test TLS var where local library accesses a var in another + * library, then call into that other library where it will access + * that same var locally. + */ + void testTlsConsumerFirst() + { + TS_INFO(ENTER_MRK "testTlsConsumerFirst"); + __tls_test::spawnTasks("testTlsConsumerFirst", + __tls_test::test_tls_module_cons); + TS_INFO(EXIT_MRK "testTlsConsumerFirst"); + + __tls_test::test_tls_call_other_module_producer(); + } + + /** + * @brief Test TLS var where the var is accessed from the local library, + * then call into a different library and have it access the same var + * from this library. + */ + void testTlsProducerFirst() + { + TS_INFO(ENTER_MRK "testTlsProducerFirst"); + __tls_test::spawnTasks("testTlsProducerFirst", + __tls_test::test_tls_module_prod); + TS_INFO(EXIT_MRK "testTlsProducerFirst"); + + __tls_test::test_tls_call_other_module_consumer(); + } +}; + +#endif // End __TLSMOD_TLSMOD_H diff --git a/src/usr/testcore/tlsmod/trivial.C b/src/usr/testcore/tlsmod/trivial.C new file mode 100644 index 000000000..57fb8dc7b --- /dev/null +++ b/src/usr/testcore/tlsmod/trivial.C @@ -0,0 +1,31 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/trivial.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include "trivialctor.H" + +namespace __tls_test +{ + thread_local TrivialCtor tls_trivial; +}; diff --git a/src/usr/testcore/tlsmod/trivial.H b/src/usr/testcore/tlsmod/trivial.H new file mode 100644 index 000000000..b3f9b2586 --- /dev/null +++ b/src/usr/testcore/tlsmod/trivial.H @@ -0,0 +1,97 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/trivial.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __TLSMOD_TRIVIAL_H +#define __TLSMOD_TRIVIAL_H + +#include <cxxtest/TestSuite.H> +#include <sys/task.h> +#include "trivialctor.H" +#include <string.h> + +namespace __tls_test +{ + extern thread_local TrivialCtor tls_trivial; + + /** + * @brief Test a thread local trivial constructor + */ + void* test_tls_trivial(void* unused) + { + TS_INFO(ENTER_MRK "test_tls_trivial"); + + do { + + size_t value = tls_trivial.getValue(); + + if(TrivialCtor::TRIVIAL_CTOR_INIT_VALUE != value) + { + TS_FAIL("test_tls_trivial: bad initial value; " + "expected 0x%016llX but got 0x%016llX", + TrivialCtor::TRIVIAL_CTOR_INIT_VALUE,value); + break; + } + + task_yield(); + + tls_trivial.setValue(++value); + value = 0; + + task_yield(); + + value = tls_trivial.getValue(); + + if(TrivialCtor::TRIVIAL_CTOR_POST_VALUE != value) + { + TS_FAIL("test_tls_trivial: bad post value; " + "expected 0x%016llX but got 0x%016llX", + TrivialCtor::TRIVIAL_CTOR_POST_VALUE,value); + break; + } + + } while(0); + + TS_INFO(EXIT_MRK "test_tls_trivial"); + + return nullptr; + } +}; + +// Test TLS for trivial constructors +class LibcTlsTestTrivial : public CxxTest::TestSuite +{ + public: + + /** + * @brief Test TLS trivial constructors + */ + void testTlsTrivial() + { + TS_INFO(ENTER_MRK "testTlsTrivial"); + __tls_test::spawnTasks("testTlsTrivial",__tls_test::test_tls_trivial); + TS_INFO(EXIT_MRK "testTlsTrivial"); + } +}; +#endif diff --git a/src/usr/testcore/tlsmod/trivialctor.H b/src/usr/testcore/tlsmod/trivialctor.H new file mode 100644 index 000000000..77d3a22b2 --- /dev/null +++ b/src/usr/testcore/tlsmod/trivialctor.H @@ -0,0 +1,79 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/tlsmod/trivialctor.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __TLSMOD_TRIVIALCTOR_H +#define __TLSMOD_TRIVIALCTOR_H + +#include <stdint.h> + +namespace __tls_test +{ + +// @note: src/usr/testcore/lib/tls.H for interface +void spawnTasks( + const char* const i_pFnName, + void*(*i_pFn)(void*)); + +class TrivialCtor +{ + size_t value; + + public: + + static constexpr const size_t TRIVIAL_CTOR_INIT_VALUE = 0xBADDEED5; + static constexpr const size_t TRIVIAL_CTOR_POST_VALUE = 0xBADDEED6; + + /** + * @brief Constructor; establishes initial value + */ + TrivialCtor() + : value(TRIVIAL_CTOR_INIT_VALUE) + { + } + + /** + * @brief Return internal value + * + * @return size_t Internal value + */ + size_t getValue() const + { + return value; + } + + /** + * @brief Set internal value + * + * @param[in] i_val Value to set + */ + void setValue(const size_t i_val) + { + value = i_val; + } +}; + +}; // End __tls_test namespace + +#endif // __TLSMOD_TRIVIALCTOR_H |