Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: src/untrusted/pthread/nc_semaphore.c

Issue 18711004: libpthread: Remove unneeded NULL checks from semaphore functions (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/syscalls/semaphore_tests.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 28 matching lines...) Expand all
39 * creates a thundering herd problem. If the woken threads wake 39 * creates a thundering herd problem. If the woken threads wake
40 * quickly enough, all but one of them will fail to decrement the 40 * quickly enough, all but one of them will fail to decrement the
41 * semaphore count and will wait again. Because of this problem, I've 41 * semaphore count and will wait again. Because of this problem, I've
42 * chosen not to use this algorithm. sem_post() below wakes only a 42 * chosen not to use this algorithm. sem_post() below wakes only a
43 * single thread. 43 * single thread.
44 */ 44 */
45 45
46 46
47 /* Initialize semaphore */ 47 /* Initialize semaphore */
48 int sem_init(sem_t *sem, int pshared, unsigned int value) { 48 int sem_init(sem_t *sem, int pshared, unsigned int value) {
49 if (NULL == sem) {
50 errno = EINVAL;
51 return -1;
52 }
53 if (pshared) { 49 if (pshared) {
54 /* We don't support shared semaphores yet. */ 50 /* We don't support shared semaphores yet. */
55 errno = ENOSYS; 51 errno = ENOSYS;
56 return -1; 52 return -1;
57 } 53 }
58 if (value > SEM_VALUE_MAX) { 54 if (value > SEM_VALUE_MAX) {
59 errno = EINVAL; 55 errno = EINVAL;
60 return -1; 56 return -1;
61 } 57 }
62 sem->count = value; 58 sem->count = value;
63 sem->nwaiters = 0; 59 sem->nwaiters = 0;
64 return 0; 60 return 0;
65 } 61 }
66 62
67 int sem_destroy(sem_t *sem) { 63 int sem_destroy(sem_t *sem) {
68 if (NULL == sem) {
69 errno = EINVAL;
70 return -1;
71 }
72 if (sem->nwaiters != 0) { 64 if (sem->nwaiters != 0) {
73 errno = EBUSY; 65 errno = EBUSY;
74 return -1; 66 return -1;
75 } 67 }
76 return 0; 68 return 0;
77 } 69 }
78 70
79 static int decrement_if_positive(volatile int *ptr) { 71 static int decrement_if_positive(volatile int *ptr) {
80 int old_value; 72 int old_value;
81 do { 73 do {
82 old_value = *ptr; 74 old_value = *ptr;
83 if (old_value == 0) 75 if (old_value == 0)
84 return 0; 76 return 0;
85 } while (!__sync_bool_compare_and_swap(ptr, old_value, old_value - 1)); 77 } while (!__sync_bool_compare_and_swap(ptr, old_value, old_value - 1));
86 return 1; 78 return 1;
87 } 79 }
88 80
89 int sem_wait(sem_t *sem) { 81 int sem_wait(sem_t *sem) {
90 if (NULL == sem) {
91 errno = EINVAL;
92 return -1;
93 }
94
95 if (decrement_if_positive(&sem->count)) 82 if (decrement_if_positive(&sem->count))
96 return 0; 83 return 0;
97 84
98 __sync_fetch_and_add(&sem->nwaiters, 1); 85 __sync_fetch_and_add(&sem->nwaiters, 1);
99 do { 86 do {
100 __nc_irt_futex.futex_wait_abs(&sem->count, 0, NULL); 87 __nc_irt_futex.futex_wait_abs(&sem->count, 0, NULL);
101 } while (!decrement_if_positive(&sem->count)); 88 } while (!decrement_if_positive(&sem->count));
102 __sync_fetch_and_sub(&sem->nwaiters, 1); 89 __sync_fetch_and_sub(&sem->nwaiters, 1);
103 return 0; 90 return 0;
104 } 91 }
105 92
106 int sem_post(sem_t *sem) { 93 int sem_post(sem_t *sem) {
107 if (NULL == sem) {
108 errno = EINVAL;
109 return -1;
110 }
111
112 /* Increment sem->count, checking for overflow. */ 94 /* Increment sem->count, checking for overflow. */
113 int old_value; 95 int old_value;
114 do { 96 do {
115 old_value = sem->count; 97 old_value = sem->count;
116 if (old_value == SEM_VALUE_MAX) { 98 if (old_value == SEM_VALUE_MAX) {
117 errno = EOVERFLOW; 99 errno = EOVERFLOW;
118 return -1; 100 return -1;
119 } 101 }
120 } while (!__sync_bool_compare_and_swap(&sem->count, old_value, 102 } while (!__sync_bool_compare_and_swap(&sem->count, old_value,
121 old_value + 1)); 103 old_value + 1));
122 104
123 /* 105 /*
124 * We only need to call futex_wake() if there are waiters. Note 106 * 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 107 * 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 108 * last waiter has already been woken using futex_wake() but has not
127 * yet decremented sem->nwaiters. 109 * yet decremented sem->nwaiters.
128 */ 110 */
129 if (sem->nwaiters != 0) { 111 if (sem->nwaiters != 0) {
130 int woken_count; 112 int woken_count;
131 __nc_irt_futex.futex_wake(&sem->count, 1, &woken_count); 113 __nc_irt_futex.futex_wake(&sem->count, 1, &woken_count);
132 } 114 }
133 return 0; 115 return 0;
134 } 116 }
OLDNEW
« no previous file with comments | « no previous file | tests/syscalls/semaphore_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698