os_kernel_lab/labcodes/lab7/kern/sync/monitor.h

91 lines
4.3 KiB
C
Raw Normal View History

2012-08-22 12:32:13 +08:00
#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__ */