wait
include/thread/wait.h View source View on GitHubStructs
Section titled “Structs”thread_wait_header
Section titled “thread_wait_header”thread_wait_block
Section titled “thread_wait_block” struct thread_wait_block (6 fields) source
we’re using a doubly linked list here because the block list under a thread can grow arbitrarily long. Perhaps someday we can consider something like Windows’ MAXIMUM_WAIT_OBJECTS, so we can go for a singularly linked list, save 8 bytes, at the cost of an absolute maximum + maybe minor slowdowns (?)
void *object uint16_t key enum thread_wait_block_state state struct thread_wait_header *header thread_wait_object
Section titled “thread_wait_object” struct thread_wait_object (3 fields) source
struct thread_wait_header *header void *object bool (*try_acquire)(void *object) Optional function. This runs under header->lock right before we link the wait block, and if it returns true, the wait is satisfied at registration time and any remaining objects never get linked
thread_wait_result
Section titled “thread_wait_result” struct thread_wait_result (3 fields) source
thread_wait_block_state
Section titled “thread_wait_block_state” enum thread_wait_block_state (3 variants) source
Functions
Section titled “Functions”thread_wait_header_init
Section titled “thread_wait_header_init”void thread_wait_header_init(struct thread_wait_header *header) source thread_wait_init
Section titled “thread_wait_init”thread_wait_prepare
Section titled “thread_wait_prepare”void thread_wait_prepare(
const struct thread_wait_object *objects,
size_t count,
struct thread_wait_block *storage,
enum thread_wait_type type,
enum thread_block_reason reason
) source If storage == NULL, we use the thread’s embedded blocks. No allocation ever happens in here, however, the caller remains runnable
thread_wait_prepare_one
Section titled “thread_wait_prepare_one”void thread_wait_prepare_one(
struct thread_wait_header *header,
void *object,
enum thread_wait_type type,
enum thread_block_reason reason
) source thread_wait_prepare_to_sleep
Section titled “thread_wait_prepare_to_sleep”void thread_wait_prepare_to_sleep(
struct thread_wait_header *header,
void *object,
enum thread_wait_type type
) source thread_wait_satisfy
Section titled “thread_wait_satisfy”bool thread_wait_satisfy(
struct thread_wait_block *block,
enum thread_resume_reason reason,
void (*callback)(struct thread *)
) source Satisfy unlinks ALL blocks before the waiter becomes runnable. The callback runs just for the winner
thread_wait_satisfy_epoch
Section titled “thread_wait_satisfy_epoch”bool thread_wait_satisfy_epoch(
struct thread_wait_block *block,
uint64_t epoch,
enum thread_resume_reason reason,
void (*cb)(struct thread *)
) source For callbacks that took a snapshot of thread->wait_epoch
thread_wait_header_satisfy
Section titled “thread_wait_header_satisfy”struct thread * thread_wait_header_satisfy(
struct thread_wait_header *hdr,
enum thread_resume_reason reason,
void (*cb)(struct thread *)
) source thread_wait_header_satisfy_one
Section titled “thread_wait_header_satisfy_one”struct thread * thread_wait_header_satisfy_one(
struct thread_wait_header *hdr,
enum thread_resume_reason reason,
void (*cb)(struct thread *),
void (*empty_locked)(void *),
void *arg
) source Like thread_wait_header_satisfy, but if nothing remains to satisfy, empty_locked runs under hdr->lock
thread_wait_header_satisfy_all
Section titled “thread_wait_header_satisfy_all”size_t thread_wait_header_satisfy_all(
struct thread_wait_header *hdr,
enum thread_resume_reason reason,
void (*callback)(struct thread *),
void (*before_locked)(void *),
void *arg
) source Satisfies the waiters linked when before_locked runs, under hdr->lock
thread_alert
Section titled “thread_alert”void thread_alert(struct thread *cc_nonnull_ptr) source Alert is a “level-triggered” singular event. We only end interruptible waits with alerts, but otherwise, the alert will merely pend until the next interruptible wait/park happens
thread_park
Section titled “thread_park”void thread_park(void) source thread_wait_complete
Section titled “thread_wait_complete”struct thread_wait_result thread_wait_complete(void) source The actual “go wait” action, yield and whatnot
thread_wait_complete_timeout
Section titled “thread_wait_complete_timeout”struct thread_wait_result thread_wait_complete_timeout(time_ms_t timeout_ms) source thread_wait_cancel
Section titled “thread_wait_cancel”void thread_wait_cancel(void) source Macros
Section titled “Macros”THREAD_WAIT_BLOCK_SYNC
Section titled “THREAD_WAIT_BLOCK_SYNC”#define THREAD_WAIT_BLOCK_SYNC 0 source THREAD_NUM_WAIT_BLOCKS
Section titled “THREAD_NUM_WAIT_BLOCKS”#define THREAD_NUM_WAIT_BLOCKS 4 source THREAD_WAIT_KEY_NONE
Section titled “THREAD_WAIT_KEY_NONE”#define THREAD_WAIT_KEY_NONE UINT16_MAX source THREAD_WAIT_HEADER_INIT
Section titled “THREAD_WAIT_HEADER_INIT”#define THREAD_WAIT_HEADER_INIT(name_) source Expansion
#define THREAD_WAIT_HEADER_INIT(name_) \
{.lock = SPINLOCK_INIT, .waiters = LIST_HEAD_INIT((name_).waiters)}