- Timestamp:
- 2018-06-26T17:35:40Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6e569bf
- Parents:
- fbfe59d (diff), e768aea (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. - Location:
- kernel/generic
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/proc/thread.h
rfbfe59d r8119363 112 112 /** If true, the thread can be interrupted from sleep. */ 113 113 bool sleep_interruptible; 114 115 /** 116 * If true, and this thread's sleep returns without a wakeup 117 * (timed out or interrupted), waitq ignores the next wakeup. 118 * This is necessary for futex to be able to handle those conditions. 119 */ 120 bool sleep_composable; 121 114 122 /** Wait queue in which this thread sleeps. */ 115 123 waitq_t *sleep_queue; -
kernel/generic/include/synch/futex.h
rfbfe59d r8119363 53 53 54 54 extern void futex_init(void); 55 extern sys_errno_t sys_futex_sleep(uintptr_t );55 extern sys_errno_t sys_futex_sleep(uintptr_t, uintptr_t); 56 56 extern sys_errno_t sys_futex_wakeup(uintptr_t); 57 57 -
kernel/generic/include/synch/waitq.h
rfbfe59d r8119363 62 62 int missed_wakeups; 63 63 64 /** Number of wakeups that need to be ignored due to futex timeout. */ 65 int ignore_wakeups; 66 64 67 /** List of sleeping threads for which there was no missed_wakeup. */ 65 68 list_t sleepers; -
kernel/generic/src/proc/thread.c
rfbfe59d r8119363 383 383 timeout_initialize(&thread->sleep_timeout); 384 384 thread->sleep_interruptible = false; 385 thread->sleep_composable = false; 385 386 thread->sleep_queue = NULL; 386 387 thread->timeout_pending = false; -
kernel/generic/src/synch/futex.c
rfbfe59d r8119363 398 398 } 399 399 400 /** Sleep in futex wait queue. 401 * 402 * @param uaddr Userspace address of the futex counter. 400 /** Sleep in futex wait queue with a timeout. 401 * If the sleep times out or is interrupted, the next wakeup is ignored. 402 * The userspace portion of the call must handle this condition. 403 * 404 * @param uaddr Userspace address of the futex counter. 405 * @param timeout Maximum number of useconds to sleep. 0 means no limit. 403 406 * 404 407 * @return If there is no physical mapping for uaddr ENOENT is … … 406 409 * waitq_sleep_timeout(). 407 410 */ 408 sys_errno_t sys_futex_sleep(uintptr_t uaddr )411 sys_errno_t sys_futex_sleep(uintptr_t uaddr, uintptr_t timeout) 409 412 { 410 413 futex_t *futex = get_futex(uaddr); … … 417 420 #endif 418 421 419 errno_t rc = waitq_sleep_timeout( 420 &futex->wq, 0, SYNCH_FLAGS_INTERRUPTIBLE, NULL);422 errno_t rc = waitq_sleep_timeout(&futex->wq, timeout, 423 SYNCH_FLAGS_INTERRUPTIBLE | SYNCH_FLAGS_FUTEX, NULL); 421 424 422 425 #ifdef CONFIG_UDEBUG -
kernel/generic/src/synch/waitq.c
rfbfe59d r8119363 57 57 #include <adt/list.h> 58 58 #include <arch/cycle.h> 59 #include <mem.h> 59 60 60 61 static void waitq_sleep_timed_out(void *); … … 71 72 void waitq_initialize(waitq_t *wq) 72 73 { 74 memsetb(wq, sizeof(*wq), 0); 73 75 irq_spinlock_initialize(&wq->lock, "wq.lock"); 74 76 list_initialize(&wq->sleepers); 75 wq->missed_wakeups = 0;76 77 } 77 78 … … 114 115 thread->saved_context = thread->sleep_timeout_context; 115 116 do_wakeup = true; 117 if (thread->sleep_composable) 118 wq->ignore_wakeups++; 116 119 thread->sleep_queue = NULL; 117 120 irq_spinlock_unlock(&wq->lock, false); … … 176 179 list_remove(&thread->wq_link); 177 180 thread->saved_context = thread->sleep_interruption_context; 181 if (thread->sleep_composable) 182 wq->ignore_wakeups++; 178 183 do_wakeup = true; 179 184 thread->sleep_queue = NULL; … … 393 398 */ 394 399 irq_spinlock_lock(&THREAD->lock, false); 400 401 THREAD->sleep_composable = (flags & SYNCH_FLAGS_FUTEX); 395 402 396 403 if (flags & SYNCH_FLAGS_INTERRUPTIBLE) { … … 538 545 assert(irq_spinlock_locked(&wq->lock)); 539 546 547 if (wq->ignore_wakeups > 0) { 548 if (mode == WAKEUP_FIRST) { 549 wq->ignore_wakeups--; 550 return; 551 } 552 wq->ignore_wakeups = 0; 553 } 554 540 555 loop: 541 556 if (list_empty(&wq->sleepers)) {
Note:
See TracChangeset
for help on using the changeset viewer.