1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
3 */
4 /*
5 * Copyright (c) 2022 Huawei Device Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <signal.h>
20 #include <stdlib.h>
21 #include <threads.h>
22 #include <pthread.h>
23 #include <stdio.h>
24 #include <time.h>
25 #include <errno.h>
26 #include "test.h"
27
28 #define LOCK_SUCCESS (0)
29 #define LOCK_TIMEOUT (-1)
30 #define LOCK_WAIT_MAX_TIME_COUNT (50)
31 #define NSEC_TO_MS (1000000)
32 #define TRYLOCK_FAIL (-2)
33
34 static thrd_t thr;
35 static int count = 0;
36 pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
37
TrylockWithTimeout(pthread_mutex_t *mutex)38 int TrylockWithTimeout(pthread_mutex_t *mutex)
39 {
40 int rc;
41
42 int sleepCount = 0;
43
44 do {
45 rc = pthread_mutex_trylock(mutex);
46 if (rc == 0) {
47 return LOCK_SUCCESS;
48 } else if (rc != EBUSY) {
49 perror("pthread_mutex_trylock");
50 return TRYLOCK_FAIL;
51 }
52
53 struct timespec req = { .tv_sec = 0, .tv_nsec = NSEC_TO_MS * 10 }; // 等待10毫秒
54 nanosleep(&req, NULL);
55
56 sleepCount++;
57 if (sleepCount >= LOCK_WAIT_MAX_TIME_COUNT) {
58 return LOCK_TIMEOUT;
59 }
60 } while (1);
61 }
62
threadfuncA(void *arg)63 int threadfuncA(void *arg)
64 {
65 count++;
66 thrd_t id = thrd_current();
67 if (!(thrd_equal(id, thr))) {
68 t_error("%s thrd_current failed", __func__);
69 }
70
71 thrd_exit(thrd_success);
72 }
73
threadfuncB(void *arg)74 int threadfuncB(void *arg)
75 {
76 int result = TrylockWithTimeout(&g_mutex);
77 if (result == LOCK_SUCCESS) {
78 count++;
79 pthread_mutex_unlock(&g_mutex);
80 } else if (result == LOCK_TIMEOUT) {
81 t_error("Lock acquisition timed out.\n");
82 } else {
83 t_error("Error pthread_mutex_trylock.\n");
84 }
85
86 thrd_exit(thrd_success);
87 }
88
89 /**
90 * @tc.name : thrd_current_0100
91 * @tc.desc : Returns the identifier of the calling thread
92 * @tc.level : Level 0
93 */
thrd_current_0100(void)94 void thrd_current_0100(void)
95 {
96 int result;
97
98 result = thrd_create(&thr, threadfuncA, NULL);
99 if (result != thrd_success) {
100 t_error("%s thrd_create failed", __func__);
101 }
102
103 result = thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);
104 if (result != 0) {
105 t_error("%s thrd_sleep failed", __func__);
106 }
107
108 result = thrd_join(thr, NULL);
109 if (result != thrd_success) {
110 t_error("%s thrd_join failed", __func__);
111 }
112
113 if (count != 1) {
114 t_error("%s failed, count is %d", __func__, count);
115 }
116 count = 0;
117 }
118
119 /**
120 * @tc.name : thrd_current_0200
121 * @tc.desc : Create two threads to execute the same func
122 * @tc.level : Level 1
123 */
thrd_current_0200(void)124 void thrd_current_0200(void)
125 {
126 thrd_t thr1, thr2;
127 int result;
128
129 result = thrd_create(&thr1, threadfuncB, NULL);
130 if (result != thrd_success) {
131 t_error("%s thrd_create failed", __func__);
132 }
133
134 result = thrd_create(&thr2, threadfuncB, NULL);
135 if (result != thrd_success) {
136 t_error("%s thrd_create failed", __func__);
137 }
138
139 result = thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);
140 if (result != 0) {
141 t_error("%s thrd_sleep failed", __func__);
142 }
143
144 if (thrd_equal(thr1, thr2)) {
145 t_error("%s equal", __func__);
146 }
147
148 if (thrd_equal(thr1, thrd_current())) {
149 t_error("%s equal", __func__);
150 }
151
152 if (thrd_equal(thr2, thrd_current())) {
153 t_error("%s equal", __func__);
154 }
155
156 result = thrd_join(thr1, NULL);
157 if (result != thrd_success) {
158 t_error("%s thrd_join failed", __func__);
159 }
160
161 result = thrd_join(thr2, NULL);
162 if (result != thrd_success) {
163 t_error("%s thrd_join failed", __func__);
164 }
165
166 if (count != 2) {
167 t_error("%s failed, count is %d", __func__, count);
168 }
169 count = 0;
170 }
171
main(int argc, char *argv[])172 int main(int argc, char *argv[])
173 {
174 thrd_current_0100();
175 thrd_current_0200();
176 return t_status;
177 }