|
|
- #ifndef __KERN_SYNC_MONITOR_CONDVAR_H__
- #define __KERN_SYNC_MOINTOR_CONDVAR_H__
-
- #include <sem.h>
- /* In [OS CONCEPT] 7.7 section, the accurate define and approximate implementation of MONITOR was introduced.
- * INTRODUCTION:
- * Monitors were invented by C. A. R. Hoare and Per Brinch Hansen, and were first implemented in Brinch Hansen's
- * Concurrent Pascal language. Generally, a monitor is a language construct and the compiler usually enforces mutual exclusion. Compare this with semaphores, which are usually an OS construct.
- * DEFNIE & CHARACTERISTIC:
- * A monitor is a collection of procedures, variables, and data structures grouped together.
- * Processes can call the monitor procedures but cannot access the internal data structures.
- * Only one process at a time may be be active in a monitor.
- * Condition variables allow for blocking and unblocking.
- * cv.wait() blocks a process.
- * The process is said to be waiting for (or waiting on) the condition variable cv.
- * cv.signal() (also called cv.notify) unblocks a process waiting for the condition variable cv.
- * When this occurs, we need to still require that only one process is active in the monitor. This can be done in several ways:
- * on some systems the old process (the one executing the signal) leaves the monitor and the new one enters
- * on some systems the signal must be the last statement executed inside the monitor.
- * on some systems the old process will block until the monitor is available again.
- * on some systems the new process (the one unblocked by the signal) will remain blocked until the monitor is available again.
- * If a condition variable is signaled with nobody waiting, the signal is lost. Compare this with semaphores, in which a signal will allow a process that executes a wait in the future to no block.
- * You should not think of a condition variable as a variable in the traditional sense.
- * It does not have a value.
- * Think of it as an object in the OOP sense.
- * It has two methods, wait and signal that manipulate the calling process.
- * IMPLEMENTATION:
- * monitor mt {
- * ----------------variable------------------
- * semaphore mutex;
- * semaphore next;
- * int next_count;
- * condvar {int count, sempahore sem} cv[N];
- * other variables in mt;
- * --------condvar wait/signal---------------
- * cond_wait (cv) {
- * cv.count ++;
- * if(mt.next_count>0)
- * signal(mt.next)
- * else
- * signal(mt.mutex);
- * wait(cv.sem);
- * cv.count --;
- * }
- *
- * cond_signal(cv) {
- * if(cv.count>0) {
- * mt.next_count ++;
- * signal(cv.sem);
- * wait(mt.next);
- * mt.next_count--;
- * }
- * }
- * --------routines in monitor---------------
- * routineA_in_mt () {
- * wait(mt.mutex);
- * ...
- * real body of routineA
- * ...
- * if(next_count>0)
- * signal(mt.next);
- * else
- * signal(mt.mutex);
- * }
- */
-
- typedef struct monitor monitor_t;
-
- typedef struct condvar{
- semaphore_t sem; // the sem semaphore is used to down the waiting proc, and the signaling proc should up the waiting proc
- int count; // the number of waiters on condvar
- monitor_t * owner; // the owner(monitor) of this condvar
- } condvar_t;
-
- typedef struct monitor{
- semaphore_t mutex; // the mutex lock for going into the routines in monitor, should be initialized to 1
- semaphore_t next; // the next semaphore is used to down the signaling proc itself, and the other OR wakeuped waiting proc should wake up the sleeped signaling proc.
- int next_count; // the number of of sleeped signaling proc
- condvar_t *cv; // the condvars in monitor
- } monitor_t;
-
- // Initialize variables in monitor.
- void monitor_init (monitor_t *cvp, size_t num_cv);
- // Unlock one of threads waiting on the condition variable.
- void cond_signal (condvar_t *cvp);
- // Suspend calling thread on a condition variable waiting for condition atomically unlock mutex in monitor,
- // and suspends calling thread on conditional variable after waking up locks mutex.
- void cond_wait (condvar_t *cvp);
-
- #endif /* !__KERN_SYNC_MONITOR_CONDVAR_H__ */
|