Home | History | Annotate | Download | only in arch-mips
      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, int* scope), (attr, scope), "(attr:%p, scope:%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_rwlockattr_init, (pthread_rwlockattr_t *attr), (attr), "(attr:%p)");
    217 
    218 PTHREAD_WRAPPER(pthread_rwlockattr_destroy, (pthread_rwlockattr_t *attr), (attr), "(attr:%p)");
    219 
    220 PTHREAD_WRAPPER(pthread_rwlockattr_setpshared, (pthread_rwlockattr_t *attr, int  pshared),
    221                 (attr, pshared), "(attr:%p, pshared:%d)");
    222 
    223 PTHREAD_WRAPPER(pthread_rwlockattr_getpshared, (pthread_rwlockattr_t *attr, int *pshared),
    224                 (attr, pshared), "(attr:%p, pshared:%p)");
    225 
    226 PTHREAD_WRAPPER(pthread_rwlock_init, (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr),
    227                 (rwlock, attr), "(rwlock:%p, attr:%p)");
    228 
    229 PTHREAD_WRAPPER(pthread_rwlock_destroy, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
    230 
    231 PTHREAD_WRAPPER(pthread_rwlock_rdlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
    232 
    233 PTHREAD_WRAPPER(pthread_rwlock_tryrdlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
    234 
    235 PTHREAD_WRAPPER(pthread_rwlock_timedrdlock, (pthread_rwlock_t *rwlock,
    236                 const struct timespec *abs_timeout),
    237                 (rwlock, abs_timeout), "(rwlock:%p, abs_timeout:%p)");
    238 
    239 PTHREAD_WRAPPER(pthread_rwlock_wrlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
    240 
    241 PTHREAD_WRAPPER(pthread_rwlock_trywrlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
    242 
    243 PTHREAD_WRAPPER(pthread_rwlock_timedwrlock, (pthread_rwlock_t *rwlock,
    244                 const struct timespec *abs_timeout), (rwlock, abs_timeout),
    245                 "(rwlock:%p, abs_timeout:%p)");
    246 
    247 PTHREAD_WRAPPER(pthread_rwlock_unlock, (pthread_rwlock_t *rwlock), (rwlock), "(rwlock:%p)");
    248 
    249 PTHREAD_WRAPPER(pthread_key_create, (pthread_key_t *key, void (*destructor_function)(void *)),
    250                 (key, destructor_function), "(key:%p, destructor_function:%p)");
    251 
    252 PTHREAD_WRAPPER(pthread_key_delete , (pthread_key_t key), (key), "(key:%x)");
    253 
    254 PTHREAD_WRAPPER(pthread_setspecific, (pthread_key_t key, const void *value), (key, value),
    255                 "(key:%x, value:%p)");
    256 
    257 // void *pthread_getspecific(pthread_key_t key);
    258 
    259 int WRAP(pthread_kill)(pthread_t thread, int portable_signum)
    260 {
    261     char *portable_signame = map_portable_signum_to_name(portable_signum);
    262     int mips_signum;
    263     int portable_ret, ret;
    264 
    265     ALOGV("%s(thread:%lx, portable_signum:%d)", __func__, thread, portable_signum);
    266 
    267     mips_signum = signum_pton(portable_signum);
    268 
    269     if ((portable_signum != 0) && (mips_signum == 0)) {
    270         /* A signal MIPS doesn't support; all we can do is ignore it. */
    271         ret = 0;
    272     } else {
    273         ALOGV("%s: calling pthread_kill(thread:%lx, mips_signum:%d);", __func__,
    274                                         thread,     mips_signum);
    275         ret = REAL(pthread_kill)(thread, mips_signum);
    276     }
    277     portable_ret = errno_ntop(ret);
    278 
    279     ALOGV("%s: return portable_ret:%d; ret:%d;", __func__,
    280                       portable_ret,    ret);
    281 
    282     return portable_ret;
    283 }
    284 
    285 int WRAP(pthread_sigmask)(int portable_how, const sigset_portable_t *portable_sigset,
    286                              sigset_portable_t *portable_oldset)
    287 {
    288     extern int REAL(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset);
    289     int portable_ret, ret;
    290 
    291     ALOGV(" ");
    292     ALOGV("%s(portable_how:%d portable_sigset:%p, portable_oldset:%p)", __func__,
    293               portable_how,   portable_sigset,    portable_oldset);
    294 
    295     ret = do_sigmask(portable_how, portable_sigset, portable_oldset, REAL(pthread_sigmask), NULL);
    296 
    297     portable_ret = errno_ntop(ret);
    298 
    299     ALOGV("%s: return portable_ret:%d; ret:%d;", __func__,
    300                       portable_ret,    ret);
    301 
    302     return portable_ret;
    303 }
    304 
    305 PTHREAD_WRAPPER(pthread_getcpuclockid, (pthread_t tid, clockid_t *clockid), (tid, clockid),
    306                 "(tid:%lx, clockid:%p)");
    307 
    308 PTHREAD_WRAPPER(pthread_once, (pthread_once_t *once_control, void (*init_routine)(void)),
    309                 (once_control, init_routine), "(once_control:%p, init_routine:%p)");
    310 
    311 PTHREAD_WRAPPER(pthread_setname_np, (pthread_t thid, const char *thname), (thid, thname),
    312                 "(thid:%lx, thname:\"%s\")");
    313