#ifndef KERNEL_WAIT_H_ #define KERNEL_WAIT_H_ #include #include #define wait_event(wq, cond) \ ({ \ struct thread *self = current_thread(); \ struct wait_item waiter; \ wait_item_init(&waiter, self); \ for (;;) { \ thread_wait_begin(&waiter, wq); \ if (cond) { \ break; \ } \ schedule(SCHED_NORMAL); \ } \ thread_wait_end(&waiter, wq); \ }) struct wait_item { struct thread *w_thread; struct queue_entry w_entry; }; struct waitqueue { struct queue wq_waiters; spin_lock_t wq_lock; }; extern void wait_item_init(struct wait_item *item, struct thread *thr); extern void thread_wait_begin(struct wait_item *waiter, struct waitqueue *q); extern void thread_wait_end(struct wait_item *waiter, struct waitqueue *q); extern void thread_wait_begin_nosleep( struct wait_item *waiter, struct waitqueue *q); extern void thread_wait_end_nosleep( struct wait_item *waiter, struct waitqueue *q); extern void wait_on_queue(struct waitqueue *q); extern void wakeup_queue(struct waitqueue *q); extern void wakeup_n(struct waitqueue *q, size_t n); extern void wakeup_one(struct waitqueue *q); static inline bool waitqueue_empty(struct waitqueue *wq) { unsigned long flags; spin_lock_irqsave(&wq->wq_lock, &flags); bool result = queue_empty(&wq->wq_waiters); spin_unlock_irqrestore(&wq->wq_lock, flags); return result; } #endif