1 /*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <portability.h>
18 #include <pthread.h>
19 #include <time.h>
20 #include <signal.h>
21 #include <signal_portable.h>
22 #include <errno.h>
23 #include <errno_portable.h>
24
25 #define PORTABLE_TAG "pthread_portable"
26 #include <log_portable.h>
27
28 /*
29 * Macros for STRIP_PARENS() which is used below in PTHREAD_WRAPPER(); cpp magic from:
30 * http://boost.2283326.n4.nabble.com/preprocessor-removing-parentheses-td2591973.html
31 */
32 #define CAT(x, y) CAT_I(x, y)
33 #define CAT_I(x, y) x ## y
34
35 #define APPLY(macro, args) APPLY_I(macro, args)
36 #define APPLY_I(macro, args) macro args
37
38 #define STRIP_PARENS(x) EVAL((STRIP_PARENS_I x), x)
39 #define STRIP_PARENS_I(...) 1,1
40
41 #define EVAL(test, x) EVAL_I(test, x)
42 #define EVAL_I(test, x) MAYBE_STRIP_PARENS(TEST_ARITY test, x)
43
44 #define TEST_ARITY(...) APPLY(TEST_ARITY_I, (__VA_ARGS__, 2, 1))
45 #define TEST_ARITY_I(a,b,c,...) c
46
47 #define MAYBE_STRIP_PARENS(cond, x) MAYBE_STRIP_PARENS_I(cond, x)
48 #define MAYBE_STRIP_PARENS_I(cond, x) CAT(MAYBE_STRIP_PARENS_, cond)(x)
49
50 #define MAYBE_STRIP_PARENS_1(x) x
51 #define MAYBE_STRIP_PARENS_2(x) APPLY(MAYBE_STRIP_PARENS_2_I, x)
52 #define MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__
53
54 /*
55 * Call pthread function and convert return value (a native errno) to portable error number.
56 */
57 #define PTHREAD_WRAPPER(fn, DECLARGS, CALLARGS, fmt) \
58 int WRAP(fn) DECLARGS \
59 { \
60 int rv, portable_rv; \
61 \
62 ALOGV(" "); \
63 ALOGV("%s" fmt, __func__, STRIP_PARENS(CALLARGS)); \
64 rv = REAL(fn) CALLARGS; \
65 portable_rv = errno_ntop(rv); \
66 ALOGV("%s: return(portable_rv:%d); rv:%d;", __func__, \
67 portable_rv, rv); \
68 return portable_rv; \
69 }
70
71 PTHREAD_WRAPPER(pthread_attr_init, (pthread_attr_t *attr), (attr), "(attr:%p)");
72
73 PTHREAD_WRAPPER(pthread_attr_destroy, (pthread_attr_t *attr), (attr), "(attr:%p)");
74
75 PTHREAD_WRAPPER(pthread_attr_setdetachstate, (pthread_attr_t *attr, int state), (attr, state),
76 "(attr:%p, state:%d)");
77
78 PTHREAD_WRAPPER(pthread_attr_getdetachstate, (pthread_attr_t const *attr, int *state),
79 (attr, state), "(attr:%p, state:%p)");
80
81 PTHREAD_WRAPPER(pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy), (attr, policy),
82 "(attr:%p, policy:%d)");
83
84 PTHREAD_WRAPPER(pthread_attr_getschedpolicy, (pthread_attr_t const *attr, int *policy),
85 (attr, policy), "(attr:%p, policy:%p)");
86
87 PTHREAD_WRAPPER(pthread_attr_setschedparam,
88 (pthread_attr_t *attr, struct sched_param const *param), (attr, param),
89 "(attr:%p, param:%p)");
90
91 PTHREAD_WRAPPER(pthread_attr_getschedparam,
92 (pthread_attr_t const *attr, struct sched_param *param), (attr, param),
93 "(attr:%p, param:%p)");
94
95 PTHREAD_WRAPPER(pthread_attr_setstacksize, (pthread_attr_t *attr, size_t stack_size),
96 (attr, stack_size), "(attr:%p, stack_size:%d)");
97
98 PTHREAD_WRAPPER(pthread_attr_getstacksize, (pthread_attr_t const *attr, size_t *stack_size),
99 (attr, stack_size), "(attr:%p, stack_size:%p)");
100
101 PTHREAD_WRAPPER(pthread_attr_setstack, (pthread_attr_t *attr, void *stackaddr, size_t stack_size),
102 (attr, stackaddr, stack_size), "(attr:%p, stackaddr:%p, stack_size:%d)");
103
104 PTHREAD_WRAPPER(pthread_attr_getstack, (pthread_attr_t const *attr, void **stackaddr,
105 size_t *stack_size), (attr, stackaddr, stack_size),
106 "(attr:%p, stackaddr:%p stack_size:%p)");
107
108 PTHREAD_WRAPPER(pthread_attr_setguardsize, (pthread_attr_t *attr, size_t guard_size),
109 (attr, guard_size), "(attr:%p, guard_size:%d)");
110
111 PTHREAD_WRAPPER(pthread_attr_getguardsize, (pthread_attr_t const *attr, size_t *guard_size),
112 (attr, guard_size), "(attr:%p, guard_size:%p)");
113
114 PTHREAD_WRAPPER(pthread_attr_setscope, (pthread_attr_t *attr, int scope), (attr, scope),
115 "(attr:%p, scope:%d)");
116
117 PTHREAD_WRAPPER(pthread_attr_getscope, (pthread_attr_t const *attr), (attr), "(attr:%p)");
118
119 PTHREAD_WRAPPER(pthread_getattr_np, (pthread_t thid, pthread_attr_t *attr), (thid, attr),
120 "(thid:%lx, attr:%p)");
121
122 PTHREAD_WRAPPER(pthread_create, (pthread_t *thread, const pthread_attr_t *attr,
123 void *(*start_routine) (void *), void *arg),
124 (thread, attr, start_routine, arg),
125 "(thread:%p attr:%p, start_routine:%p, arg:%p)");
126
127 // void pthread_exit(void * retval);
128 PTHREAD_WRAPPER(pthread_join, (pthread_t thid, void **ret_val), (thid, ret_val),
129 "(thid:%lx, ret_val:%p)");
130
131 PTHREAD_WRAPPER(pthread_detach, (pthread_t thid), (thid), "(thid:%lx)");
132
133 // pthread_t pthread_self(void);
134 // int pthread_equal(pthread_t one, pthread_t two);
135
136 PTHREAD_WRAPPER(pthread_getschedparam, (pthread_t thid, int *policy, struct sched_param *param),
137 (thid, policy, param), "(thid:%lx, policy:%p, param:%p)");
138
139 PTHREAD_WRAPPER(pthread_setschedparam, (pthread_t thid, int policy,
140 struct sched_param const *param), (thid, policy, param),
141 "(thid:%lx, policy:%d, param:%p)");
142
143 PTHREAD_WRAPPER(pthread_mutexattr_init, (pthread_mutexattr_t *attr), (attr), "(attr:%p)");
144
145 PTHREAD_WRAPPER(pthread_mutexattr_destroy, (pthread_mutexattr_t *attr), (attr), "(attr:%p)");
146
147 PTHREAD_WRAPPER(pthread_mutexattr_gettype, (const pthread_mutexattr_t *attr, int *type),
148 (attr, type), "(attr:%p, type:%p)");
149
150 PTHREAD_WRAPPER(pthread_mutexattr_settype, (pthread_mutexattr_t *attr, int type), (attr, type),
151 "(attr:%p, type:%d)");
152
153 PTHREAD_WRAPPER(pthread_mutexattr_setpshared, (pthread_mutexattr_t *attr, int pshared),
154 (attr, pshared), "(attr:%p, pshared:%d)");
155
156 PTHREAD_WRAPPER(pthread_mutexattr_getpshared, (pthread_mutexattr_t *attr, int *pshared),
157 (attr, pshared), "(attr:%p, pshared:%p)");
158
159 PTHREAD_WRAPPER(pthread_mutex_init, (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr),
160 (mutex, attr), "(mutex:%p, attr:%p)");
161
162 PTHREAD_WRAPPER(pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), "(mutex:%p)");
163
164 PTHREAD_WRAPPER(pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), "(mutex:%p)");
165
166 PTHREAD_WRAPPER(pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), "(mutex:%p)");
167
168 PTHREAD_WRAPPER(pthread_mutex_trylock, (pthread_mutex_t *mutex), (mutex), "(mutex:%p)");
169
170 #if 0 /* MISSING FROM BIONIC */
171 PTHREAD_WRAPPER(pthread_mutex_timedlock, (pthread_mutex_t *mutex, struct timespec *ts),
172 (mutex, ts), "(mutex:%p, ts:%p)");
173 #endif /* MISSING */
174
175 PTHREAD_WRAPPER(pthread_condattr_init, (pthread_condattr_t *attr), (attr), "(attr:%p)");
176
177 PTHREAD_WRAPPER(pthread_condattr_getpshared, (pthread_condattr_t *attr, int *pshared),
178 (attr, pshared), "(attr:%p, pshared:%p)");
179
180 PTHREAD_WRAPPER(pthread_condattr_setpshared, (pthread_condattr_t* attr, int pshared),
181 (attr, pshared), "(attr:%p, pshared:%d)");
182
183 PTHREAD_WRAPPER(pthread_condattr_destroy, (pthread_condattr_t *attr), (attr), "(attr:%p)");
184
185 PTHREAD_WRAPPER(pthread_cond_init, (pthread_cond_t *cond, const pthread_condattr_t *attr),
186 (cond, attr), "(cond:%p, attr:%p)");
187
188 PTHREAD_WRAPPER(pthread_cond_destroy, (pthread_cond_t *cond), (cond), "(cond:%p)");
189
190 PTHREAD_WRAPPER(pthread_cond_broadcast, (pthread_cond_t *cond), (cond), "(cond:%p)");
191
192 PTHREAD_WRAPPER(pthread_cond_signal, (pthread_cond_t *cond), (cond), "(cond:%p)");
193
194 PTHREAD_WRAPPER(pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
195 (cond, mutex), "(cond:%p, mutex:%p)");
196
197 PTHREAD_WRAPPER(pthread_cond_timedwait, (pthread_cond_t *cond, pthread_mutex_t *mutex,
198 const struct timespec *abstime), (cond, mutex, abstime),
199 "(cond:%p, mutex:%p, abstime:%p)");
200
201 PTHREAD_WRAPPER(pthread_cond_timedwait_monotonic_np, (pthread_cond_t *cond,
202 pthread_mutex_t *mutex, const struct timespec *abstime),
203 (cond, mutex, abstime), "(cond:%p, mutex:%p, abstime:%p)");
204
205 PTHREAD_WRAPPER(pthread_cond_timedwait_monotonic, (pthread_cond_t *cond, pthread_mutex_t
206 *mutex, const struct timespec *abstime),
207 (cond, mutex, abstime), "(cond:%p, mutex:%p, abstime:%p)");
208
209 PTHREAD_WRAPPER(pthread_cond_timedwait_relative_np, (pthread_cond_t *cond, pthread_mutex_t *mutex,
210 const struct timespec *reltime), (cond, mutex, reltime),
211 "(cond:%p, mutex:%p, reltime:%p)");
212
213 PTHREAD_WRAPPER(pthread_cond_timeout_np, (pthread_cond_t *cond, pthread_mutex_t *mutex,
214 unsigned msecs), (cond, mutex, msecs), "(cond:%p, mutex:%p, msecs:%u)");
215
216 PTHREAD_WRAPPER(pthread_mutex_lock_timeout_np, (pthread_mutex_t *mutex, unsigned msecs),
217 (mutex, msecs), "(mutex:%p, msecs:%u)");
218
219 PTHREAD_WRAPPER(pthread_rwlockattr_init, (pthread_rwlockattr_t *attr), (attr), "(attr:%p)");
220
221 PTHREAD_WRAPPER(pthread_rwlockattr_destroy, (pthread_rwlockattr_t *attr), (attr), "(attr:%p)");
222
223 PTHREAD_WRAPPER(pthread_rwlockattr_setpshared, (pthread_rwlockattr_t *attr, int pshared),
224 (attr, pshared), "(attr:%p, pshared:%d)");
225
226 PTHREAD_WRAPPER(pthread_rwlockattr_getpshared, (pthread_rwlockattr_t *attr, int *pshared),
227 (attr, pshared), "(attr:%p, pshared:%p)");
228
229 PTHREAD_WRAPPER(pthread_rwlock_init, (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr),
230 (rwlock, attr), "(rwlock:%p, attr:%p)");
231
232 PTHREAD_WRAPPER(pthread_rwlock_destroy, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
233
234 PTHREAD_WRAPPER(pthread_rwlock_rdlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
235
236 PTHREAD_WRAPPER(pthread_rwlock_tryrdlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
237
238 PTHREAD_WRAPPER(pthread_rwlock_timedrdlock, (pthread_rwlock_t *rwlock,
239 const struct timespec *abs_timeout),
240 (rwlock, abs_timeout), "(rwlock:%p, abs_timeout:%p)");
241
242 PTHREAD_WRAPPER(pthread_rwlock_wrlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
243
244 PTHREAD_WRAPPER(pthread_rwlock_trywrlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
245
246 PTHREAD_WRAPPER(pthread_rwlock_timedwrlock, (pthread_rwlock_t *rwlock,
247 const struct timespec *abs_timeout), (rwlock, abs_timeout),
248 "(rwlock:%p, abs_timeout:%p)");
249
250 PTHREAD_WRAPPER(pthread_rwlock_unlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
251
252 PTHREAD_WRAPPER(pthread_key_create, (pthread_key_t *key, void (*destructor_function)(void *)),
253 (key, destructor_function), "(key:%p, destructor_function:%p)");
254
255 PTHREAD_WRAPPER(pthread_key_delete , (pthread_key_t key), (key), "(key:%x)");
256
257 PTHREAD_WRAPPER(pthread_setspecific, (pthread_key_t key, const void *value), (key, value),
258 "(key:%x, value:%p)");
259
260 // void *pthread_getspecific(pthread_key_t key);
261
WRAP(pthread_kill)262 int WRAP(pthread_kill)(pthread_t thread, int portable_signum)
263 {
264 char *portable_signame = map_portable_signum_to_name(portable_signum);
265 int mips_signum;
266 int portable_ret, ret;
267
268 ALOGV("%s(thread:%lx, portable_signum:%d)", __func__, thread, portable_signum);
269
270 mips_signum = signum_pton(portable_signum);
271
272 if ((portable_signum != 0) && (mips_signum == 0)) {
273 /* A signal MIPS doesn't support; all we can do is ignore it. */
274 ret = 0;
275 } else {
276 ALOGV("%s: calling pthread_kill(thread:%lx, mips_signum:%d);", __func__,
277 thread, mips_signum);
278 ret = REAL(pthread_kill)(thread, mips_signum);
279 }
280 portable_ret = errno_ntop(ret);
281
282 ALOGV("%s: return portable_ret:%d; ret:%d;", __func__,
283 portable_ret, ret);
284
285 return portable_ret;
286 }
287
WRAP(pthread_sigmask)288 int WRAP(pthread_sigmask)(int portable_how, const sigset_portable_t *portable_sigset,
289 sigset_portable_t *portable_oldset)
290 {
291 int portable_ret, ret;
292
293 ALOGV(" ");
294 ALOGV("%s(portable_how:%d portable_sigset:%p, portable_oldset:%p)", __func__,
295 portable_how, portable_sigset, portable_oldset);
296
297 ret = do_sigmask(portable_how, portable_sigset, portable_oldset, pthread_sigmask, NULL);
298
299 portable_ret = errno_ntop(ret);
300
301 ALOGV("%s: return portable_ret:%d; ret:%d;", __func__,
302 portable_ret, ret);
303
304 return portable_ret;
305 }
306
307 PTHREAD_WRAPPER(pthread_getcpuclockid, (pthread_t tid, clockid_t *clockid), (tid, clockid),
308 "(tid:%lx, clockid:%p)");
309
310 PTHREAD_WRAPPER(pthread_once, (pthread_once_t *once_control, void (*init_routine)(void)),
311 (once_control, init_routine), "(once_control:%p, init_routine:%p)");
312
313 PTHREAD_WRAPPER(pthread_setname_np, (pthread_t thid, const char *thname), (thid, thname),
314 "(thid:%lx, thname:\"%s\")");
315