《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
4.3 KiB

12 years ago
  1. #ifndef __KERN_SYNC_MONITOR_CONDVAR_H__
  2. #define __KERN_SYNC_MOINTOR_CONDVAR_H__
  3. #include <sem.h>
  4. /* In [OS CONCEPT] 7.7 section, the accurate define and approximate implementation of MONITOR was introduced.
  5. * INTRODUCTION:
  6. * Monitors were invented by C. A. R. Hoare and Per Brinch Hansen, and were first implemented in Brinch Hansen's
  7. * 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.
  8. * DEFNIE & CHARACTERISTIC:
  9. * A monitor is a collection of procedures, variables, and data structures grouped together.
  10. * Processes can call the monitor procedures but cannot access the internal data structures.
  11. * Only one process at a time may be be active in a monitor.
  12. * Condition variables allow for blocking and unblocking.
  13. * cv.wait() blocks a process.
  14. * The process is said to be waiting for (or waiting on) the condition variable cv.
  15. * cv.signal() (also called cv.notify) unblocks a process waiting for the condition variable cv.
  16. * When this occurs, we need to still require that only one process is active in the monitor. This can be done in several ways:
  17. * on some systems the old process (the one executing the signal) leaves the monitor and the new one enters
  18. * on some systems the signal must be the last statement executed inside the monitor.
  19. * on some systems the old process will block until the monitor is available again.
  20. * on some systems the new process (the one unblocked by the signal) will remain blocked until the monitor is available again.
  21. * 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.
  22. * You should not think of a condition variable as a variable in the traditional sense.
  23. * It does not have a value.
  24. * Think of it as an object in the OOP sense.
  25. * It has two methods, wait and signal that manipulate the calling process.
  26. * IMPLEMENTATION:
  27. * monitor mt {
  28. * ----------------variable------------------
  29. * semaphore mutex;
  30. * semaphore next;
  31. * int next_count;
  32. * condvar {int count, sempahore sem} cv[N];
  33. * other variables in mt;
  34. * --------condvar wait/signal---------------
  35. * cond_wait (cv) {
  36. * cv.count ++;
  37. * if(mt.next_count>0)
  38. * signal(mt.next)
  39. * else
  40. * signal(mt.mutex);
  41. * wait(cv.sem);
  42. * cv.count --;
  43. * }
  44. *
  45. * cond_signal(cv) {
  46. * if(cv.count>0) {
  47. * mt.next_count ++;
  48. * signal(cv.sem);
  49. * wait(mt.next);
  50. * mt.next_count--;
  51. * }
  52. * }
  53. * --------routines in monitor---------------
  54. * routineA_in_mt () {
  55. * wait(mt.mutex);
  56. * ...
  57. * real body of routineA
  58. * ...
  59. * if(next_count>0)
  60. * signal(mt.next);
  61. * else
  62. * signal(mt.mutex);
  63. * }
  64. */
  65. typedef struct monitor monitor_t;
  66. typedef struct condvar{
  67. semaphore_t sem; // the sem semaphore is used to down the waiting proc, and the signaling proc should up the waiting proc
  68. int count; // the number of waiters on condvar
  69. monitor_t * owner; // the owner(monitor) of this condvar
  70. } condvar_t;
  71. typedef struct monitor{
  72. semaphore_t mutex; // the mutex lock for going into the routines in monitor, should be initialized to 1
  73. 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.
  74. int next_count; // the number of of sleeped signaling proc
  75. condvar_t *cv; // the condvars in monitor
  76. } monitor_t;
  77. // Initialize variables in monitor.
  78. void monitor_init (monitor_t *cvp, size_t num_cv);
  79. // Unlock one of threads waiting on the condition variable.
  80. void cond_signal (condvar_t *cvp);
  81. // Suspend calling thread on a condition variable waiting for condition atomically unlock mutex in monitor,
  82. // and suspends calling thread on conditional variable after waking up locks mutex.
  83. void cond_wait (condvar_t *cvp);
  84. #endif /* !__KERN_SYNC_MONITOR_CONDVAR_H__ */