|
PatchworkOS
da8a090
A non-POSIX operating system.
|
Wait queue implementation. More...
Wait queue implementation.
The waiting subsystem provides threads with the ability to suspend their execution until a certain condition is met and/or a timeout occurs.
The common usage pattern is to call WAIT_BLOCK() to check for a specified condition, when that condition is modified the subsystem utilizing the wait queue is expected to call wait_unblock() to wake up a specified number of waiting threads, causing them to re-evaluate the condition. If the condition is still not met the thread will go back to sleep, otherwise it will continue executing.
WAIT_BLOCK* macros instead of directly calling the functions provided by this subsystem. Data Structures | |
| struct | wait_entry_t |
| Represents a thread waiting on a wait queue. More... | |
| struct | wait_queue_t |
| The primitive that threads block on. More... | |
| struct | wait_client_t |
| Represents a thread in the waiting subsystem. More... | |
| struct | wait_t |
| Represents one instance of the waiting subsystem for a CPU. More... | |
Macros | |
| #define | WAIT_ALL UINT64_MAX |
| Used to indicate that the wait should unblock all waiting threads. | |
| #define | WAIT_BLOCK(queue, condition) |
| Blocks until the condition is true, will test the condition on every wakeup. | |
| #define | WAIT_BLOCK_TIMEOUT(queue, condition, timeout) |
| Blocks until the condition is true, condition will be tested on every wakeup. Reaching the timeout will always unblock. | |
| #define | WAIT_BLOCK_LOCK(queue, lock, condition) |
| Blocks until the condition is true, condition will be tested on every wakeup. Will release the lock before blocking and acquire it again after waking up. | |
| #define | WAIT_BLOCK_LOCK_TIMEOUT(queue, lock, condition, timeout) |
| Blocks until the condition is true, condition will be tested on every wakeup. Will release the lock before blocking and acquire it again after waking up. Reaching the timeout will always unblock. | |
| #define | WAIT_QUEUE_CREATE(name) {.lock = LOCK_CREATE(), .entries = LIST_CREATE(name.entries)} |
| Create a wait queue initializer. | |
Functions | |
| void | wait_queue_init (wait_queue_t *queue) |
| Initialize wait queue. | |
| void | wait_queue_deinit (wait_queue_t *queue) |
| Deinitialize wait queue. | |
| void | wait_client_init (wait_client_t *client) |
| Initialize a threads wait client. | |
| void | wait_init (wait_t *wait) |
| Initialize an instance of the waiting subsystem. | |
| void | wait_check_timeouts (interrupt_frame_t *frame, cpu_t *self) |
| Check for timeouts and unblock threads as needed. | |
| uint64_t | wait_block_prepare (wait_queue_t **waitQueues, uint64_t amount, clock_t timeout) |
| Prepare to block the currently running thread. | |
| void | wait_block_cancel (void) |
| Cancels blocking of the currently running thread. | |
| uint64_t | wait_block_commit (void) |
| Block the currently running thread. | |
| bool | wait_block_finalize (interrupt_frame_t *frame, cpu_t *self, thread_t *thread, clock_t uptime) |
| Finalize blocking of a thread. | |
| void | wait_unblock_thread (thread_t *thread, errno_t err) |
| Unblock a specific thread. | |
| uint64_t | wait_unblock (wait_queue_t *queue, uint64_t amount, errno_t err) |
| Unblock threads waiting on a wait queue. | |
| #define WAIT_ALL UINT64_MAX |
| #define WAIT_BLOCK | ( | queue, | |
| condition | |||
| ) |
Blocks until the condition is true, will test the condition on every wakeup.
0. On error, ERR and errno is set to:wait_block_commit(). | #define WAIT_BLOCK_TIMEOUT | ( | queue, | |
| condition, | |||
| timeout | |||
| ) |
Blocks until the condition is true, condition will be tested on every wakeup. Reaching the timeout will always unblock.
0. On error, ERR and errno is set to:wait_block_commit(). | #define WAIT_BLOCK_LOCK | ( | queue, | |
| lock, | |||
| condition | |||
| ) |
Blocks until the condition is true, condition will be tested on every wakeup. Will release the lock before blocking and acquire it again after waking up.
0. On error, ERR and errno is set to:wait_block_commit(). | #define WAIT_BLOCK_LOCK_TIMEOUT | ( | queue, | |
| lock, | |||
| condition, | |||
| timeout | |||
| ) |
Blocks until the condition is true, condition will be tested on every wakeup. Will release the lock before blocking and acquire it again after waking up. Reaching the timeout will always unblock.
0. On error, ERR and errno is set to:wait_block_commit(). | #define WAIT_QUEUE_CREATE | ( | name | ) | {.lock = LOCK_CREATE(), .entries = LIST_CREATE(name.entries)} |
| void wait_queue_init | ( | wait_queue_t * | queue | ) |
| void wait_queue_deinit | ( | wait_queue_t * | queue | ) |
| void wait_client_init | ( | wait_client_t * | client | ) |
| void wait_init | ( | wait_t * | wait | ) |
| void wait_check_timeouts | ( | interrupt_frame_t * | frame, |
| cpu_t * | self | ||
| ) |
Check for timeouts and unblock threads as needed.
Will be called by the interrupt_handler().
| frame | The interrupt frame. |
| self | The current CPU. |
Definition at line 69 of file wait.c.
| uint64_t wait_block_prepare | ( | wait_queue_t ** | waitQueues, |
| uint64_t | amount, | ||
| clock_t | timeout | ||
| ) |
Prepare to block the currently running thread.
Needed to handle race conditions when a thread is unblocked prematurely. The following sequence is used:
wait_block_prepare() to add the currently running thread to the provided wait queues and disable interrupts.wait_block_cancel().wait_block_commit() to block the thread. If the thread was unblocked prematurely this function will return immediately.Will reenable interrupts on failure.
| waitQueues | Array of wait queues to add the thread to. |
| amount | Number of wait queues to add the thread to. |
| timeout | Timeout. |
0. On failure, returns ERR and errno is set to:EINVAL: Invalid arguments.ENOMEM: Out of memory. Definition at line 103 of file wait.c.
| void wait_block_cancel | ( | void | ) |
Cancels blocking of the currently running thread.
Should be called after wait_block_prepare() has been called if the condition to block is no longer valid.
Will reenable interrupts.
Definition at line 178 of file wait.c.
| uint64_t wait_block_commit | ( | void | ) |
Block the currently running thread.
Should be called after wait_block_prepare(). If the thread was unblocked prematurely this function will return immediately.
Will reenable interrupts.
0. On failure, ERR and errno is set to:ETIMEDOUT: The thread timed out.EINTR: The thread was interrupted by a note.Definition at line 199 of file wait.c.
| bool wait_block_finalize | ( | interrupt_frame_t * | frame, |
| cpu_t * | self, | ||
| thread_t * | thread, | ||
| clock_t | uptime | ||
| ) |
Finalize blocking of a thread.
When wait_block_commit() is called the scheduler will be invoked, the scheduler will then call this function to finalize the blocking of the thread.
Its possible that during the gap between wait_block_commit() and this function being called the thread was prematurely unblocked, in that case this function will return false and the scheduler will resume the thread immediately.
| frame | The interrupt frame. |
| self | The CPU the thread is being blocked on. |
| thread | The thread to block. |
| uptime | The current uptime. |
true if the thread was blocked, false if the thread was prematurely unblocked. Definition at line 231 of file wait.c.
Unblock a specific thread.
Unblocks the provided thread, removing it from all wait queues it is waiting on.
The thread must be in the THREAD_UNBLOCKING state when this function is called.
| thread | The thread to unblock. |
| err | The errno value to set for the thread or EOK for no error. |
Definition at line 284 of file wait.c.
| uint64_t wait_unblock | ( | wait_queue_t * | queue, |
| uint64_t | amount, | ||
| errno_t | err | ||
| ) |
Unblock threads waiting on a wait queue.
| queue | The wait queue to unblock threads from. |
| amount | The number of threads to unblock or WAIT_ALL to unblock all threads. |
| err | The errno value to set for the unblocked threads or EOK for no error. |
Definition at line 296 of file wait.c.