PatchworkOS
Loading...
Searching...
No Matches
Waiting subsystem

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.
 

Detailed Description

Wait queue implementation.

Macro Definition Documentation

◆ WAIT_ALL

#define WAIT_ALL   UINT64_MAX

Wait for all.

Used to indicate that the wait should unblock when all wait queues have unblocked the thread.

Definition at line 26 of file wait.h.

◆ WAIT_BLOCK

#define WAIT_BLOCK (   waitQueue,
  condition 
)
Value:
({ \
uint64_t result = 0; \
while (!(condition) && result == 0) \
{ \
wait_queue_t* temp = waitQueue; \
if (wait_block_setup(&temp, 1, CLOCKS_NEVER) == ERR) \
{ \
result = ERR; \
break; \
} \
result = wait_block_commit(); \
} \
result; \
})
#define CLOCKS_NEVER
Definition clock_t.h:16
uint64_t wait_block_commit(void)
Block the currently running thread.
Definition wait.c:321
uint64_t wait_block_setup(wait_queue_t **waitQueues, uint64_t amount, clock_t timeout)
Setup blocking but dont block yet.
Definition wait.c:227
#define ERR
Integer error value.
Definition ERR.h:17
#define RFLAGS_INTERRUPT_ENABLE
Definition regs.h:32
static uint64_t rflags_read()
Definition regs.h:78
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
Wait queue structure.
Definition wait.h:166

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.

Returns
On success, 0. On error, ERR and errno is set.

Definition at line 37 of file wait.h.

◆ WAIT_BLOCK_LOCK

#define WAIT_BLOCK_LOCK (   waitQueue,
  lock,
  condition 
)
Value:
({ \
uint64_t result = 0; \
while (!(condition) && result == 0) \
{ \
wait_queue_t* temp = waitQueue; \
if (wait_block_setup(&temp, 1, CLOCKS_NEVER) == ERR) \
{ \
result = ERR; \
break; \
} \
lock_release(lock); \
result = wait_block_commit(); \
lock_acquire(lock); \
} \
result; \
})
static rwlock_t lock
Definition irq.c:10

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.

Returns
On success, 0. On error, ERR and errno is set.

Definition at line 101 of file wait.h.

◆ WAIT_BLOCK_LOCK_TIMEOUT

#define WAIT_BLOCK_LOCK_TIMEOUT (   waitQueue,
  lock,
  condition,
  timeout 
)
Value:
({ \
uint64_t result = 0; \
clock_t deadline = (timeout) == CLOCKS_NEVER ? CLOCKS_NEVER : (timeout) + uptime; \
while (!(condition) && result == ERR) \
{ \
if (deadline <= uptime) \
{ \
result = ERR; \
break; \
} \
clock_t remaining = deadline == CLOCKS_NEVER ? CLOCKS_NEVER : (deadline > uptime ? deadline - uptime : 0); \
wait_queue_t* temp = waitQueue; \
if (wait_block_setup(&temp, 1, remaining) == ERR) \
{ \
result = ERR; \
break; \
} \
lock_release(lock); \
result = wait_block_commit(); \
lock_acquire(lock); \
} \
result; \
})
clock_t timer_uptime(void)
Time since boot.
Definition timer.c:73
#define ETIMEDOUT
Connection timed out.
Definition errno.h:577
#define errno
Error number variable.
Definition errno.h:27
clock_t uptime(void)
System call for retreving the time since boot.
Definition uptime.c:6
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13

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.

Returns
On success, 0. On error, ERR and errno is set.

Definition at line 132 of file wait.h.

◆ WAIT_BLOCK_TIMEOUT

#define WAIT_BLOCK_TIMEOUT (   waitQueue,
  condition,
  timeout 
)
Value:
({ \
uint64_t result = 0; \
clock_t deadline = (timeout) == CLOCKS_NEVER ? CLOCKS_NEVER : (timeout) + uptime; \
while (!(condition) && result == 0) \
{ \
if (deadline <= uptime) \
{ \
result = ERR; \
break; \
} \
clock_t remaining = deadline == CLOCKS_NEVER ? CLOCKS_NEVER : (deadline > uptime ? deadline - uptime : 0); \
wait_queue_t* temp = waitQueue; \
if (wait_block_setup(&temp, 1, remaining) == ERR) \
{ \
result = ERR; \
break; \
} \
result = wait_block_commit(); \
} \
result; \
})

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.

Returns
On success, 0. On error, ERR and errno is set.

Definition at line 64 of file wait.h.

◆ WAIT_QUEUE_CREATE

#define WAIT_QUEUE_CREATE (   name)    {.lock = LOCK_CREATE, .entries = LIST_CREATE(name.entries)}

Create a wait queue initializer.

Parameters
nameThe name of the wait queue variable.
Returns
The wait queue initializer.

Definition at line 220 of file wait.h.

Function Documentation

◆ wait_block_cancel()

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().

◆ wait_block_commit()

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.)
Returns
On success, 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().

◆ wait_block_finalize()

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.

Parameters
frameThe interrupt frame.
selfThe CPU the thread is being blocked on.
threadThe thread to block.
uptimeThe current uptime.
Returns
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().

◆ wait_block_setup()

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.

Parameters
waitQueuesArray of wait queues to add the thread to.
amountNumber of wait queues to add the thread to.
timeoutTimeout.
Returns
On success, 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().

◆ wait_cpu_ctx_init()

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.

Parameters
waitThe CPU wait context to initialize.
selfThe 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().

◆ wait_queue_deinit()

void wait_queue_deinit ( wait_queue_t waitQueue)

Deinitialize wait queue.

Parameters
waitQueueThe 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().

◆ wait_queue_init()

void wait_queue_init ( wait_queue_t waitQueue)

Initialize wait queue.

Parameters
waitQueueThe 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().

◆ wait_thread_ctx_init()

void wait_thread_ctx_init ( wait_thread_ctx_t wait)

Initialize per-thread wait context.

Parameters
waitThe 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().

◆ wait_unblock()

uint64_t wait_unblock ( wait_queue_t waitQueue,
uint64_t  amount,
errno_t  err 
)

Unblock threads waiting on a wait queue.

Parameters
waitQueueThe wait queue to unblock threads from.
amountThe number of threads to unblock or WAIT_ALL to unblock all threads.
errThe errno value to set for the unblocked threads or EOK for no error.
Returns
The number of threads that were unblocked.

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().

◆ wait_unblock_thread()

void wait_unblock_thread ( thread_t thread,
errno_t  err 
)

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.

Parameters
threadThe thread to unblock.
errThe 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().