#include <lwp/lwp.h>
int mon_create(mid) mon_t *mid;
int mon_destroy(mid) mon_t mid;
int mon_enter(mid) mon_t mid;
int mon_exit(mid) mon_t mid;
int mon_enumerate(vec, maxsize) mon_t vec[]; /* list of all monitors */ int maxsize; /* max size of vec */
int mon_waiters(mid, owner, vec, maxsize) mon_t mid; /* monitor in question */ thread_t *owner; /* which thread owns the monitor */ thread_t vec[]; /* list of blocked threads */ int maxsize; /* max size of vec */
int mon_cond_enter(mid) mon_t mid;
int mon_break(mid) mon_t mid;
void MONITOR(mid) mon_t mid;
int SAMEMON(m1, m2) mon_t m1; mon_t m2;
Monitors are used to synchronize access to common resources. Although it is possible (on a uniprocessor) to use knowledge of how scheduling priorities work to serialize access to a resource, monitors (and condition variables) provide a general tool to provide the necessary synchronization.
mon_create() creates a new monitor and returns its identity in mid. mon_destroy() destroys a monitor, as well as any conditions bound to it (see cv_create.3l Because the lifetime of a monitor can transcend the lifetime of the LWP that created it, monitor destruction is not automatic upon LWP destruction.
mon_enter() blocks the calling thread (if the monitor is in use) until the monitor becomes free by being exited or by waiting on a condition (see cv_create.3l Threads unable to gain entry into the monitor are queued for monitor service by the priority of the thread requesting monitor access, FCFS within a priority. Monitor calls may nest. If, while holding monitor M1 a request for monitor M2 is made, M1 will be held until M2 can be acquired.
mon_cond_enter() will enter the monitor only if the monitor is not busy. Otherwise, an error is returned.
mon_enter() and mon_cond_enter() will allow a thread which already has the monitor to reenter the monitor. In this case, the nesting level of monitor entries is returned. Thus, the first time a monitor is entered, mon_enter() returns 0. The next time the monitor is entered, mon_enter() returns 1. mon_exit() frees the current monitor and allows the next thread blocked on the monitor (if any) to enter the monitor. However, if a monitor is entered more than once, mon_exit() returns the previous monitor nesting level without freeing the monitor to other threads. Thus, if the monitor was not reentered, mon_exit() returns 0.
mon_enumerate() lists all the monitors in the system. The vector supplied is filled in with the ID's of the monitors. maxsize is used to avoid exceeding the capacity of the list. If the number of monitors is greater than maxsize, only maxsize monitor ID's are filled in vec.
mon_waiters() puts the thread that currently owns the monitor in owner and all threads blocked on the monitor in vec (subject to the maxsize limitation), and returns the number of waiting threads.
mon_break() forces the release of a monitor lock not necessarily held by the invoking thread. This enables the next thread blocked on the monitor to enter it.
MONITOR is a macro that can be used at the start of a procedure to indicate that the procedure is a monitor. It uses the exception handling mechanism to ensure that the monitor is exited automatically when the procedure exits. Ordinarily, this single macro replaces paired mon_enter()- mon_exit() calls in a monitor procedure.
The SAMEMON macro is a convenient predicate used to compare two monitors for equality.
Monitor locks are released automatically when the LWP holding them dies. This may have implications for the validity of the monitor invariant (a condition that is always true outside of the monitor) if a thread unexpectedly terminates.
mon_create() returns the ID of a new monitor.
mon_destroy() returns:
mon_enter() returns the nesting level of the monitor.
mon_exit() returns the previous nesting level on success. On failure, it returns -1.
mon_enumerate() returns the total number of monitors.
mon_waiters() returns the number of threads waiting for the monitor.
mon_cond_enter() returns the nesting level of the monitor if the monitor is not busy. If the monitor is busy, it returns -1.
mon_break() returns:
The macro SAMEMON() returns 1 if the monitors specified by m1 and m2 are equal. It returns 0 otherwise.
mon_break() will fail if one or more of the following are true:
mon_cond_enter() will fail if one or more of the following are true:
mon_destroy() will fail if one or more of the following are true:
mon_exit() will fail if one or more of the following are true:
There should be language support to enforce the monitor enter-exit discipline.
Created by unroff & hp-tools. © somebody (See intro for details). All Rights Reserved. Last modified 11/5/97