|
PatchworkOS
|
Wait queue implementation. More...
Data Structures | |
| struct | wait_queue_t |
| Wait queue structure. More... | |
| struct | wait_entry_t |
| Per-thread wait entry. More... | |
| struct | wait_cpu_ctx_t |
| Per-CPU wait context. More... | |
| struct | wait_thread_ctx_t |
| Per-thread wait context. More... | |
Macros | |
| #define | WAIT_ALL UINT64_MAX |
| Wait for all. | |
| #define | WAIT_BLOCK(waitQueue, condition) |
| Basic block. | |
| #define | WAIT_BLOCK_TIMEOUT(waitQueue, condition, timeout) |
| Block with timeout. | |
| #define | WAIT_BLOCK_LOCK(waitQueue, lock, condition) |
| Block with a spinlock. | |
| #define | WAIT_BLOCK_LOCK_TIMEOUT(waitQueue, lock, condition, timeout) |
| Block with a spinlock and timeout. | |
| #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 *waitQueue) |
| Initialize wait queue. | |
| void | wait_queue_deinit (wait_queue_t *waitQueue) |
| Deinitialize wait queue. | |
| void | wait_thread_ctx_init (wait_thread_ctx_t *wait) |
| Initialize per-thread wait context. | |
| void | wait_cpu_ctx_init (wait_cpu_ctx_t *wait, cpu_t *self) |
| Initialize per-CPU wait context. | |
| 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 *waitQueue, uint64_t amount, errno_t err) |
| Unblock threads waiting on a wait queue. | |
| uint64_t | wait_block_setup (wait_queue_t **waitQueues, uint64_t amount, clock_t timeout) |
| Setup blocking but dont block yet. | |
| void | wait_block_cancel (void) |
| Cancel blocking. | |
| uint64_t | wait_block_commit (void) |
| Block the currently running thread. | |
Wait queue implementation.
| #define WAIT_ALL UINT64_MAX |
| #define WAIT_BLOCK | ( | waitQueue, | |
| condition | |||
| ) |
Basic block.
Blocks untill condition is true, condition will be tested after every time the thread wakes up.
Check wait_block_commit() for errno values.
0. On error, ERR and errno is set. | #define WAIT_BLOCK_LOCK | ( | waitQueue, | |
| lock, | |||
| condition | |||
| ) |
Block with a spinlock.
Blocks untill condition is true, condition will be tested after every time the thread wakes up. Should be called with the lock acquired, will release the lock before blocking and return with the lock acquired.
Check wait_block_commit() for errno values.
0. On error, ERR and errno is set. | #define WAIT_BLOCK_LOCK_TIMEOUT | ( | waitQueue, | |
| lock, | |||
| condition, | |||
| timeout | |||
| ) |
Block with a spinlock and timeout.
Blocks untill condition is true, condition will be tested after every call to wait_unblock. Should be called with lock acquired, will release lock before blocking and return with lock acquired. Will also return after timeout is reached, timeout will be reached even if wait_unblock is never called.
Check wait_block_commit() for errno values.
0. On error, ERR and errno is set. | #define WAIT_BLOCK_TIMEOUT | ( | waitQueue, | |
| condition, | |||
| timeout | |||
| ) |
Block with timeout.
Blocks untill condition is true, condition will be tested after every time the thread wakes up. Will also return after timeout is reached, the thread will automatically wake up whence the timeout is reached.
Check wait_block_commit() for errno values.
0. On error, ERR and errno is set. | #define WAIT_QUEUE_CREATE | ( | name | ) | {.lock = LOCK_CREATE, .entries = LIST_CREATE(name.entries)} |
| void wait_block_cancel | ( | void | ) |
Cancel blocking.
Cancels the blocking of the currently running thread. Should only be called afterwait_block_setup() has been called. It removes the thread from the wait queues and sets the threads state toTHREAD_RUNNING. It also always enables interrupts.
Definition at line 300 of file wait.c.
References assert, atomic_exchange, EOK, NULL, RFLAGS_INTERRUPT_ENABLE, rflags_read(), sched_cpu_ctx_t::runThread, cpu_t::sched, smp_put(), smp_self_unsafe(), THREAD_PRE_BLOCK, THREAD_RUNNING, THREAD_UNBLOCKING, and wait_remove_wait_entries().
Referenced by SYSCALL_DEFINE(), and vfs_poll().
| uint64_t wait_block_commit | ( | void | ) |
Block the currently running thread.
Blocks the currently running thread. Should only be called after wait_block_setup() has been called. It invokes the scheduler which will end up calling wait_block_finalize() to finalize the blocking of the thread. Will enable interrupts again when the thread is unblocked.
Noteworthy errno values:
ETIMEDOUT: The wait timed out.EINTR: The wait was interrupted (probably by a note.)0. On failure, ERR and errno is set. Definition at line 321 of file wait.c.
References assert, atomic_load, atomic_store, EOK, wait_thread_ctx_t::err, ERR, errno, NULL, panic(), RFLAGS_INTERRUPT_ENABLE, rflags_read(), sched_cpu_ctx_t::runThread, cpu_t::sched, smp_put(), smp_self_unsafe(), THREAD_PRE_BLOCK, THREAD_RUNNING, THREAD_UNBLOCKING, timer_notify_self(), thread_t::wait, and wait_remove_wait_entries().
Referenced by SYSCALL_DEFINE(), and vfs_poll().
| 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 thread will schedule, 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 unblocked already, in that case this function will return false and the thread will not be blocked.
This function will add the thread to the cpu's blockedThreads list to handle timeouts.
| 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 already unblocked. Definition at line 103 of file wait.c.
References atomic_compare_exchange_strong, atomic_store, wait_cpu_ctx_t::blockedThreads, CLOCKS_NEVER, CONTAINER_OF, wait_thread_ctx_t::cpu, wait_thread_ctx_t::deadline, EINTR, thread_t::entry, EOK, LIST_FOR_EACH, list_is_empty(), list_last(), list_prepend(), list_push(), list_remove(), wait_cpu_ctx_t::lock, LOCK_SCOPE, THREAD_BLOCKED, thread_is_note_pending(), THREAD_PRE_BLOCK, THREAD_RUNNING, THREAD_UNBLOCKING, timer_one_shot(), uptime(), cpu_t::wait, thread_t::wait, and wait_remove_wait_entries().
Referenced by sched_invoke().
| uint64_t wait_block_setup | ( | wait_queue_t ** | waitQueues, |
| uint64_t | amount, | ||
| clock_t | timeout | ||
| ) |
Setup blocking but dont block yet.
Adds the currently running thread to the provided wait queues, sets the threads state and disables interrupts. But it does not yet actually block, and it does not add the thread to its cpus blockedThreads list, the thread will continue executing code and will return from the function.
| 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, interrupts are reenabled, returns ERR and errno is set. Definition at line 227 of file wait.c.
References assert, atomic_compare_exchange_strong, CLOCKS_NEVER, CONTAINER_OF_SAFE, wait_thread_ctx_t::cpu, wait_thread_ctx_t::deadline, EINVAL, wait_queue_t::entries, wait_thread_ctx_t::entries, EOK, wait_thread_ctx_t::err, ERR, errno, free(), list_entry_init(), list_pop(), list_push(), lock, lock_acquire(), lock_release(), malloc(), NULL, panic(), wait_entry_t::queueEntry, sched_cpu_ctx_t::runThread, cpu_t::sched, smp_put(), smp_self(), wait_entry_t::thread, THREAD_PRE_BLOCK, THREAD_RUNNING, THREAD_UNBLOCKING, wait_entry_t::threadEntry, timer_uptime(), thread_t::wait, and wait_entry_t::waitQueue.
Referenced by SYSCALL_DEFINE(), and vfs_poll().
| void wait_cpu_ctx_init | ( | wait_cpu_ctx_t * | wait, |
| cpu_t * | self | ||
| ) |
Initialize per-CPU wait context.
Must be called on the CPU the context belongs to.
| wait | The CPU wait context to initialize. |
| self | The CPU the context belongs to. |
Definition at line 95 of file wait.c.
References wait_cpu_ctx_t::blockedThreads, wait_cpu_ctx_t::cpu, list_init(), wait_cpu_ctx_t::lock, lock_init(), cpu_t::timer, timer_subscribe(), and wait_timer_handler().
Referenced by cpu_init().
| void wait_queue_deinit | ( | wait_queue_t * | waitQueue | ) |
Deinitialize wait queue.
| waitQueue | The wait queue to deinitialize. |
Definition at line 77 of file wait.c.
References wait_queue_t::entries, list_is_empty(), wait_queue_t::lock, LOCK_SCOPE, NULL, and panic().
Referenced by futex_ctx_deinit(), kbd_dir_cleanup(), kbd_new(), local_listen_free(), local_listen_new(), mouse_dir_cleanup(), mouse_new(), mutex_deinit(), pipe_close(), process_free(), and rwmutex_deinit().
| void wait_queue_init | ( | wait_queue_t * | waitQueue | ) |
Initialize wait queue.
| waitQueue | The wait queue to initialize. |
Definition at line 71 of file wait.c.
References wait_queue_t::entries, list_init(), wait_queue_t::lock, and lock_init().
Referenced by futex_ctx_get(), kbd_new(), local_conn_new(), local_listen_new(), mouse_new(), mutex_init(), pipe_open(), pipe_open2(), process_init(), and rwmutex_init().
| void wait_thread_ctx_init | ( | wait_thread_ctx_t * | wait | ) |
Initialize per-thread wait context.
| wait | The thread wait context to initialize. |
Definition at line 87 of file wait.c.
References wait_thread_ctx_t::cpu, wait_thread_ctx_t::deadline, wait_thread_ctx_t::entries, EOK, wait_thread_ctx_t::err, list_init(), and NULL.
Referenced by thread_init().
| uint64_t wait_unblock | ( | wait_queue_t * | waitQueue, |
| uint64_t | amount, | ||
| errno_t | err | ||
| ) |
Unblock threads waiting on a wait queue.
| waitQueue | 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 168 of file wait.c.
References atomic_exchange, wait_queue_t::entries, wait_thread_ctx_t::entries, free(), LIST_FOR_EACH_SAFE, list_remove(), wait_queue_t::lock, lock_acquire(), lock_release(), wait_entry_t::queueEntry, sched_push(), wait_entry_t::thread, THREAD_BLOCKED, THREAD_UNBLOCKING, wait_entry_t::threadEntry, threads, thread_t::wait, and wait_remove_wait_entries().
Referenced by kbd_push(), local_listen_free(), local_socket_connect(), local_socket_deinit(), local_socket_recv(), local_socket_send(), mouse_push(), mutex_release(), pipe_close(), pipe_read(), pipe_write(), process_kill(), rwmutex_read_release(), rwmutex_write_release(), and SYSCALL_DEFINE().
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 156 of file wait.c.
References assert, atomic_load, wait_cpu_ctx_t::blockedThreads, wait_cpu_ctx_t::cpu, wait_thread_ctx_t::cpu, thread_t::entry, list_remove(), wait_cpu_ctx_t::lock, lock_acquire(), lock_release(), sched_push(), THREAD_UNBLOCKING, thread_t::wait, and wait_remove_wait_entries().
Referenced by thread_send_note().