Rev 2071 | Rev 2745 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2071 | Rev 2087 | ||
|---|---|---|---|
| Line 100... | Line 100... | ||
| 100 | } |
100 | } |
| 101 | 101 | ||
| 102 | /** Sleep in futex wait queue. |
102 | /** Sleep in futex wait queue. |
| 103 | * |
103 | * |
| 104 | * @param uaddr Userspace address of the futex counter. |
104 | * @param uaddr Userspace address of the futex counter. |
| 105 | * @param usec If non-zero, number of microseconds this thread is willing to sleep. |
105 | * @param usec If non-zero, number of microseconds this thread is willing to |
| - | 106 | * sleep. |
|
| 106 | * @param flags Select mode of operation. |
107 | * @param flags Select mode of operation. |
| 107 | * |
108 | * |
| 108 | * @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See synch.h. |
109 | * @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See |
| 109 | * If there is no physical mapping for uaddr ENOENT is returned. |
110 | * synch.h. If there is no physical mapping for uaddr ENOENT is returned. |
| 110 | */ |
111 | */ |
| 111 | unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags) |
112 | unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags) |
| 112 | { |
113 | { |
| 113 | futex_t *futex; |
114 | futex_t *futex; |
| 114 | uintptr_t paddr; |
115 | uintptr_t paddr; |
| Line 132... | Line 133... | ||
| 132 | 133 | ||
| 133 | interrupts_restore(ipl); |
134 | interrupts_restore(ipl); |
| 134 | 135 | ||
| 135 | futex = futex_find(paddr); |
136 | futex = futex_find(paddr); |
| 136 | 137 | ||
| 137 | return (unative_t) waitq_sleep_timeout(&futex->wq, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE); |
138 | return (unative_t) waitq_sleep_timeout(&futex->wq, usec, flags | |
| - | 139 | SYNCH_FLAGS_INTERRUPTIBLE); |
|
| 138 | } |
140 | } |
| 139 | 141 | ||
| 140 | /** Wakeup one thread waiting in futex wait queue. |
142 | /** Wakeup one thread waiting in futex wait queue. |
| 141 | * |
143 | * |
| 142 | * @param uaddr Userspace address of the futex counter. |
144 | * @param uaddr Userspace address of the futex counter. |
| Line 240... | Line 242... | ||
| 240 | * The futex is new to the current task. |
242 | * The futex is new to the current task. |
| 241 | * Upgrade its reference count and put it to the |
243 | * Upgrade its reference count and put it to the |
| 242 | * current task's B+tree of known futexes. |
244 | * current task's B+tree of known futexes. |
| 243 | */ |
245 | */ |
| 244 | futex->refcount++; |
246 | futex->refcount++; |
| 245 | btree_insert(&TASK->futexes, paddr, futex, leaf); |
247 | btree_insert(&TASK->futexes, paddr, futex, |
| - | 248 | leaf); |
|
| 246 | } |
249 | } |
| 247 | mutex_unlock(&TASK->futexes_lock); |
250 | mutex_unlock(&TASK->futexes_lock); |
| 248 | 251 | ||
| 249 | rwlock_write_unlock(&futex_ht_lock); |
252 | rwlock_write_unlock(&futex_ht_lock); |
| 250 | } else { |
253 | } else { |
| Line 269... | Line 272... | ||
| 269 | return futex; |
272 | return futex; |
| 270 | } |
273 | } |
| 271 | 274 | ||
| 272 | /** Compute hash index into futex hash table. |
275 | /** Compute hash index into futex hash table. |
| 273 | * |
276 | * |
| 274 | * @param key Address where the key (i.e. physical address of futex counter) is stored. |
277 | * @param key Address where the key (i.e. physical address of futex counter) is |
| - | 278 | * stored. |
|
| 275 | * |
279 | * |
| 276 | * @return Index into futex hash table. |
280 | * @return Index into futex hash table. |
| 277 | */ |
281 | */ |
| 278 | index_t futex_ht_hash(unative_t *key) |
282 | index_t futex_ht_hash(unative_t *key) |
| 279 | { |
283 | { |
| 280 | return *key & (FUTEX_HT_SIZE-1); |
284 | return *key & (FUTEX_HT_SIZE-1); |
| 281 | } |
285 | } |
| 282 | 286 | ||
| 283 | /** Compare futex hash table item with a key. |
287 | /** Compare futex hash table item with a key. |
| 284 | * |
288 | * |
| 285 | * @param key Address where the key (i.e. physical address of futex counter) is stored. |
289 | * @param key Address where the key (i.e. physical address of futex counter) is |
| - | 290 | * stored. |
|
| 286 | * |
291 | * |
| 287 | * @return True if the item matches the key. False otherwise. |
292 | * @return True if the item matches the key. False otherwise. |
| 288 | */ |
293 | */ |
| 289 | bool futex_ht_compare(unative_t *key, count_t keys, link_t *item) |
294 | bool futex_ht_compare(unative_t *key, count_t keys, link_t *item) |
| 290 | { |
295 | { |
| Line 314... | Line 319... | ||
| 314 | link_t *cur; |
319 | link_t *cur; |
| 315 | 320 | ||
| 316 | rwlock_write_lock(&futex_ht_lock); |
321 | rwlock_write_lock(&futex_ht_lock); |
| 317 | mutex_lock(&TASK->futexes_lock); |
322 | mutex_lock(&TASK->futexes_lock); |
| 318 | 323 | ||
| - | 324 | for (cur = TASK->futexes.leaf_head.next; |
|
| 319 | for (cur = TASK->futexes.leaf_head.next; cur != &TASK->futexes.leaf_head; cur = cur->next) { |
325 | cur != &TASK->futexes.leaf_head; cur = cur->next) { |
| 320 | btree_node_t *node; |
326 | btree_node_t *node; |
| 321 | int i; |
327 | int i; |
| 322 | 328 | ||
| 323 | node = list_get_instance(cur, btree_node_t, leaf_link); |
329 | node = list_get_instance(cur, btree_node_t, leaf_link); |
| 324 | for (i = 0; i < node->keys; i++) { |
330 | for (i = 0; i < node->keys; i++) { |