1 #include <functional> 2 #include <gtest/gtest.h> 3 #include <sys/mman.h> 4 #include <thread> 5 #include <threads.h> 6 7 using namespace testing::ext; 8 9 constexpr size_t TEST_MULTIPLE = 640; 10 constexpr size_t TEST_BASE = 1024; 11 12 class PthreadKeyTest : public testing::Test { SetUp()13 void SetUp() override {} TearDown()14 void TearDown() override {} 15 }; 16 17 /** 18 * @tc.name: pthread_key_create_001 19 * @tc.desc: Successfully created and deleted key. 20 * @tc.type: FUNC 21 * */ 22 HWTEST_F(PthreadKeyTest, pthread_key_create_001, TestSize.Level1) 23 { 24 pthread_key_t pthreadKey; 25 EXPECT_EQ(0, pthread_key_create(&pthreadKey, nullptr)); 26 EXPECT_EQ(0, pthread_key_delete(pthreadKey)); 27 } 28 29 /** 30 * @tc.name: pthread_key_create_002 31 * @tc.desc: Set the key for the thread until the key namespace is used up and counted, 32 * delete all, and finally verify that the technology is equal to expected 33 * @tc.type: FUNC 34 * */ 35 HWTEST_F(PthreadKeyTest, pthread_key_create_002, TestSize.Level1) 36 { 37 std::vector<pthread_key_t> pthreadKeys; 38 int falseNum = 0; 39 for (int i = 0; i < PTHREAD_KEYS_MAX; i++) { 40 pthread_key_t pthreadKey; 41 falseNum = pthread_key_create(&pthreadKey, nullptr); 42 if (falseNum == EAGAIN) { 43 break; 44 } 45 pthreadKeys.push_back(pthreadKey); 46 } 47 EXPECT_EQ(EAGAIN, falseNum); 48 for (const auto& pthreadKey : pthreadKeys) { 49 pthread_key_delete(pthreadKey); 50 } 51 pthreadKeys.clear(); 52 } 53 54 /** 55 * @tc.name: pthread_key_create_003 56 * @tc.desc: Successfully set attrStack address and size 57 * @tc.type: FUNC 58 * */ 59 HWTEST_F(PthreadKeyTest, pthread_key_create_003, TestSize.Level1) 60 { 61 pthread_key_t pthreadKey; 62 pthread_attr_t pthreadAttr; 63 const size_t stackSize = TEST_MULTIPLE * TEST_BASE; 64 pthread_key_create(&pthreadKey, nullptr); 65 void* attrStack = mmap(nullptr, stackSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 66 memset(attrStack, 0xff, stackSize); 67 pthread_attr_init(&pthreadAttr); 68 EXPECT_EQ(0, pthread_attr_setstack(&pthreadAttr, attrStack, stackSize)); __anon8cf96f240102(void* key) 69 auto dirtyKeyThread = [](void* key) -> void* { 70 if (key == nullptr) { 71 return nullptr; 72 } 73 return pthread_getspecific(*reinterpret_cast<pthread_key_t*>(key)); 74 }; 75 pthread_t thread; 76 pthread_create(&thread, &pthreadAttr, dirtyKeyThread, &pthreadKey); 77 void* attrStackResult; 78 pthread_join(thread, &attrStackResult); 79 EXPECT_EQ(nullptr, attrStackResult); 80 EXPECT_EQ(0, pthread_key_delete(pthreadKey)); 81 munmap(attrStack, stackSize); 82 } 83 84 /** 85 * @tc.name: pthread_key_delete_001 86 * @tc.desc: Created a certain number of pthread keys, traverse the keys array in reverse order, and delete each key. 87 * @tc.type: FUNC 88 * */ 89 HWTEST_F(PthreadKeyTest, pthread_key_delete_001, TestSize.Level1) 90 { 91 int keyCounts = PTHREAD_KEYS_MAX / 2; 92 std::vector<pthread_key_t> pthreadKeys; 93 for (int i = 0; i < keyCounts; ++i) { 94 pthread_key_t pthreadKey; 95 EXPECT_EQ(0, pthread_key_create(&pthreadKey, nullptr)); 96 pthreadKeys.push_back(pthreadKey); 97 } 98 for (auto& pthreadKey : pthreadKeys) { 99 EXPECT_EQ(0, pthread_key_delete(pthreadKey)); 100 } 101 pthreadKeys.clear(); 102 }