> If I understand him correctly, the idea is to make the struct one node of a
> Btree -like construct.
> IE: (struct-of 2-or3-processes)(link to next struct)
Nope..
The code might be the simplest explanation here
diff -u --new-file --recursive --exclude-from /usr/src/exclude elks/kernel/sleepwake.c
elks-ac/kernel/sleepwake.c
--- elks/kernel/sleepwake.c Thu Aug 19 16:13:55 1999
+++ elks-ac/kernel/sleepwake.c Mon Jun 19 15:14:01 2000
@@ -10,84 +10,52 @@
* Copyright (C) 1991, 1992 Linus Torvalds
* Elks tweaks (C) 1995 Alan Cox.
*
+ * Copyright (C) 2000 Alan Cox.
+ * Rewrote the entire queue functionality to reflect ELKS actual needs
+ * not Linux needs
*/
-void add_wait_queue(p,wait)
-register struct wait_queue **p;
-register struct wait_queue *wait;
+void wait_set(p)
+register struct wait_queue *p;
{
- flag_t flags;
- save_flags(flags);
- icli();
- if(!*p)
- {
- wait->next = wait;
- *p = wait;
- }
- else
- {
- wait->next = (*p)->next;
- (*p)->next = wait;
- }
- restore_flags(flags);
+ if(current->waitpt)
+ panic("double wait");
+ current->waitpt=p;
}
-void remove_wait_queue(p,wait)
-struct wait_queue **p;
-register struct wait_queue *wait;
+void wait_clear(p)
+struct wait_queue *p;
{
- flag_t flags;
- save_flags(flags);
- icli();
- if((*p==wait) && ((*p=wait->next)==wait))
- *p=NULL;
- else
- {
- register struct wait_queue *tmp=wait;
- while(tmp->next != wait)
- tmp = tmp->next;
- tmp->next = wait->next;
- }
- wait->next=NULL;
- restore_flags(flags);
+ if(current->waitpt!=p)
+ printk("wrong waitpt");
+ current->waitpt=NULL;
}
int marker;
static void __sleep_on(p,state)
-register struct wait_queue **p;
+register struct wait_queue *p;
int state;
{
- flag_t flags;
- struct wait_queue wait;
-
- wait.next=NULL;
- wait.task = current;
-
- if(!p)
- return;
if(current==&task[0]) {
printk("task[0] trying to sleep ");
panic("from %x", marker);
}
current->state = state;
- add_wait_queue(p, &wait);
- save_flags(flags);
- isti();
+ wait_set(p);
schedule();
- remove_wait_queue(p, &wait);
- restore_flags(flags);
+ wait_clear(p);
}
void sleep_on(p)
-struct wait_queue **p;
+struct wait_queue *p;
{
marker = peekw(get_ds(), get_bp() + 2);
__sleep_on(p, TASK_UNINTERRUPTIBLE);
}
void interruptible_sleep_on(p)
-struct wait_queue **p;
+struct wait_queue *p;
{
__sleep_on(p, TASK_INTERRUPTIBLE);
}
@@ -127,54 +95,29 @@
*/
void _wake_up(q,it)
-struct wait_queue **q;
+struct wait_queue *q;
int it;
{
- register struct wait_queue *tmp;
- register struct task_struct * p;
-
- if (!q || !(tmp = *q))
- return;
- do {
- if ((p = tmp->task) != NULL) {
- if ((it && (p->state == TASK_UNINTERRUPTIBLE)) ||
- (p->state == TASK_INTERRUPTIBLE))
- wake_up_process(p);
- }
- if (!tmp->next) {
- printk("wait_queue is bad\n");
- printk(" q = %x\n",q);
- printk(" *q = %x\n",*q);
- printk(" tmp = %x\n",tmp);
- break;
- }
- tmp = tmp->next;
- } while (tmp != *q);
-}
-
-#ifdef NOTYET
-void wake_up_interruptible(q)
-struct wait_queue **q;
-{
- register struct wait_queue *tmp;
register struct task_struct * p;
-
- if (!q || !(tmp = *q))
- return;
- do {
- if ((p = tmp->task) != NULL) {
- if (p->state == TASK_INTERRUPTIBLE)
+ int phash = 1<<((((int)q)>>4)&15);
+ extern struct wait_queue select_poll;
+
+ for_each_task(p)
+ {
+ if(p->waitpt==q)
+ {
+ if(p->state == TASK_INTERRUPTIBLE ||
+ (it && p->state == TASK_UNINTERRUPTIBLE))
wake_up_process(p);
}
- if (!tmp->next) {
- printk("wait_queue is bad\n");
- printk(" q = %p\n",q);
- printk(" *q = %p\n",*q);
- printk(" tmp = %p\n",tmp);
- break;
+ if(p->waitpt==&select_poll)
+ {
+ if(p->pollhash&phash)
+ {
+ if(p->state == TASK_INTERRUPTIBLE ||
+ (it && p->state == TASK_UNINTERRUPTIBLE))
+ wake_up_process(p);
+ }
}
- tmp = tmp->next;
- } while (tmp != *q);
+ }
}
-
-#endif