Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* | 7 /* |
| 8 * Native Client mutex implementation | 8 * Native Client mutex implementation |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 | 29 |
| 30 if (nc_token_acquire(&mutex->token)) { | 30 if (nc_token_acquire(&mutex->token)) { |
| 31 /* Mutex_type was set by pthread_mutex_init */ | 31 /* Mutex_type was set by pthread_mutex_init */ |
| 32 rv = nc_thread_mutex_init(mutex); | 32 rv = nc_thread_mutex_init(mutex); |
| 33 nc_token_release(&mutex->token); | 33 nc_token_release(&mutex->token); |
| 34 } | 34 } |
| 35 | 35 |
| 36 return rv; | 36 return rv; |
| 37 } | 37 } |
| 38 | 38 |
| 39 int pthread_mutex_init (pthread_mutex_t *mutex, | 39 int pthread_mutex_init(pthread_mutex_t *mutex, |
| 40 const pthread_mutexattr_t *mutex_attr) { | 40 const pthread_mutexattr_t *mutex_attr) { |
| 41 int retval; | 41 int retval; |
| 42 nc_token_init(&mutex->token, 1); | 42 nc_token_init(&mutex->token, 1); |
| 43 if (mutex_attr != NULL) { | 43 if (mutex_attr != NULL) { |
| 44 mutex->mutex_type = mutex_attr->kind; | 44 mutex->mutex_type = mutex_attr->kind; |
| 45 } else { | 45 } else { |
| 46 mutex->mutex_type = PTHREAD_MUTEX_FAST_NP; | 46 mutex->mutex_type = PTHREAD_MUTEX_FAST_NP; |
| 47 } | 47 } |
| 48 retval = nc_thread_mutex_init(mutex); | 48 retval = nc_thread_mutex_init(mutex); |
| 49 nc_token_release(&mutex->token); | 49 nc_token_release(&mutex->token); |
| 50 return retval; | 50 return retval; |
| 51 } | 51 } |
| 52 | 52 |
| 53 int pthread_mutex_destroy (pthread_mutex_t *mutex) { | 53 int pthread_mutex_destroy(pthread_mutex_t *mutex) { |
| 54 int retval; | 54 int retval; |
| 55 pthread_mutex_validate(mutex); | 55 pthread_mutex_validate(mutex); |
| 56 if (NACL_PTHREAD_ILLEGAL_THREAD_ID != mutex->owner_thread_id) { | 56 if (NACL_PTHREAD_ILLEGAL_THREAD_ID != mutex->owner_thread_id) { |
| 57 /* the mutex is still locked - cannot destroy */ | 57 /* the mutex is still locked - cannot destroy */ |
| 58 return EBUSY; | 58 return EBUSY; |
| 59 } | 59 } |
| 60 retval = __nc_irt_mutex.mutex_destroy(mutex->mutex_handle); | 60 retval = __nc_irt_mutex.mutex_destroy(mutex->mutex_handle); |
| 61 mutex->mutex_handle = NC_INVALID_HANDLE; | 61 mutex->mutex_handle = NC_INVALID_HANDLE; |
| 62 mutex->owner_thread_id = NACL_PTHREAD_ILLEGAL_THREAD_ID; | 62 mutex->owner_thread_id = NACL_PTHREAD_ILLEGAL_THREAD_ID; |
| 63 mutex->recursion_counter = 0; | 63 mutex->recursion_counter = 0; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 if (rv) { | 98 if (rv) { |
| 99 return rv; | 99 return rv; |
| 100 } | 100 } |
| 101 | 101 |
| 102 mutex->owner_thread_id = pthread_self(); | 102 mutex->owner_thread_id = pthread_self(); |
| 103 mutex->recursion_counter = 1; | 103 mutex->recursion_counter = 1; |
| 104 | 104 |
| 105 return 0; | 105 return 0; |
| 106 } | 106 } |
| 107 | 107 |
| 108 int pthread_mutex_trylock (pthread_mutex_t *mutex) { | 108 int pthread_mutex_trylock(pthread_mutex_t *mutex) { |
| 109 return nc_thread_mutex_lock(mutex, 1); | 109 return nc_thread_mutex_lock(mutex, 1); |
| 110 } | 110 } |
| 111 | 111 |
| 112 int pthread_mutex_lock (pthread_mutex_t *mutex) { | 112 int pthread_mutex_lock(pthread_mutex_t *mutex) { |
| 113 return nc_thread_mutex_lock(mutex, 0); | 113 return nc_thread_mutex_lock(mutex, 0); |
| 114 } | 114 } |
| 115 | 115 |
| 116 int pthread_mutex_unlock (pthread_mutex_t *mutex) { | 116 int pthread_mutex_unlock(pthread_mutex_t *mutex) { |
| 117 pthread_mutex_validate(mutex); | 117 pthread_mutex_validate(mutex); |
| 118 if (mutex->mutex_type != PTHREAD_MUTEX_FAST_NP) { | 118 if (mutex->mutex_type != PTHREAD_MUTEX_FAST_NP) { |
| 119 if ((PTHREAD_MUTEX_RECURSIVE_NP == mutex->mutex_type) && | 119 if ((PTHREAD_MUTEX_RECURSIVE_NP == mutex->mutex_type) && |
| 120 (0 != (--mutex->recursion_counter))) { | 120 (0 != (--mutex->recursion_counter))) { |
| 121 /* | 121 /* |
| 122 * We assume that this thread owns the lock | 122 * We assume that this thread owns the lock |
| 123 * (no verification for recursive locks), | 123 * (no verification for recursive locks), |
| 124 * so just decrement the counter, this thread is still the owner | 124 * so just decrement the counter, this thread is still the owner |
| 125 */ | 125 */ |
| 126 return 0; | 126 return 0; |
| 127 } | 127 } |
| 128 if ((PTHREAD_MUTEX_ERRORCHECK_NP == mutex->mutex_type) && | 128 if ((PTHREAD_MUTEX_ERRORCHECK_NP == mutex->mutex_type) && |
| 129 (pthread_self() != mutex->owner_thread_id)) { | 129 (pthread_self() != mutex->owner_thread_id)) { |
| 130 /* error - releasing a mutex that's free or owned by another thread */ | 130 /* error - releasing a mutex that's free or owned by another thread */ |
| 131 return EPERM; | 131 return EPERM; |
| 132 } | 132 } |
| 133 } | 133 } |
| 134 mutex->owner_thread_id = NACL_PTHREAD_ILLEGAL_THREAD_ID; | 134 mutex->owner_thread_id = NACL_PTHREAD_ILLEGAL_THREAD_ID; |
| 135 mutex->recursion_counter = 0; | 135 mutex->recursion_counter = 0; |
| 136 return __nc_irt_mutex.mutex_unlock(mutex->mutex_handle); | 136 return __nc_irt_mutex.mutex_unlock(mutex->mutex_handle); |
| 137 } | 137 } |
| 138 | 138 |
| 139 /* | 139 /* |
| 140 * NOTE(sehr): pthread_once needs to be defined in the same module as contains | 140 * NOTE(sehr): pthread_once needs to be defined in the same module as contains |
| 141 * the mutex definitions, so that it overrides the weak symbol in the libstdc++ | 141 * the mutex definitions, so that it overrides the weak symbol in the libstdc++ |
| 142 * library. Otherwise we get calls through address zero. | 142 * library. Otherwise we get calls through address zero. |
| 143 */ | 143 */ |
| 144 int pthread_once(pthread_once_t* __once_control, | 144 int pthread_once(pthread_once_t *__once_control, |
|
Roland McGrath
2012/12/04 00:04:20
It's also a style violation (or should be) that th
Mark Seaborn
2012/12/05 05:10:57
Done.
| |
| 145 void (*__init_routine) (void)) { | 145 void (*__init_routine)(void)) { |
| 146 /* | 146 /* |
| 147 * NOTE(gregoryd): calling pthread_once from __init_routine providing the same | 147 * NOTE(gregoryd): calling pthread_once from __init_routine providing the same |
| 148 * __once_control argument is an error and will cause a deadlock | 148 * __once_control argument is an error and will cause a deadlock |
| 149 */ | 149 */ |
| 150 volatile AtomicInt32* pdone = &__once_control->done; | 150 volatile AtomicInt32 *pdone = &__once_control->done; |
| 151 if (*pdone == 0) { | 151 if (*pdone == 0) { |
| 152 /* not done yet */ | 152 /* not done yet */ |
| 153 pthread_mutex_lock(&__once_control->lock); | 153 pthread_mutex_lock(&__once_control->lock); |
| 154 if (*pdone == 0) { | 154 if (*pdone == 0) { |
| 155 /* still not done - but this time we own the lock */ | 155 /* still not done - but this time we own the lock */ |
| 156 (*__init_routine)(); | 156 (*__init_routine)(); |
| 157 | 157 |
| 158 /* GCC intrinsic; see: | 158 /* GCC intrinsic; see: |
| 159 * http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html. | 159 * http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html. |
| 160 * The x86-{32,64} compilers generate inline code. The ARM | 160 * The x86-{32,64} compilers generate inline code. The ARM |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 189 return -1; | 189 return -1; |
| 190 } | 190 } |
| 191 return 0; | 191 return 0; |
| 192 } | 192 } |
| 193 | 193 |
| 194 int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, | 194 int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, |
| 195 int *kind) { | 195 int *kind) { |
| 196 *kind = attr->kind; | 196 *kind = attr->kind; |
| 197 return 0; | 197 return 0; |
| 198 } | 198 } |
| OLD | NEW |