Changeset 58775d30 in mainline for uspace/lib/c/include/futex.h
- Timestamp:
- 2015-03-16T16:07:21Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2003739
- Parents:
- 6069061 (diff), 795e2bf (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/include/futex.h
r6069061 r58775d30 38 38 #include <atomic.h> 39 39 #include <sys/types.h> 40 #include <libc.h> 40 41 41 #define FUTEX_INITIALIZER {1} 42 typedef struct futex { 43 atomic_t val; 44 #ifdef FUTEX_UPGRADABLE 45 int upgraded; 46 #endif 47 } futex_t; 42 48 43 typedef atomic_t futex_t;44 49 45 50 extern void futex_initialize(futex_t *futex, int value); 46 extern int futex_down(futex_t *futex); 47 extern int futex_trydown(futex_t *futex); 48 extern int futex_up(futex_t *futex); 51 52 #ifdef FUTEX_UPGRADABLE 53 #include <rcu.h> 54 55 #define FUTEX_INITIALIZE(val) {{ (val) }, 0} 56 57 #define futex_lock(fut) \ 58 ({ \ 59 rcu_read_lock(); \ 60 (fut)->upgraded = rcu_access(_upgrade_futexes); \ 61 if ((fut)->upgraded) \ 62 (void) futex_down((fut)); \ 63 }) 64 65 #define futex_trylock(fut) \ 66 ({ \ 67 rcu_read_lock(); \ 68 int _upgraded = rcu_access(_upgrade_futexes); \ 69 if (_upgraded) { \ 70 int _acquired = futex_trydown((fut)); \ 71 if (!_acquired) { \ 72 rcu_read_unlock(); \ 73 } else { \ 74 (fut)->upgraded = true; \ 75 } \ 76 _acquired; \ 77 } else { \ 78 (fut)->upgraded = false; \ 79 1; \ 80 } \ 81 }) 82 83 #define futex_unlock(fut) \ 84 ({ \ 85 if ((fut)->upgraded) \ 86 (void) futex_up((fut)); \ 87 rcu_read_unlock(); \ 88 }) 89 90 extern int _upgrade_futexes; 91 92 extern void futex_upgrade_all_and_wait(void); 93 94 #else 95 96 #define FUTEX_INITIALIZE(val) {{ (val) }} 97 98 #define futex_lock(fut) (void) futex_down((fut)) 99 #define futex_trylock(fut) futex_trydown((fut)) 100 #define futex_unlock(fut) (void) futex_up((fut)) 101 102 #endif 103 104 #define FUTEX_INITIALIZER FUTEX_INITIALIZE(1) 105 106 /** Try to down the futex. 107 * 108 * @param futex Futex. 109 * 110 * @return Non-zero if the futex was acquired. 111 * @return Zero if the futex was not acquired. 112 * 113 */ 114 static inline int futex_trydown(futex_t *futex) 115 { 116 return cas(&futex->val, 1, 0); 117 } 118 119 /** Down the futex. 120 * 121 * @param futex Futex. 122 * 123 * @return ENOENT if there is no such virtual address. 124 * @return Zero in the uncontended case. 125 * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED. 126 * 127 */ 128 static inline int futex_down(futex_t *futex) 129 { 130 if ((atomic_signed_t) atomic_predec(&futex->val) < 0) 131 return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->val.count); 132 133 return 0; 134 } 135 136 /** Up the futex. 137 * 138 * @param futex Futex. 139 * 140 * @return ENOENT if there is no such virtual address. 141 * @return Zero in the uncontended case. 142 * 143 */ 144 static inline int futex_up(futex_t *futex) 145 { 146 if ((atomic_signed_t) atomic_postinc(&futex->val) < 0) 147 return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->val.count); 148 149 return 0; 150 } 49 151 50 152 #endif
Note:
See TracChangeset
for help on using the changeset viewer.