2010.01.21 This really needs serious stress testing to see if the locking is working. Idea - generate 10,000 processes to do waits and signals randomly and test against this experiment with locking and the experiment 1 without locking. See if you can get experiment one to crash but not this experiment 2 code with locking. 2010.01.21 Seems to work OK! Of course I can't tell if locking is really working to prevent race conditions, but at least it doesn't crash or fail to otherwise work of simple test cases. NOTE: I tried to do a control Z after a wait to put the wait in the background, but got no response. Of course, this is because I put the task state as TASK_UNTERRUPTIBLE. But after the wait started running again, the ctl Z was sent and suddenly wait was in the background! I had to fg and watch it finish. Now I could try putting the task state as TASK_INTERRUPTIBLE, but then the interrupt might not know how to properly remove and re-insert the task into the wait queue because I'm not using wait queues in the intended way! (Yet). That's the next experiment - a single wait queue used as intended. After than, two wait queues and then finally an array of wait queues. 2010.01.21 In order to use the locks like sleep_on and wake_up I will declare a wait queue so I get a lock, but I won't use the queue. Next experiment I'll use the queue. 2010.01.21 Here's the locking scheme used by sleep_on. It is pretty much the same as in Nutt, but some parameter changes. Note the slight asymetry in the locking. SLEEP_ON_HEAD wq_write_lock_irqsave(&q->lock, flags) __add_wait_queue(q, &wait) wq_write_unlock(&q->lock, flags) A schedule() call is here in the middle, which explains the need for the outer bracketing irqsave and irqrestore. SLEEP_ON_TAIL wq_write_lock_irq(&q->lock) __remove_wait_queue(q, &wait) wq_write_unlock_irqrestore(&q->lock, flags) 2010.01.21 Here's the locking scheme used by wake_up. See line 738 in sched.c of the LXR Linux 2.4-31 repository. wq_read_lock_irqsave(&q->lock, flags) wq_read_unlock_irqrestore($q->lock, flags) I assume the irqsave and restore is key. I don't know what flags is for or what to put in it if anything. It apparently has to do with the irqsave and irqrestore. 2010.01.21 I've spent more time looking at the sleep_on and wake_up functions in the kernel and the locking they use. It looks like following those examples will be the right locks to use. Here's the appropriate files. has macros for wake_up that match Nutt. has __wakeup core functions has sleep_on and related macros. 2010.01.20 I believe the appropriate locking is a spinlock because we are providing mutual exclusion over a single shared variable in a multi-core environment. Look at to see all the spin locks. For this simple example we want a lock that allows multiple readers but one writer exclusive of readers and writers. But, of course, since both eventWait and eventSig are writers, then we really want just writer exclusion. Even more primitively, we want test and set exclusion. But I don't think that will work at this level of programming. 2010.01.20 This experiment 2 starts with the code of experiment 1 and inserts the required mutual exclusion around the testing and update of my_wait_task variable. Testing and update of my_wait_task must be atomic to avoid race conditions.