X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=kitten%2Fkernel%2Fwaitq.c;fp=kitten%2Fkernel%2Fwaitq.c;h=80f5de9054ee6b0a3ce83d7a14a01422832977d7;hb=66a1a4c7a9edcd7d8bc207aca093d694a6e6b5b2;hp=0000000000000000000000000000000000000000;hpb=f7cf9c19ecb0a589dd45ae0d2c91814bd3c2acc2;p=palacios.git diff --git a/kitten/kernel/waitq.c b/kitten/kernel/waitq.c new file mode 100644 index 0000000..80f5de9 --- /dev/null +++ b/kitten/kernel/waitq.c @@ -0,0 +1,89 @@ +#include +#include +#include + +void +waitq_init(waitq_t *waitq) +{ + spin_lock_init(&waitq->lock); + list_head_init(&waitq->waitq); +} + +void +waitq_init_entry(waitq_entry_t *entry, struct task_struct *task) +{ + entry->task = task; + list_head_init(&entry->link); +} + +bool +waitq_active(waitq_t *waitq) +{ + bool active; + unsigned long irqstate; + + spin_lock_irqsave(&waitq->lock, irqstate); + active = !list_empty(&waitq->waitq); + spin_unlock_irqrestore(&waitq->lock, irqstate); + + return active; +} + +void +waitq_add_entry(waitq_t *waitq, waitq_entry_t *entry) +{ + unsigned long irqstate; + + spin_lock_irqsave(&waitq->lock, irqstate); + BUG_ON(!list_empty(&entry->link)); + list_add(&entry->link, &waitq->waitq); + spin_unlock_irqrestore(&waitq->lock, irqstate); +} + +void +waitq_remove_entry(waitq_t *waitq, waitq_entry_t *entry) +{ + unsigned long irqstate; + + spin_lock_irqsave(&waitq->lock, irqstate); + BUG_ON(list_empty(&entry->link)); + list_del_init(&entry->link); + spin_unlock_irqrestore(&waitq->lock, irqstate); +} + +void +waitq_prepare_to_wait(waitq_t *waitq, waitq_entry_t *entry, taskstate_t state) +{ + unsigned long irqstate; + + spin_lock_irqsave(&waitq->lock, irqstate); + if (list_empty(&entry->link)) + list_add(&entry->link, &waitq->waitq); + set_mb(entry->task->state, state); + spin_unlock_irqrestore(&waitq->lock, irqstate); +} + +void +waitq_finish_wait(waitq_t *waitq, waitq_entry_t *entry) +{ + set_mb(entry->task->state, TASKSTATE_READY); + waitq_remove_entry(waitq, entry); +} + +void +waitq_wakeup(waitq_t *waitq) +{ + unsigned long irqstate; + struct list_head *tmp; + waitq_entry_t *entry; + + spin_lock_irqsave(&waitq->lock, irqstate); + list_for_each(tmp, &waitq->waitq) { + entry = list_entry(tmp, waitq_entry_t, link); + sched_wakeup_task( + entry->task, + (TASKSTATE_UNINTERRUPTIBLE | TASKSTATE_INTERRUPTIBLE) + ); + } + spin_unlock_irqrestore(&waitq->lock, irqstate); +}