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 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 288 int WRAP(pthread_sigmask)(int portable_how, const sigset_portable_t *portable_sigset, 289 sigset_portable_t *portable_oldset) 290 { 291 extern int REAL(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset); 292 int portable_ret, ret; 293 294 ALOGV(" "); 295 ALOGV("%s(portable_how:%d portable_sigset:%p, portable_oldset:%p)", __func__, 296 portable_how, portable_sigset, portable_oldset); 297 298 ret = do_sigmask(portable_how, portable_sigset, portable_oldset, REAL(pthread_sigmask), NULL); 299 300 portable_ret = errno_ntop(ret); 301 302 ALOGV("%s: return portable_ret:%d; ret:%d;", __func__, 303 portable_ret, ret); 304 305 return portable_ret; 306 } 307 308 PTHREAD_WRAPPER(pthread_getcpuclockid, (pthread_t tid, clockid_t *clockid), (tid, clockid), 309 "(tid:%lx, clockid:%p)"); 310 311 PTHREAD_WRAPPER(pthread_once, (pthread_once_t *once_control, void (*init_routine)(void)), 312 (once_control, init_routine), "(once_control:%p, init_routine:%p)"); 313 314 PTHREAD_WRAPPER(pthread_setname_np, (pthread_t thid, const char *thname), (thid, thname), 315 "(thid:%lx, thname:\"%s\")"); 316