I'm learning a operating system course from Harvard's cs course cs161. And I find that this url is useful for the ASST1 which is tips on implement lock and condition variable.
http://www.cs.toronto.edu/~demke/369S.05/Assignments/A1-hints.html
Design Condition Variable Functions
The original idea behind a condition variable is to allow a thread to suspend itself while executing in a monitor until some boolean condition is satisfied. "Executing in a monitor" implies that the thread is holding some lock, which must be passed as an argument to the cv_wait function. Threads that call cv_wait() always block, and it is important that they release the lock before doing so. Before returning from cv_wait(), the thread must re-acquire the lock. Thus, the lock is held when cv_wait() is called, and is held when cv_wait returns, but must be released while the thread sleeps.
The pseudocode for cv_wait() is given below:
cv_wait(struct lock *lock, struct cv *cv) {
// Atomically, do the following:
// 1. release the lock
// 2. put the thread to sleep on the condition variable "cv"
// 3. re-acquire the lock
}
The "signal" operation on a condition variable allows a thread executing in a monitor (which implies it must be holding the same lock that the waiting thread was holding when it called cv_wait) to notify a waiting thread that the thing it was waiting for has happened. The cv_signal() function should wake up exactly one thread waiting on the address "cv". However, a read of the thread_wakeup() function (used by the semaphore V() code) shows that it will wake all threads waiting on the same condition variable address. You will need to implement a "thread_wakeone" function which is identical to thread_wakeup(), except that it wakes a single thread waiting on a given address, rather than all of them.
The cv_broadcast operation is identical to signal, except that it should wake up all threads waiting on the cv. The original thread_wakeup() function is ideal for this.