/* @(#)vm_mp.c 1.1 94/10/31 */ /* * Copyright (c) 1986 by Sun Microsystems, Inc. */ /* * VM - multiprocessor/ing support. * * Currently the kmon_enter() / kmon_exit() pair implements a * simple monitor for objects protected by the appropriate lock. * The kcv_wait() / kcv_broadcast pait implements a simple * condition variable which can be used for `sleeping' * and `waking' inside a monitor if some resource is * is needed which is not available. * * XXX - this code is written knowing about the semantics * of sleep/wakeup and UNIX scheduling on a uniprocessor machine. */ #ifdef KMON_DEBUG #include #include #define ISLOCKED 0x1 #define LOCKWANT 0x2 /* * kmon_enter is used as a type of multiprocess semaphore * used to implement a monitor where the lock represents * the ability to operate on the associated object. * For now, the lock/object association is done * by convention only. */ void kmon_enter(lk) kmon_t *lk; { int s; s = spl6(); while ((lk->dummy & ISLOCKED) != 0) { #ifdef notnow lk->dummy |= LOCKWANT; (void) sleep((char *)lk, PSWP+1); #else notnow panic("kmon_enter"); #endif notnow } lk->dummy |= ISLOCKED; (void) splx(s); } /* * Release the lock associated with a monitor, * waiting up anybody that has already decided * to wait for this lock (monitor). */ void kmon_exit(lk) kmon_t *lk; { int s; if ((lk->dummy & ISLOCKED) == 0) /* paranoid */ panic("kmon_exit not locked"); s = spl6(); lk->dummy &= ~ISLOCKED; if ((lk->dummy & LOCKWANT) != 0) { lk->dummy &= ~LOCKWANT; wakeup((char *)lk); } (void) splx(s); } /* * Wait for the named condition variable. * Must already have the monitor lock when kcv_wait is called. */ void kcv_wait(lk, cond) kmon_t *lk; char *cond; { int s; if ((lk->dummy & ISLOCKED) == 0) /* paranoia */ panic("kcv_wait not locked"); s = spl6(); lk->dummy &= ~ISLOCKED; /* release lock */ (void) sleep(cond, PSWP+1); if ((lk->dummy & ISLOCKED) != 0) /* more paranoia */ panic("kcv_wait locked"); lk->dummy |= ISLOCKED; /* reacquire lock */ (void) splx(s); } /* * Wake up all processes waiting on the named condition variable. * * We just use current UNIX sleep/wakeup semantics to delay the actual * context switching until later after we have released the lock. */ void kcv_broadcast(lk, cond) kmon_t *lk; char *cond; { if ((lk->dummy & ISLOCKED) == 0) panic("kcv_broadcast"); wakeup(cond); } #endif /* !KMON_DEBUG */