X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=misc%2Ftest_vm%2Fsrc%2Fgeekos%2Fsynch.c;fp=misc%2Ftest_vm%2Fsrc%2Fgeekos%2Fsynch.c;h=0000000000000000000000000000000000000000;hp=86e7191efd075ba696adf097d7f4891cc183bb89;hb=a70930549d1b741704dd7af4e6bb0e89f6f8a519;hpb=afb634a80f946634454a5d067a92aa600227bd93 diff --git a/misc/test_vm/src/geekos/synch.c b/misc/test_vm/src/geekos/synch.c deleted file mode 100644 index 86e7191..0000000 --- a/misc/test_vm/src/geekos/synch.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Synchronization primitives - * Copyright (c) 2001,2004 David H. Hovemeyer - * $Revision: 1.1 $ - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "COPYING". - */ - -#include -#include -#include -#include -#include - -/* - * NOTES: - * - The GeekOS mutex and condition variable APIs are based on those - * in pthreads. - * - Unlike disabling interrupts, mutexes offer NO protection against - * concurrent execution of interrupt handlers. Mutexes and - * condition variables should only be used from kernel threads, - * with interrupts enabled. - */ - -/* ---------------------------------------------------------------------- - * Private functions - * ---------------------------------------------------------------------- */ - -/* - * The mutex is currently locked. - * Atomically reenable preemption and wait in the - * mutex's wait queue. - */ -static void Mutex_Wait(struct Mutex *mutex) -{ - KASSERT(mutex->state == MUTEX_LOCKED); - KASSERT(g_preemptionDisabled); - - Disable_Interrupts(); - g_preemptionDisabled = false; - Wait(&mutex->waitQueue); - g_preemptionDisabled = true; - Enable_Interrupts(); -} - -/* - * Lock given mutex. - * Preemption must be disabled. - */ -static __inline__ void Mutex_Lock_Imp(struct Mutex* mutex) -{ - KASSERT(g_preemptionDisabled); - - /* Make sure we're not already holding the mutex */ - KASSERT(!IS_HELD(mutex)); - - /* Wait until the mutex is in an unlocked state */ - while (mutex->state == MUTEX_LOCKED) { - Mutex_Wait(mutex); - } - - /* Now it's ours! */ - mutex->state = MUTEX_LOCKED; - mutex->owner = g_currentThread; -} - -/* - * Unlock given mutex. - * Preemption must be disabled. - */ -static __inline__ void Mutex_Unlock_Imp(struct Mutex* mutex) -{ - KASSERT(g_preemptionDisabled); - - /* Make sure mutex was actually acquired by this thread. */ - KASSERT(IS_HELD(mutex)); - - /* Unlock the mutex. */ - mutex->state = MUTEX_UNLOCKED; - mutex->owner = 0; - - /* - * If there are threads waiting to acquire the mutex, - * wake one of them up. Note that it is legal to inspect - * the queue with interrupts enabled because preemption - * is disabled, and therefore we know that no thread can - * concurrently add itself to the queue. - */ - if (!Is_Thread_Queue_Empty(&mutex->waitQueue)) { - Disable_Interrupts(); - Wake_Up_One(&mutex->waitQueue); - Enable_Interrupts(); - } -} - -/* ---------------------------------------------------------------------- - * Public functions - * ---------------------------------------------------------------------- */ - -/* - * Initialize given mutex. - */ -void Mutex_Init(struct Mutex* mutex) -{ - mutex->state = MUTEX_UNLOCKED; - mutex->owner = 0; - Clear_Thread_Queue(&mutex->waitQueue); -} - -/* - * Lock given mutex. - */ -void Mutex_Lock(struct Mutex* mutex) -{ - KASSERT(Interrupts_Enabled()); - - g_preemptionDisabled = true; - Mutex_Lock_Imp(mutex); - g_preemptionDisabled = false; -} - -/* - * Unlock given mutex. - */ -void Mutex_Unlock(struct Mutex* mutex) -{ - KASSERT(Interrupts_Enabled()); - - g_preemptionDisabled = true; - Mutex_Unlock_Imp(mutex); - g_preemptionDisabled = false; -} - -/* - * Initialize given condition. - */ -void Cond_Init(struct Condition* cond) -{ - Clear_Thread_Queue(&cond->waitQueue); -} - -/* - * Wait on given condition (protected by given mutex). - */ -void Cond_Wait(struct Condition* cond, struct Mutex* mutex) -{ - KASSERT(Interrupts_Enabled()); - - /* Ensure mutex is held. */ - KASSERT(IS_HELD(mutex)); - - /* Turn off scheduling. */ - g_preemptionDisabled = true; - - /* - * Release the mutex, but leave preemption disabled. - * No other threads will be able to run before this thread - * is able to wait. Therefore, this thread will not - * miss the eventual notification on the condition. - */ - Mutex_Unlock_Imp(mutex); - - /* - * Atomically reenable preemption and wait in the condition wait queue. - * Other threads can run while this thread is waiting, - * and eventually one of them will call Cond_Signal() or Cond_Broadcast() - * to wake up this thread. - * On wakeup, disable preemption again. - */ - Disable_Interrupts(); - g_preemptionDisabled = false; - Wait(&cond->waitQueue); - g_preemptionDisabled = true; - Enable_Interrupts(); - - /* Reacquire the mutex. */ - Mutex_Lock_Imp(mutex); - - /* Turn scheduling back on. */ - g_preemptionDisabled = false; -} - -/* - * Wake up one thread waiting on the given condition. - * The mutex guarding the condition should be held! - */ -void Cond_Signal(struct Condition* cond) -{ - KASSERT(Interrupts_Enabled()); - Disable_Interrupts(); /* prevent scheduling */ - Wake_Up_One(&cond->waitQueue); - Enable_Interrupts(); /* resume scheduling */ -} - -/* - * Wake up all threads waiting on the given condition. - * The mutex guarding the condition should be held! - */ -void Cond_Broadcast(struct Condition* cond) -{ - KASSERT(Interrupts_Enabled()); - Disable_Interrupts(); /* prevent scheduling */ - Wake_Up(&cond->waitQueue); - Enable_Interrupts(); /* resume scheduling */ -}