Changeset 111b9b9 in mainline for kernel/generic/include


Ignore:
Timestamp:
2023-02-11T19:13:44Z (3 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4777e02
Parents:
76e17d7c
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2022-08-15 17:46:39)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-11 19:13:44)
Message:

Reimplement waitq using thread_wait/wakeup

This adds a few functions to the thread API which can be
summarized as "stop running until woken up by others".
The ordering and context-switching concerns are thus yeeted
to this abstraction and waitq only deals with maintaining
the queues. Overall, this makes the control flow in waitq
much easier to navigate.

Location:
kernel/generic/include
Files:
4 edited

Legend:

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

    r76e17d7c r111b9b9  
    5757extern void scheduler_fpu_lazy_request(void);
    5858extern void scheduler(void);
     59extern void scheduler_locked(ipl_t);
    5960extern void kcpulb(void *arg);
    6061
  • kernel/generic/include/proc/thread.h

    r76e17d7c r111b9b9  
    7979        odlink_t lthreads;
    8080
     81        /** Tracking variable for thread_wait/thread_wakeup */
     82        atomic_int sleep_state;
     83
    8184        /**
    8285         * If true, the thread is terminating.
     
    8588         */
    8689        volatile bool interrupted;
     90
     91        /** Wait queue in which this thread sleeps. Used for debug printouts. */
     92        _Atomic(waitq_t *) sleep_queue;
    8793
    8894        /** Waitq for thread_join_timeout(). */
     
    108114        context_t saved_context;
    109115        ipl_t saved_ipl;
    110 
    111         /**
    112          * From here, the stored timeout context
    113          * is restored when sleep times out.
    114          */
    115         context_t sleep_timeout_context;
    116 
    117         /**
    118          * From here, the stored interruption context
    119          * is restored when sleep is interrupted.
    120          */
    121         context_t sleep_interruption_context;
    122 
    123         /** If true, the thread can be interrupted from sleep. */
    124         bool sleep_interruptible;
    125 
    126         /**
    127          * If true, and this thread's sleep returns without a wakeup
    128          * (timed out or interrupted), waitq ignores the next wakeup.
    129          * This is necessary for futex to be able to handle those conditions.
    130          */
    131         bool sleep_composable;
    132 
    133         /** Wait queue in which this thread sleeps. */
    134         waitq_t *sleep_queue;
    135116
    136117        /**
     
    216197extern void thread_ready(thread_t *);
    217198extern void thread_exit(void) __attribute__((noreturn));
    218 extern void thread_interrupt(thread_t *, bool);
     199extern void thread_interrupt(thread_t *);
     200
     201typedef enum {
     202        THREAD_OK,
     203        THREAD_TERMINATING,
     204} thread_termination_state_t;
     205
     206typedef enum {
     207        THREAD_WAIT_SUCCESS,
     208        THREAD_WAIT_TIMEOUT,
     209} thread_wait_result_t;
     210
     211extern thread_termination_state_t thread_wait_start(void);
     212extern thread_wait_result_t thread_wait_finish(deadline_t);
     213extern void thread_wakeup(thread_t *);
    219214
    220215static inline thread_t *thread_ref(thread_t *thread)
  • kernel/generic/include/synch/waitq.h

    r76e17d7c r111b9b9  
    4141#include <adt/list.h>
    4242
    43 typedef enum {
    44         WAKEUP_FIRST = 0,
    45         WAKEUP_ALL,
    46         WAKEUP_CLOSE,
    47 } wakeup_mode_t;
    48 
    4943/** Wait queue structure.
    5044 *
     
    5852
    5953        /**
    60          * Number of waitq_wakeup() calls that didn't find a thread to wake up.
    61          *
     54         * If negative, number of wakeups that are to be ignored (necessary for futex operation).
     55         * If positive, number of wakeups that weren't able to wake a thread.
    6256         */
    63         int missed_wakeups;
    64 
    65         /** Number of wakeups that need to be ignored due to futex timeout. */
    66         int ignore_wakeups;
     57        int wakeup_balance;
    6758
    6859        /** List of sleeping threads for which there was no missed_wakeup. */
    6960        list_t sleepers;
     61
     62        bool closed;
    7063} waitq_t;
     64
     65typedef struct wait_guard {
     66        ipl_t ipl;
     67} wait_guard_t;
    7168
    7269struct thread;
     
    7572extern void waitq_initialize_with_count(waitq_t *, int);
    7673extern errno_t waitq_sleep(waitq_t *);
    77 extern errno_t waitq_sleep_timeout(waitq_t *, uint32_t, unsigned int, bool *);
    78 extern ipl_t waitq_sleep_prepare(waitq_t *);
    79 extern errno_t waitq_sleep_unsafe(waitq_t *, bool *);
    80 extern errno_t waitq_sleep_timeout_unsafe(waitq_t *, uint32_t, unsigned int, bool *);
    81 extern void waitq_sleep_finish(waitq_t *, bool, ipl_t);
    82 extern void waitq_wakeup(waitq_t *, wakeup_mode_t);
    83 extern void _waitq_wakeup_unsafe(waitq_t *, wakeup_mode_t);
    84 extern void waitq_interrupt_sleep(struct thread *);
     74extern errno_t _waitq_sleep_timeout(waitq_t *, uint32_t, unsigned int);
     75extern errno_t waitq_sleep_timeout(waitq_t *, uint32_t);
     76extern wait_guard_t waitq_sleep_prepare(waitq_t *);
     77extern errno_t waitq_sleep_unsafe(waitq_t *, wait_guard_t);
     78extern errno_t waitq_sleep_timeout_unsafe(waitq_t *, uint32_t, unsigned int, wait_guard_t);
     79
     80extern void waitq_wake_one(waitq_t *);
     81extern void waitq_wake_all(waitq_t *);
     82extern void waitq_signal(waitq_t *);
     83extern void waitq_close(waitq_t *);
    8584
    8685#endif
  • kernel/generic/include/time/timeout.h

    r76e17d7c r111b9b9  
    4242typedef void (*timeout_handler_t)(void *arg);
    4343
     44typedef uint64_t deadline_t;
     45#define DEADLINE_NEVER ((deadline_t) UINT64_MAX)
     46
    4447typedef struct {
    4548        /** Link to the list of active timeouts on timeout->cpu */
    4649        link_t link;
    4750        /** Timeout will be activated when current clock tick reaches this value. */
    48         uint64_t deadline;
     51        deadline_t deadline;
    4952        /** Function that will be called on timeout activation. */
    5053        timeout_handler_t handler;
     
    5962#define us2ticks(us)  ((uint64_t) (((uint32_t) (us) / (1000000 / HZ))))
    6063
     64extern deadline_t timeout_deadline_in_usec(uint32_t us);
     65
    6166extern void timeout_init(void);
    6267extern void timeout_initialize(timeout_t *);
    6368extern void timeout_register(timeout_t *, uint64_t, timeout_handler_t, void *);
     69extern void timeout_register_deadline(timeout_t *, deadline_t, timeout_handler_t, void *);
    6470extern bool timeout_unregister(timeout_t *);
    6571
Note: See TracChangeset for help on using the changeset viewer.