Condition variables changes:

* Removed left-over commented C implementation.
* It is now possible for a thread to wait for more than one condition
  variable at a time.
* Made waiting for condition variables optionally interruptable.
* Renamed Notify() method to NotifyAll() and added a NotifyOne(), so
  that it is now possible to wake up only one of the waiting threads.
Pretty much untested at the moment.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22081 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-08-26 23:53:12 +00:00
parent 61b50eed27
commit ff308b0b49
5 changed files with 250 additions and 195 deletions
+23 -8
View File
@@ -10,6 +10,7 @@
#include <OS.h>
#include <KernelExport.h>
#include <condition_variable.h>
#include <debug.h>
#include <kernel.h>
#include <kscheduler.h>
@@ -221,12 +222,26 @@ is_kill_signal_pending(void)
}
/** Delivers the \a signal to the \a thread, but doesn't handle the signal -
* it just makes sure the thread gets the signal, ie. unblocks it if needed.
* This function must be called with interrupts disabled and the
* thread lock held.
*/
/*! Tries to interrupt a thread waiting for a semaphore or a condition variable.
Interrupts must be disabled, the thread lock be held. Note, that the thread
lock may temporarily be released.
*/
static status_t
signal_interrupt_thread(struct thread* thread)
{
if (thread->sem.blocking >= 0)
return sem_interrupt_thread(thread);
else if (thread->condition_variable_entry)
return condition_variable_interrupt_thread(thread);
return B_BAD_VALUE;
}
/*! Delivers the \a signal to the \a thread, but doesn't handle the signal -
it just makes sure the thread gets the signal, ie. unblocks it if needed.
This function must be called with interrupts disabled and the
thread lock held.
*/
static status_t
deliver_signal(struct thread *thread, uint signal, uint32 flags)
{
@@ -260,7 +275,7 @@ deliver_signal(struct thread *thread, uint signal, uint32 flags)
mainThread->state = mainThread->next_state = B_THREAD_READY;
scheduler_enqueue_in_run_queue(mainThread);
} else if (mainThread->state == B_THREAD_WAITING)
sem_interrupt_thread(mainThread);
signal_interrupt_thread(mainThread);
// Supposed to fall through
}
@@ -270,7 +285,7 @@ deliver_signal(struct thread *thread, uint signal, uint32 flags)
thread->state = thread->next_state = B_THREAD_READY;
scheduler_enqueue_in_run_queue(thread);
} else if (thread->state == B_THREAD_WAITING)
sem_interrupt_thread(thread);
signal_interrupt_thread(thread);
break;
case SIGCONT:
@@ -289,7 +304,7 @@ deliver_signal(struct thread *thread, uint signal, uint32 flags)
& (~thread->sig_block_mask | SIGNAL_TO_MASK(SIGCHLD))) {
// Interrupt thread if it was waiting
if (thread->state == B_THREAD_WAITING)
sem_interrupt_thread(thread);
signal_interrupt_thread(thread);
}
break;
}