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 semaphore API | 8 * Native Client semaphore API |
9 */ | 9 */ |
10 | 10 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 return 0; | 96 return 0; |
97 | 97 |
98 __sync_fetch_and_add(&sem->nwaiters, 1); | 98 __sync_fetch_and_add(&sem->nwaiters, 1); |
99 do { | 99 do { |
100 __nc_irt_futex.futex_wait_abs(&sem->count, 0, NULL); | 100 __nc_irt_futex.futex_wait_abs(&sem->count, 0, NULL); |
101 } while (!decrement_if_positive(&sem->count)); | 101 } while (!decrement_if_positive(&sem->count)); |
102 __sync_fetch_and_sub(&sem->nwaiters, 1); | 102 __sync_fetch_and_sub(&sem->nwaiters, 1); |
103 return 0; | 103 return 0; |
104 } | 104 } |
105 | 105 |
106 int sem_trywait(sem_t *sem) { | |
107 if (NULL == sem) { | |
Roland McGrath
2013/07/12 21:15:58
Failing gracefully rather than crashing when passe
Mark Seaborn
2013/07/15 15:51:21
OK, I've removed the NULL checks.
The NULL check
| |
108 errno = EINVAL; | |
109 return -1; | |
110 } | |
111 | |
112 if (decrement_if_positive(&sem->count)) | |
113 return 0; | |
114 | |
115 errno = EAGAIN; | |
116 return -1; | |
117 } | |
118 | |
106 int sem_post(sem_t *sem) { | 119 int sem_post(sem_t *sem) { |
107 if (NULL == sem) { | 120 if (NULL == sem) { |
108 errno = EINVAL; | 121 errno = EINVAL; |
109 return -1; | 122 return -1; |
110 } | 123 } |
111 | 124 |
112 /* Increment sem->count, checking for overflow. */ | 125 /* Increment sem->count, checking for overflow. */ |
113 int old_value; | 126 int old_value; |
114 do { | 127 do { |
115 old_value = sem->count; | 128 old_value = sem->count; |
116 if (old_value == SEM_VALUE_MAX) { | 129 if (old_value == SEM_VALUE_MAX) { |
117 errno = EOVERFLOW; | 130 errno = EOVERFLOW; |
118 return -1; | 131 return -1; |
119 } | 132 } |
120 } while (!__sync_bool_compare_and_swap(&sem->count, old_value, | 133 } while (!__sync_bool_compare_and_swap(&sem->count, old_value, |
121 old_value + 1)); | 134 old_value + 1)); |
122 | 135 |
123 /* | 136 /* |
124 * We only need to call futex_wake() if there are waiters. Note | 137 * We only need to call futex_wake() if there are waiters. Note |
125 * that this might do an unnecessary call to futex_wake() if the | 138 * that this might do an unnecessary call to futex_wake() if the |
126 * last waiter has already been woken using futex_wake() but has not | 139 * last waiter has already been woken using futex_wake() but has not |
127 * yet decremented sem->nwaiters. | 140 * yet decremented sem->nwaiters. |
128 */ | 141 */ |
129 if (sem->nwaiters != 0) { | 142 if (sem->nwaiters != 0) { |
130 int woken_count; | 143 int woken_count; |
131 __nc_irt_futex.futex_wake(&sem->count, 1, &woken_count); | 144 __nc_irt_futex.futex_wake(&sem->count, 1, &woken_count); |
132 } | 145 } |
133 return 0; | 146 return 0; |
134 } | 147 } |
148 | |
149 int sem_getvalue(sem_t *sem, int *value) { | |
150 if (NULL == sem || NULL == value) { | |
Roland McGrath
2013/07/12 21:15:58
See above about checking |sem| being a null pointe
Mark Seaborn
2013/07/15 15:51:21
Done.
| |
151 errno = EINVAL; | |
152 return -1; | |
153 } | |
154 | |
155 *value = sem->count; | |
156 return 0; | |
157 } | |
OLD | NEW |