43#define WAIT_ALL UINT64_MAX
51#define WAIT_BLOCK(queue, condition) \
53 assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); \
54 uint64_t result = 0; \
55 while (!(condition) && result == 0) \
57 wait_queue_t* temp = queue; \
58 if (wait_block_prepare(&temp, 1, CLOCKS_NEVER) == ERR) \
63 result = wait_block_commit(); \
75#define WAIT_BLOCK_TIMEOUT(queue, condition, timeout) \
77 assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); \
78 uint64_t result = 0; \
79 clock_t uptime = clock_uptime(); \
80 clock_t deadline = CLOCKS_DEADLINE(timeout, uptime); \
81 while (!(condition) && result == 0) \
83 if (deadline <= uptime) \
89 clock_t remaining = CLOCKS_REMAINING(deadline, uptime); \
90 wait_queue_t* temp = queue; \
91 if (wait_block_prepare(&temp, 1, remaining) == ERR) \
96 result = wait_block_commit(); \
97 uptime = clock_uptime(); \
109#define WAIT_BLOCK_LOCK(queue, lock, condition) \
111 assert(!(rflags_read() & RFLAGS_INTERRUPT_ENABLE)); \
112 uint64_t result = 0; \
113 while (!(condition) && result == 0) \
115 wait_queue_t* temp = queue; \
116 if (wait_block_prepare(&temp, 1, CLOCKS_NEVER) == ERR) \
121 lock_release(lock); \
122 result = wait_block_commit(); \
123 assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); \
124 lock_acquire(lock); \
136#define WAIT_BLOCK_LOCK_TIMEOUT(queue, lock, condition, timeout) \
138 uint64_t result = 0; \
139 clock_t uptime = clock_uptime(); \
140 clock_t deadline = CLOCKS_DEADLINE(timeout, uptime); \
141 while (!(condition) && result == ERR) \
143 if (deadline <= uptime) \
149 clock_t remaining = CLOCKS_REMAINING(deadline, uptime); \
150 wait_queue_t* temp = queue; \
151 if (wait_block_prepare(&temp, 1, remaining) == ERR) \
156 lock_release(lock); \
157 result = wait_block_commit(); \
158 assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); \
159 lock_acquire(lock); \
160 uptime = clock_uptime(); \
172typedef struct wait_entry
184typedef struct wait_queue
197typedef struct wait_client
222#define WAIT_QUEUE_CREATE(name) {.lock = LOCK_CREATE(), .entries = LIST_CREATE(name.entries)}
uint64_t wait_block_prepare(wait_queue_t **waitQueues, uint64_t amount, clock_t timeout)
Prepare to block the currently running thread.
uint64_t wait_unblock(wait_queue_t *queue, uint64_t amount, errno_t err)
Unblock threads waiting on a wait queue.
uint64_t wait_block_commit(void)
Block the currently running thread.
void wait_block_cancel(void)
Cancels blocking of the currently running thread.
void wait_queue_deinit(wait_queue_t *queue)
Deinitialize wait queue.
void wait_queue_init(wait_queue_t *queue)
Initialize wait queue.
void wait_client_init(wait_client_t *client)
Initialize a threads wait client.
bool wait_block_finalize(interrupt_frame_t *frame, thread_t *thread, clock_t uptime)
Finalize blocking of a thread.
void wait_check_timeouts(interrupt_frame_t *frame)
Check for timeouts and unblock threads as needed.
void wait_unblock_thread(thread_t *thread, errno_t err)
Unblock a specific thread.
clock_t uptime(void)
System call for retreving the time since boot.
__UINT64_TYPE__ clock_t
A nanosecond time.
A entry in a doubly linked list.
A simple ticket lock implementation.
Thread of execution structure.
Represents a thread in the waiting subsystem.
list_t entries
List of wait entries, one for each wait queue the thread is waiting on.
wait_t * owner
The wait cpu context of the cpu the thread is blocked on.
clock_t deadline
Deadline for timeout, CLOCKS_NEVER for no timeout.
errno_t err
Error number set when unblocking the thread, EOK for no error.
Represents a thread waiting on a wait queue.
thread_t * thread
The thread that is waiting.
wait_queue_t * queue
The wait queue the thread is waiting on.
list_entry_t queueEntry
Used in wait_queue_t->entries.
list_entry_t threadEntry
Used in wait_client_t->entries.
The primitive that threads block on.
list_t entries
List of wait entries for threads waiting on this queue.
Represents one instance of the waiting subsystem for a CPU.
list_t blockedThreads
List of blocked threads, sorted by deadline.