• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }