#include #include void wait_item_init(struct wait_item *item, struct thread *thr) { item->w_thread = thr; item->w_entry = QUEUE_ENTRY_INIT; } void thread_wait_begin(struct wait_item *waiter, struct waitqueue *q) { unsigned long flags; spin_lock_irqsave(&q->wq_lock, &flags); queue_push_back(&q->wq_waiters, &waiter->w_entry); waiter->w_thread->tr_state = THREAD_SLEEPING; spin_unlock_irqrestore(&q->wq_lock, flags); } void thread_wait_end(struct wait_item *waiter, struct waitqueue *q) { waiter->w_thread->tr_state = THREAD_READY; unsigned long flags; spin_lock_irqsave(&q->wq_lock, &flags); queue_delete(&q->wq_waiters, &waiter->w_entry); spin_unlock_irqrestore(&q->wq_lock, flags); } void wakeup_queue(struct waitqueue *q) { unsigned long flags; spin_lock_irqsave(&q->wq_lock, &flags); struct queue_entry *ent = queue_pop_front(&q->wq_waiters); while (ent) { struct wait_item *waiter = QUEUE_CONTAINER(struct wait_item, w_entry, ent); struct thread *thr = waiter->w_thread; struct runqueue *rq = thr->tr_rq; if (!rq) { rq = cpu_rq(this_cpu()); } thr->tr_state = THREAD_READY; rq_enqueue(rq, thr); ent = queue_pop_front(&q->wq_waiters); } spin_unlock_irqrestore(&q->wq_lock, flags); } void wakeup_one(struct waitqueue *q) { unsigned long flags; spin_lock_irqsave(&q->wq_lock, &flags); struct queue_entry *ent = queue_pop_front(&q->wq_waiters); if(ent) { struct wait_item *waiter = QUEUE_CONTAINER(struct wait_item, w_entry, ent); struct thread *thr = waiter->w_thread; struct runqueue *rq = thr->tr_rq; if (!rq) { rq = cpu_rq(this_cpu()); } thr->tr_state = THREAD_READY; rq_enqueue(rq, thr); } spin_unlock_irqrestore(&q->wq_lock, flags); } void sleep_forever(void) { struct thread *thr = current_thread(); struct runqueue *rq = thr->tr_rq; unsigned long flags; rq_lock(rq, &flags); rq_remove_thread(rq, thr); thr->tr_state = THREAD_SLEEPING; rq_unlock(rq, flags); while (thr->tr_state == THREAD_SLEEPING) { schedule(SCHED_NORMAL); } }