Changeset f6372be9 in mainline for uspace/lib/c/generic/futex.c
- Timestamp:
- 2018-06-26T17:34:23Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b59318e
- Parents:
- 38e3427
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-25 20:50:53)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-26 17:34:23)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/futex.c
r38e3427 rf6372be9 34 34 35 35 #include <futex.h> 36 37 #include <assert.h> 36 38 #include <atomic.h> 39 #include <fibril.h> 40 #include <io/kio.h> 41 42 #include "private/fibril.h" 43 44 //#define DPRINTF(...) kio_printf(__VA_ARGS__) 45 #define DPRINTF(...) ((void)0) 37 46 38 47 /** Initialize futex counter. … … 47 56 } 48 57 58 #ifdef CONFIG_DEBUG_FUTEX 59 60 void __futex_assert_is_locked(futex_t *futex, const char *name) 61 { 62 void *owner = __atomic_load_n(&futex->owner, __ATOMIC_RELAXED); 63 fibril_t *self = (fibril_t *) fibril_get_id(); 64 if (owner != self) { 65 DPRINTF("Assertion failed: %s (%p) is not locked by fibril %p (instead locked by fibril %p).\n", name, futex, self, owner); 66 } 67 assert(owner == self); 68 } 69 70 void __futex_assert_is_not_locked(futex_t *futex, const char *name) 71 { 72 void *owner = __atomic_load_n(&futex->owner, __ATOMIC_RELAXED); 73 fibril_t *self = (fibril_t *) fibril_get_id(); 74 if (owner == self) { 75 DPRINTF("Assertion failed: %s (%p) is already locked by fibril %p.\n", name, futex, self); 76 } 77 assert(owner != self); 78 } 79 80 void __futex_lock(futex_t *futex, const char *name) 81 { 82 /* We use relaxed atomics to avoid violating C11 memory model. 83 * They should compile to regular load/stores, but simple assignments 84 * would be UB by definition. 85 */ 86 87 fibril_t *self = (fibril_t *) fibril_get_id(); 88 DPRINTF("Locking futex %s (%p) by fibril %p.\n", name, futex, self); 89 __futex_assert_is_not_locked(futex, name); 90 futex_down(futex); 91 92 void *prev_owner = __atomic_exchange_n(&futex->owner, self, __ATOMIC_RELAXED); 93 assert(prev_owner == NULL); 94 95 atomic_inc(&self->futex_locks); 96 } 97 98 void __futex_unlock(futex_t *futex, const char *name) 99 { 100 fibril_t *self = (fibril_t *) fibril_get_id(); 101 DPRINTF("Unlocking futex %s (%p) by fibril %p.\n", name, futex, self); 102 __futex_assert_is_locked(futex, name); 103 __atomic_store_n(&futex->owner, NULL, __ATOMIC_RELAXED); 104 atomic_dec(&self->futex_locks); 105 futex_up(futex); 106 } 107 108 bool __futex_trylock(futex_t *futex, const char *name) 109 { 110 fibril_t *self = (fibril_t *) fibril_get_id(); 111 bool success = futex_trydown(futex); 112 if (success) { 113 void *owner = __atomic_load_n(&futex->owner, __ATOMIC_RELAXED); 114 assert(owner == NULL); 115 116 __atomic_store_n(&futex->owner, self, __ATOMIC_RELAXED); 117 118 atomic_inc(&self->futex_locks); 119 120 DPRINTF("Trylock on futex %s (%p) by fibril %p succeeded.\n", name, futex, self); 121 } else { 122 DPRINTF("Trylock on futex %s (%p) by fibril %p failed.\n", name, futex, self); 123 } 124 125 return success; 126 } 127 128 void __futex_give_to(futex_t *futex, void *new_owner, const char *name) 129 { 130 fibril_t *self = fibril_self(); 131 fibril_t *no = new_owner; 132 DPRINTF("Passing futex %s (%p) from fibril %p to fibril %p.\n", name, futex, self, no); 133 134 __futex_assert_is_locked(futex, name); 135 atomic_dec(&self->futex_locks); 136 atomic_inc(&no->futex_locks); 137 __atomic_store_n(&futex->owner, new_owner, __ATOMIC_RELAXED); 138 } 139 140 #endif 141 49 142 /** @} 50 143 */
Note:
See TracChangeset
for help on using the changeset viewer.