Changeset 8119363 in mainline for kernel


Ignore:
Timestamp:
2018-06-26T17:35:40Z (7 years ago)
Author:
Jiří Zárevúcky <jiri.zarevucky@…>
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.
Message:

Merge some preliminary async/fibril framework changes.

Location:
kernel/generic
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/proc/thread.h

    rfbfe59d r8119363  
    112112        /** If true, the thread can be interrupted from sleep. */
    113113        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
    114122        /** Wait queue in which this thread sleeps. */
    115123        waitq_t *sleep_queue;
  • kernel/generic/include/synch/futex.h

    rfbfe59d r8119363  
    5353
    5454extern void futex_init(void);
    55 extern sys_errno_t sys_futex_sleep(uintptr_t);
     55extern sys_errno_t sys_futex_sleep(uintptr_t, uintptr_t);
    5656extern sys_errno_t sys_futex_wakeup(uintptr_t);
    5757
  • kernel/generic/include/synch/waitq.h

    rfbfe59d r8119363  
    6262        int missed_wakeups;
    6363
     64        /** Number of wakeups that need to be ignored due to futex timeout. */
     65        int ignore_wakeups;
     66
    6467        /** List of sleeping threads for which there was no missed_wakeup. */
    6568        list_t sleepers;
  • kernel/generic/src/proc/thread.c

    rfbfe59d r8119363  
    383383        timeout_initialize(&thread->sleep_timeout);
    384384        thread->sleep_interruptible = false;
     385        thread->sleep_composable = false;
    385386        thread->sleep_queue = NULL;
    386387        thread->timeout_pending = false;
  • kernel/generic/src/synch/futex.c

    rfbfe59d r8119363  
    398398}
    399399
    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.
    403406 *
    404407 * @return              If there is no physical mapping for uaddr ENOENT is
     
    406409 *                      waitq_sleep_timeout().
    407410 */
    408 sys_errno_t sys_futex_sleep(uintptr_t uaddr)
     411sys_errno_t sys_futex_sleep(uintptr_t uaddr, uintptr_t timeout)
    409412{
    410413        futex_t *futex = get_futex(uaddr);
     
    417420#endif
    418421
    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);
    421424
    422425#ifdef CONFIG_UDEBUG
  • kernel/generic/src/synch/waitq.c

    rfbfe59d r8119363  
    5757#include <adt/list.h>
    5858#include <arch/cycle.h>
     59#include <mem.h>
    5960
    6061static void waitq_sleep_timed_out(void *);
     
    7172void waitq_initialize(waitq_t *wq)
    7273{
     74        memsetb(wq, sizeof(*wq), 0);
    7375        irq_spinlock_initialize(&wq->lock, "wq.lock");
    7476        list_initialize(&wq->sleepers);
    75         wq->missed_wakeups = 0;
    7677}
    7778
     
    114115                thread->saved_context = thread->sleep_timeout_context;
    115116                do_wakeup = true;
     117                if (thread->sleep_composable)
     118                        wq->ignore_wakeups++;
    116119                thread->sleep_queue = NULL;
    117120                irq_spinlock_unlock(&wq->lock, false);
     
    176179                list_remove(&thread->wq_link);
    177180                thread->saved_context = thread->sleep_interruption_context;
     181                if (thread->sleep_composable)
     182                        wq->ignore_wakeups++;
    178183                do_wakeup = true;
    179184                thread->sleep_queue = NULL;
     
    393398         */
    394399        irq_spinlock_lock(&THREAD->lock, false);
     400
     401        THREAD->sleep_composable = (flags & SYNCH_FLAGS_FUTEX);
    395402
    396403        if (flags & SYNCH_FLAGS_INTERRUPTIBLE) {
     
    538545        assert(irq_spinlock_locked(&wq->lock));
    539546
     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
    540555loop:
    541556        if (list_empty(&wq->sleepers)) {
Note: See TracChangeset for help on using the changeset viewer.