Guest User

Untitled

a guest
Jun 13th, 2018
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.78 KB | None | 0 0
  1. #include "../../h/const.h"
  2.  
  3. #include "../../h/types.h"
  4.  
  5. #include "../../h/vpop.h"
  6.  
  7. #include "../../h/util.h"
  8.  
  9. #include "../../h/procq.e"
  10.  
  11. #include "../../h/asl.e"
  12.  
  13.  
  14.  
  15. #define NUM_DEV 15 /* number of devices */
  16.  
  17. #define QUANTUM 5000 /* 5ms */
  18.  
  19. #define DELAY 100000 /* 100ms */
  20.  
  21. #define MAXLEN 64 /* maximal size of a string */
  22.  
  23.  
  24.  
  25. extern int mem_size;
  26.  
  27. extern proc_link RQ;
  28.  
  29.  
  30.  
  31. /* global variables */
  32.  
  33. HIDDEN devsemtable_t devsemtable[NUM_DEV]; /* device sem table */
  34.  
  35. HIDDEN int pseudoclock;
  36.  
  37. long last_check_time = 0;
  38.  
  39.  
  40.  
  41. void static sleep () {
  42.  
  43. asm("stop #0x2000");
  44.  
  45. }
  46.  
  47.  
  48.  
  49. void intschedule () {
  50.  
  51. long timeslice = QUANTUM;
  52.  
  53. LDIT(&timeslice);
  54.  
  55. }
  56.  
  57.  
  58.  
  59. int check_devsem() {
  60.  
  61. int i;
  62.  
  63. for(i=0;i<NUM_DEV;i++) {
  64.  
  65. if(devsemtable[i].devsem <0)
  66.  
  67. return TRUE;
  68.  
  69. }
  70.  
  71. return FALSE;
  72.  
  73. }
  74.  
  75.  
  76.  
  77. void print_foo(char* buf) {
  78.  
  79. devreg_t *printer0 = (devreg_t *)0x1450;
  80.  
  81. printer0->d_amnt = MAXLEN; /* buffer size */
  82.  
  83. printer0->d_badd = buf; /* address of buf */
  84.  
  85. printer0->d_op = IOWRITE;
  86.  
  87. printer0->d_stat = -1; /* normal state 0-9 */
  88.  
  89. /* wait for the printer to finish printing */
  90.  
  91. while (printer0->d_stat == -1);
  92.  
  93. /* shut it down */
  94.  
  95. HALT();
  96.  
  97. }
  98.  
  99.  
  100.  
  101. /* handle the case of empty RQ */
  102.  
  103. void intdeadlock () {
  104.  
  105. /* any process blocked on pseudoclock? */
  106.  
  107. if (pseudoclock < 0) {
  108.  
  109. intschedule();
  110.  
  111. sleep();
  112.  
  113. }
  114.  
  115. /* any process blocked on I/O? */
  116.  
  117. else if (check_devsem())
  118.  
  119. sleep();
  120.  
  121. /* system shut down normally */
  122.  
  123. else if (headASL() == FALSE) {
  124.  
  125. /* print out the termination information */
  126.  
  127. char buf[MAXLEN] = "normal termination.";
  128.  
  129. print_foo(buf);
  130.  
  131. }
  132.  
  133. /* deadlock */
  134.  
  135. else {
  136.  
  137. char buf[MAXLEN] = "deadlock.";
  138.  
  139. print_foo(buf);
  140.  
  141. }
  142.  
  143. }
  144.  
  145.  
  146.  
  147. int on_sem(proc_t * p) {
  148.  
  149. int i=0;
  150.  
  151. for(;i<SEMMAX;i++) {
  152.  
  153. if(p->semvec[i] != (int*)NULL ) {
  154.  
  155. return TRUE;
  156.  
  157. }
  158.  
  159. }
  160.  
  161. return FALSE;
  162.  
  163. }
  164.  
  165.  
  166.  
  167. /* P/V for interrupts */
  168.  
  169. void intsemop (int *semaddr, int semop) {
  170.  
  171. long currenttime;
  172.  
  173. *semaddr += semop;
  174.  
  175. if ( semop == LOCK && *semaddr < 0 ) {
  176.  
  177. /*remove the head of RQ to the sem queue*/
  178.  
  179. proc_t *p = removeProc(&RQ);
  180.  
  181. STCK(&currenttime);
  182.  
  183. p->acc_time += currenttime - p->start_time;
  184.  
  185. insertBlocked(semaddr, p);
  186.  
  187. /* schedule the new head */
  188.  
  189. if (headQueue(RQ) != (proc_t *)NULL)
  190.  
  191. schedule();
  192.  
  193. else
  194.  
  195. intdeadlock();
  196.  
  197. }
  198.  
  199. else if (semop == UNLOCK && *semaddr <= 0) {
  200.  
  201. proc_t *p = removeBlocked(semaddr);
  202.  
  203. /* if not on any sem */
  204.  
  205. if (!on_sem(p)) {
  206.  
  207. insertProc(&RQ, p);
  208.  
  209. if(headQueue(RQ) == p)
  210.  
  211. schedule();
  212.  
  213. }
  214.  
  215. }
  216.  
  217. }
  218.  
  219.  
  220.  
  221. /* interrupt handler */
  222.  
  223. void static inthandler (int devtyp, int devnum) {
  224.  
  225. /* no wait_for_io happened */
  226.  
  227. if (devsemtable[devnum].devsem >= 0) {
  228.  
  229. devsemtable[devnum].devsem += UNLOCK;
  230.  
  231. devsemtable[devnum].devinfo.io_len = devsemtable[devnum].devreg_p->d_amnt;
  232.  
  233. devsemtable[devnum].devinfo.io_sta = devsemtable[devnum].devreg_p->d_stat;
  234.  
  235. }
  236.  
  237. /* wait_for_io happened */
  238.  
  239. else {
  240.  
  241. proc_t *p = headBlocked(&(devsemtable[devnum].devsem));
  242.  
  243. p->p_s.s_r[2] = devsemtable[devnum].devreg_p->d_amnt;
  244.  
  245. p->p_s.s_r[3] = devsemtable[devnum].devreg_p->d_stat;
  246.  
  247. intsemop(&(devsemtable[devnum].devsem), UNLOCK);
  248.  
  249. }
  250.  
  251. }
  252.  
  253.  
  254.  
  255. /* terminal interrupt handler */
  256.  
  257. void static intterminalhandler () {
  258.  
  259. int devtyp = TERMINAL;
  260.  
  261. int devnum = ((state_t *)0x9c8)->s_tmp.tmp_int.in_dno;
  262.  
  263. inthandler(devtyp, devnum + TERM0);
  264.  
  265. LDST((state_t *)0x9c8);
  266.  
  267. }
  268.  
  269.  
  270.  
  271. /* printer interrupt handler */
  272.  
  273. void static intprinterhandler () {
  274.  
  275. int devtyp = PRINTER;
  276.  
  277. int devnum = ((state_t *)0xa60)->s_tmp.tmp_int.in_dno;
  278.  
  279. inthandler(devtyp, devnum + PRINT0);
  280.  
  281. LDST((state_t *)0xa60);
  282.  
  283. }
  284.  
  285.  
  286.  
  287. /* disk interrupt handler */
  288.  
  289. void static intdiskhandler () {
  290.  
  291. int devtyp = DISK;
  292.  
  293. int devnum = ((state_t *)0xaf8)->s_tmp.tmp_int.in_dno;
  294.  
  295. inthandler(devtyp, devnum + DISK0);
  296.  
  297. LDST((state_t *)0xaf8);
  298.  
  299. }
  300.  
  301.  
  302.  
  303. /* floppy interrupt handler */
  304.  
  305. void static intfloppyhandler () {
  306.  
  307. int devtyp = FLOPPY;
  308.  
  309. int devnum = ((state_t *)0xb90)->s_tmp.tmp_int.in_dno;
  310.  
  311. inthandler(devtyp, devnum + FLOPPY0);
  312.  
  313. LDST((state_t *)0xb90);
  314.  
  315. }
  316.  
  317.  
  318.  
  319. /* clock interrupt handler */
  320.  
  321. void static intclockhandler () {
  322.  
  323. proc_t *head = headQueue(RQ);
  324.  
  325. long current_time = 0;
  326.  
  327. STCK(&current_time);
  328.  
  329. if (head != (proc_t *)NULL) {
  330.  
  331. /* restore the current status into the process */
  332.  
  333. head->p_s = *(state_t *)0xc28;
  334.  
  335. head->acc_time += current_time - head->start_time;
  336.  
  337. removeProc(&RQ);
  338.  
  339. insertProc(&RQ, head);
  340.  
  341. schedule();
  342.  
  343. }
  344.  
  345. /* V the pseudoclock if nessecery */
  346.  
  347. if (pseudoclock < 0) {
  348.  
  349. if(current_time - last_check_time >= DELAY) {
  350.  
  351. intsemop(&pseudoclock, UNLOCK);
  352.  
  353. last_check_time = current_time;
  354.  
  355. }
  356.  
  357. }
  358.  
  359. LDST((state_t *)0xc28);
  360.  
  361. }
  362.  
  363.  
  364.  
  365. /* initialize interrupt area */
  366.  
  367. void intinit () {
  368.  
  369. int i;
  370.  
  371. /* set the new area for terminal interrupt */
  372.  
  373. ((state_t *)(0x9c8 + sizeof(state_t)))->s_sp = mem_size;
  374.  
  375. ((state_t *)(0x9c8 + sizeof(state_t)))->s_pc = (int)intterminalhandler;
  376.  
  377. ((state_t *)(0x9c8 + sizeof(state_t)))->s_sr.ps_s = 1;
  378.  
  379. ((state_t *)(0x9c8 + sizeof(state_t)))->s_sr.ps_int = 7;
  380.  
  381. /* set the new area for printer interrupt */
  382.  
  383. ((state_t *)(0xa60 + sizeof(state_t)))->s_sp = mem_size;
  384.  
  385. ((state_t *)(0xa60 + sizeof(state_t)))->s_pc = (int)intprinterhandler;
  386.  
  387. ((state_t *)(0xa60 + sizeof(state_t)))->s_sr.ps_s = 1;
  388.  
  389. ((state_t *)(0xa60 + sizeof(state_t)))->s_sr.ps_int = 7;
  390.  
  391. /* set the new area for disk interrupt */
  392.  
  393. ((state_t *)(0xaf8 + sizeof(state_t)))->s_sp = mem_size;
  394.  
  395. ((state_t *)(0xaf8 + sizeof(state_t)))->s_pc = (int)intdiskhandler;
  396.  
  397. ((state_t *)(0xaf8 + sizeof(state_t)))->s_sr.ps_s = 1;
  398.  
  399. ((state_t *)(0xaf8 + sizeof(state_t)))->s_sr.ps_int = 7;
  400.  
  401. /* set the new area for floppy interrupt */
  402.  
  403. ((state_t *)(0xb90 + sizeof(state_t)))->s_sp = mem_size;
  404.  
  405. ((state_t *)(0xb90 + sizeof(state_t)))->s_pc = (int)intfloppyhandler;
  406.  
  407. ((state_t *)(0xb90 + sizeof(state_t)))->s_sr.ps_s = 1;
  408.  
  409. ((state_t *)(0xb90 + sizeof(state_t)))->s_sr.ps_int = 7;
  410.  
  411. /* set the new area for clock interrupt */
  412.  
  413. ((state_t *)(0xc28 + sizeof(state_t)))->s_sp = mem_size;
  414.  
  415. ((state_t *)(0xc28 + sizeof(state_t)))->s_pc = (int)intclockhandler;
  416.  
  417. ((state_t *)(0xc28 + sizeof(state_t)))->s_sr.ps_s = 1;
  418.  
  419. ((state_t *)(0xc28 + sizeof(state_t)))->s_sr.ps_int = 7;
  420.  
  421. /* initialize the interrupt table */
  422.  
  423. for (i = 0; i < NUM_DEV; i++) {
  424.  
  425. devsemtable[i].devsem = 0;
  426.  
  427. devsemtable[i].devreg_p = (devreg_t *)(0x1400 + 0x10 * i);
  428.  
  429. devsemtable[i].devinfo.io_len = 0;
  430.  
  431. devsemtable[i].devinfo.io_sta = NULL; /* normal status: 0-9 */
  432.  
  433. }
  434.  
  435. /* initilize the psudoclock */
  436.  
  437. pseudoclock = 0;
  438.  
  439. }
  440.  
  441.  
  442.  
  443. /* SYS7: wait on clock */
  444.  
  445. void waitforpclock (state_t *oldzone) {
  446.  
  447. /* restore the oldzone */
  448.  
  449. headQueue(RQ)->p_s = *oldzone;
  450.  
  451. /* p the pseudoclock */
  452.  
  453. intsemop(&pseudoclock, LOCK);
  454.  
  455. }
  456.  
  457.  
  458.  
  459. /* SYS8: wait on an interrupt */
  460.  
  461. void waitforio (state_t *oldzone) {
  462.  
  463. int d4 = oldzone->s_r[4]; /* for device number */
  464.  
  465. int *d2 = &(oldzone->s_r[2]); /* length reg */
  466.  
  467. int *d3 = &(oldzone->s_r[3]); /* status reg */
  468.  
  469. /* if an interrupt has already occured */
  470.  
  471. if (devsemtable[d4].devsem > 0) {
  472.  
  473. devsemtable[d4].devsem += LOCK;
  474.  
  475. *d2 = devsemtable[d4].devinfo.io_len;
  476.  
  477. *d3 = devsemtable[d4].devinfo.io_sta;
  478.  
  479. }
  480.  
  481. /* wait for interrupt */
  482.  
  483. else {
  484.  
  485. headQueue(RQ)->p_s = *oldzone;
  486.  
  487. intsemop(&(devsemtable[d4].devsem), LOCK);
  488.  
  489. }
  490.  
  491. }
Add Comment
Please, Sign In to add comment