Rev 2071 | Rev 3603 | 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++) { |