/** * @ingroup monitors * * Return a monitor's count * @param mon target monitor * @return count from montab entry on success, SYSERR on failure */ syscall moncount(monitor mon) { if (isbadmon(mon)) { return SYSERR; } return (montab[mon].count); }
/** * @ingroup monitors * * Current thread attempts to grab the lock on a monitor. * If another thread does not hold the lock the current thread owns the lock * and increases the monitor's count by one. Otherwise, the thread waits. * @param mon target monitor * @return OK on success, SYSERR on failure */ syscall lock(monitor mon) { register struct monent *monptr; irqmask im; im = disable(); if (isbadmon(mon)) { restore(im); return SYSERR; } monptr = &montab[mon]; /* if no thread owns the lock, the current thread claims it */ if (NOOWNER == monptr->owner) { monptr->owner = thrcurrent; /* current thread now owns the lock */ (monptr->count)++; /* add 1 "lock" to the monitor's count */ wait(monptr->sem); /* this thread owns the semaphore */ } else { /* if current thread owns the lock increase count; dont wait on sem */ if (thrcurrent == monptr->owner) { (monptr->count)++; } /* if another thread owns the lock, wait on sem until monitor is free */ else { wait(monptr->sem); monptr->owner = thrcurrent; (monptr->count)++; } } restore(im); return OK; }
/** * @ingroup monitors * * Free a monitor previously allocated with moncreate(). * * A monitor must only be freed when no thread has it locked -- that is, either * the monitor is unowned, or is owned by a thread that has been killed. * * @param mon * The monitor to free. * * @return * ::OK on success; ::SYSERR on failure (@p mon did not specify a valid, * allocated monitor). */ syscall monfree(monitor mon) { struct monent *monptr; irqmask im; im = disable(); /* make sure the specified monitor is valid and allocated */ if (isbadmon(mon)) { restore(im); return SYSERR; } monptr = &montab[mon]; /* free the monitor's semaphore and mark the monitor table entry as free */ semfree(monptr->sem); monptr->state = MFREE; restore(im); return OK; }