《操作系统》的实验代码。
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.

196 lines
6.0 KiB

12 years ago
  1. #include <stdio.h>
  2. #include <proc.h>
  3. #include <sem.h>
  4. #include <monitor.h>
  5. #include <assert.h>
  6. #define N 5 /* 哲学家数目 */
  7. #define LEFT (i-1+N)%N /* i的左邻号码 */
  8. #define RIGHT (i+1)%N /* i的右邻号码 */
  9. #define THINKING 0 /* 哲学家正在思考 */
  10. #define HUNGRY 1 /* 哲学家想取得叉子 */
  11. #define EATING 2 /* 哲学家正在吃面 */
  12. #define TIMES 4 /* 吃4次饭 */
  13. #define SLEEP_TIME 10
  14. //---------- philosophers problem using semaphore ----------------------
  15. int state_sema[N]; /* 记录每个人状态的数组 */
  16. /* 信号量是一个特殊的整型变量 */
  17. semaphore_t mutex; /* 临界区互斥 */
  18. semaphore_t s[N]; /* 每个哲学家一个信号量 */
  19. struct proc_struct *philosopher_proc_sema[N];
  20. void phi_test_sema(i) /* i:哲学家号码从0到N-1 */
  21. {
  22. if(state_sema[i]==HUNGRY&&state_sema[LEFT]!=EATING
  23. &&state_sema[RIGHT]!=EATING)
  24. {
  25. state_sema[i]=EATING;
  26. up(&s[i]);
  27. }
  28. }
  29. void phi_take_forks_sema(int i) /* i:哲学家号码从0到N-1 */
  30. {
  31. down(&mutex); /* 进入临界区 */
  32. state_sema[i]=HUNGRY; /* 记录下哲学家i饥饿的事实 */
  33. phi_test_sema(i); /* 试图得到两只叉子 */
  34. up(&mutex); /* 离开临界区 */
  35. down(&s[i]); /* 如果得不到叉子就阻塞 */
  36. }
  37. void phi_put_forks_sema(int i) /* i:哲学家号码从0到N-1 */
  38. {
  39. down(&mutex); /* 进入临界区 */
  40. state_sema[i]=THINKING; /* 哲学家进餐结束 */
  41. phi_test_sema(LEFT); /* 看一下左邻居现在是否能进餐 */
  42. phi_test_sema(RIGHT); /* 看一下右邻居现在是否能进餐 */
  43. up(&mutex); /* 离开临界区 */
  44. }
  45. int philosopher_using_semaphore(void * arg) /* i:哲学家号码,从0到N-1 */
  46. {
  47. int i, iter=0;
  48. i=(int)arg;
  49. cprintf("I am No.%d philosopher_sema\n",i);
  50. while(iter++<TIMES)
  51. { /* 无限循环 */
  52. cprintf("Iter %d, No.%d philosopher_sema is thinking\n",iter,i); /* 哲学家正在思考 */
  53. do_sleep(SLEEP_TIME);
  54. phi_take_forks_sema(i);
  55. /* 需要两只叉子,或者阻塞 */
  56. cprintf("Iter %d, No.%d philosopher_sema is eating\n",iter,i); /* 进餐 */
  57. do_sleep(SLEEP_TIME);
  58. phi_put_forks_sema(i);
  59. /* 把两把叉子同时放回桌子 */
  60. }
  61. cprintf("No.%d philosopher_sema quit\n",i);
  62. return 0;
  63. }
  64. //-----------------philosopher problem using monitor ------------
  65. /*PSEUDO CODE :philosopher problem using monitor
  66. * monitor dp
  67. * {
  68. * enum {thinking, hungry, eating} state[5];
  69. * condition self[5];
  70. *
  71. * void pickup(int i) {
  72. * state[i] = hungry;
  73. * if ((state[(i+4)%5] != eating) && (state[(i+1)%5] != eating)) {
  74. * state[i] = eating;
  75. * else
  76. * self[i].wait();
  77. * }
  78. *
  79. * void putdown(int i) {
  80. * state[i] = thinking;
  81. * if ((state[(i+4)%5] == hungry) && (state[(i+3)%5] != eating)) {
  82. * state[(i+4)%5] = eating;
  83. * self[(i+4)%5].signal();
  84. * }
  85. * if ((state[(i+1)%5] == hungry) && (state[(i+2)%5] != eating)) {
  86. * state[(i+1)%5] = eating;
  87. * self[(i+1)%5].signal();
  88. * }
  89. * }
  90. *
  91. * void init() {
  92. * for (int i = 0; i < 5; i++)
  93. * state[i] = thinking;
  94. * }
  95. * }
  96. */
  97. struct proc_struct *philosopher_proc_condvar[N]; // N philosopher
  98. int state_condvar[N]; // the philosopher's state: EATING, HUNGARY, THINKING
  99. monitor_t mt, *mtp=&mt; // monitor
  100. void phi_test_condvar (i) {
  101. if(state_condvar[i]==HUNGRY&&state_condvar[LEFT]!=EATING
  102. &&state_condvar[RIGHT]!=EATING) {
  103. cprintf("phi_test_condvar: state_condvar[%d] will eating\n",i);
  104. state_condvar[i] = EATING ;
  105. cprintf("phi_test_condvar: signal self_cv[%d] \n",i);
  106. cond_signal(&mtp->cv[i]) ;
  107. }
  108. }
  109. void phi_take_forks_condvar(int i) {
  110. down(&(mtp->mutex));
  111. //--------into routine in monitor--------------
  112. // LAB7 EXERCISE1: YOUR CODE
  113. // I am hungry
  114. // try to get fork
  115. //--------leave routine in monitor--------------
  116. if(mtp->next_count>0)
  117. up(&(mtp->next));
  118. else
  119. up(&(mtp->mutex));
  120. }
  121. void phi_put_forks_condvar(int i) {
  122. down(&(mtp->mutex));
  123. //--------into routine in monitor--------------
  124. // LAB7 EXERCISE1: YOUR CODE
  125. // I ate over
  126. // test left and right neighbors
  127. //--------leave routine in monitor--------------
  128. if(mtp->next_count>0)
  129. up(&(mtp->next));
  130. else
  131. up(&(mtp->mutex));
  132. }
  133. //---------- philosophers using monitor (condition variable) ----------------------
  134. int philosopher_using_condvar(void * arg) { /* arg is the No. of philosopher 0~N-1*/
  135. int i, iter=0;
  136. i=(int)arg;
  137. cprintf("I am No.%d philosopher_condvar\n",i);
  138. while(iter++<TIMES)
  139. { /* iterate*/
  140. cprintf("Iter %d, No.%d philosopher_condvar is thinking\n",iter,i); /* thinking*/
  141. do_sleep(SLEEP_TIME);
  142. phi_take_forks_condvar(i);
  143. /* need two forks, maybe blocked */
  144. cprintf("Iter %d, No.%d philosopher_condvar is eating\n",iter,i); /* eating*/
  145. do_sleep(SLEEP_TIME);
  146. phi_put_forks_condvar(i);
  147. /* return two forks back*/
  148. }
  149. cprintf("No.%d philosopher_condvar quit\n",i);
  150. return 0;
  151. }
  152. void check_sync(void){
  153. int i;
  154. //check semaphore
  155. sem_init(&mutex, 1);
  156. for(i=0;i<N;i++){
  157. sem_init(&s[i], 0);
  158. int pid = kernel_thread(philosopher_using_semaphore, (void *)i, 0);
  159. if (pid <= 0) {
  160. panic("create No.%d philosopher_using_semaphore failed.\n");
  161. }
  162. philosopher_proc_sema[i] = find_proc(pid);
  163. set_proc_name(philosopher_proc_sema[i], "philosopher_sema_proc");
  164. }
  165. //check condition variable
  166. monitor_init(&mt, N);
  167. for(i=0;i<N;i++){
  168. state_condvar[i]=THINKING;
  169. int pid = kernel_thread(philosopher_using_condvar, (void *)i, 0);
  170. if (pid <= 0) {
  171. panic("create No.%d philosopher_using_condvar failed.\n");
  172. }
  173. philosopher_proc_condvar[i] = find_proc(pid);
  174. set_proc_name(philosopher_proc_condvar[i], "philosopher_condvar_proc");
  175. }
  176. }