X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=kitten%2Finclude%2Flwk%2Fwaitq.h;fp=kitten%2Finclude%2Flwk%2Fwaitq.h;h=f77c7e8e0621cb2cebe236f158ee847c7aaf377c;hb=66a1a4c7a9edcd7d8bc207aca093d694a6e6b5b2;hp=0000000000000000000000000000000000000000;hpb=f7cf9c19ecb0a589dd45ae0d2c91814bd3c2acc2;p=palacios.git diff --git a/kitten/include/lwk/waitq.h b/kitten/include/lwk/waitq.h new file mode 100644 index 0000000..f77c7e8 --- /dev/null +++ b/kitten/include/lwk/waitq.h @@ -0,0 +1,57 @@ +#ifndef _LWK_WAITQ_H +#define _LWK_WAITQ_H + +#include +#include +#include + +typedef struct waitq { + spinlock_t lock; + struct list_head waitq; +} waitq_t; + +typedef struct waitq_entry { + struct task_struct * task; + struct list_head link; +} waitq_entry_t; + +#define DECLARE_WAITQ(name) \ + waitq_t name = { \ + .lock = SPIN_LOCK_UNLOCKED, \ + .waitq = { &(name).waitq, &(name).waitq } \ + } + +#define DECLARE_WAITQ_ENTRY(name, tsk) \ + waitq_entry_t name = { \ + .task = tsk, \ + .link = { &(name).link, &(name).link } \ + } + +extern void waitq_init(waitq_t *waitq); +extern void waitq_init_entry(waitq_entry_t *entry, struct task_struct *task); +extern bool waitq_active(waitq_t *waitq); +extern void waitq_add_entry(waitq_t *waitq, waitq_entry_t *entry); +extern void waitq_prepare_to_wait(waitq_t *waitq, waitq_entry_t *entry, + taskstate_t state); +extern void waitq_finish_wait(waitq_t *waitq, waitq_entry_t *entry); +extern void waitq_wakeup(waitq_t *waitq); + +/** + * This puts the task to sleep until condition becomes true. + * This must be a macro because condition is tested repeatedly, not just + * when wait_event() is first called. + */ +#define wait_event(waitq, condition) \ +do { \ + DECLARE_WAITQ_ENTRY(__entry, current); \ + for (;;) { \ + waitq_prepare_to_wait(&waitq, &__entry, \ + TASKSTATE_UNINTERRUPTIBLE); \ + if (condition) \ + break; \ + schedule(); \ + } \ + waitq_finish_wait(&waitq, &__entry); \ +} while (0) + +#endif