Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "../../h/const.h"
- #include "../../h/types.h"
- #include "../../h/vpop.h"
- #include "../../h/util.h"
- #include "../../h/procq.e"
- #include "../../h/asl.e"
- #define NUM_DEV 15 /* number of devices */
- #define QUANTUM 5000 /* 5ms */
- #define DELAY 100000 /* 100ms */
- #define MAXLEN 64 /* maximal size of a string */
- extern int mem_size;
- extern proc_link RQ;
- /* global variables */
- HIDDEN devsemtable_t devsemtable[NUM_DEV]; /* device sem table */
- HIDDEN int pseudoclock;
- long last_check_time = 0;
- void static sleep () {
- asm("stop #0x2000");
- }
- void intschedule () {
- long timeslice = QUANTUM;
- LDIT(×lice);
- }
- int check_devsem() {
- int i;
- for(i=0;i<NUM_DEV;i++) {
- if(devsemtable[i].devsem <0)
- return TRUE;
- }
- return FALSE;
- }
- void print_foo(char* buf) {
- devreg_t *printer0 = (devreg_t *)0x1450;
- printer0->d_amnt = MAXLEN; /* buffer size */
- printer0->d_badd = buf; /* address of buf */
- printer0->d_op = IOWRITE;
- printer0->d_stat = -1; /* normal state 0-9 */
- /* wait for the printer to finish printing */
- while (printer0->d_stat == -1);
- /* shut it down */
- HALT();
- }
- /* handle the case of empty RQ */
- void intdeadlock () {
- /* any process blocked on pseudoclock? */
- if (pseudoclock < 0) {
- intschedule();
- sleep();
- }
- /* any process blocked on I/O? */
- else if (check_devsem())
- sleep();
- /* system shut down normally */
- else if (headASL() == FALSE) {
- /* print out the termination information */
- char buf[MAXLEN] = "normal termination.";
- print_foo(buf);
- }
- /* deadlock */
- else {
- char buf[MAXLEN] = "deadlock.";
- print_foo(buf);
- }
- }
- int on_sem(proc_t * p) {
- int i=0;
- for(;i<SEMMAX;i++) {
- if(p->semvec[i] != (int*)NULL ) {
- return TRUE;
- }
- }
- return FALSE;
- }
- /* P/V for interrupts */
- void intsemop (int *semaddr, int semop) {
- long currenttime;
- *semaddr += semop;
- if ( semop == LOCK && *semaddr < 0 ) {
- /*remove the head of RQ to the sem queue*/
- proc_t *p = removeProc(&RQ);
- STCK(¤ttime);
- p->acc_time += currenttime - p->start_time;
- insertBlocked(semaddr, p);
- /* schedule the new head */
- if (headQueue(RQ) != (proc_t *)NULL)
- schedule();
- else
- intdeadlock();
- }
- else if (semop == UNLOCK && *semaddr <= 0) {
- proc_t *p = removeBlocked(semaddr);
- /* if not on any sem */
- if (!on_sem(p)) {
- insertProc(&RQ, p);
- if(headQueue(RQ) == p)
- schedule();
- }
- }
- }
- /* interrupt handler */
- void static inthandler (int devtyp, int devnum) {
- /* no wait_for_io happened */
- if (devsemtable[devnum].devsem >= 0) {
- devsemtable[devnum].devsem += UNLOCK;
- devsemtable[devnum].devinfo.io_len = devsemtable[devnum].devreg_p->d_amnt;
- devsemtable[devnum].devinfo.io_sta = devsemtable[devnum].devreg_p->d_stat;
- }
- /* wait_for_io happened */
- else {
- proc_t *p = headBlocked(&(devsemtable[devnum].devsem));
- p->p_s.s_r[2] = devsemtable[devnum].devreg_p->d_amnt;
- p->p_s.s_r[3] = devsemtable[devnum].devreg_p->d_stat;
- intsemop(&(devsemtable[devnum].devsem), UNLOCK);
- }
- }
- /* terminal interrupt handler */
- void static intterminalhandler () {
- int devtyp = TERMINAL;
- int devnum = ((state_t *)0x9c8)->s_tmp.tmp_int.in_dno;
- inthandler(devtyp, devnum + TERM0);
- LDST((state_t *)0x9c8);
- }
- /* printer interrupt handler */
- void static intprinterhandler () {
- int devtyp = PRINTER;
- int devnum = ((state_t *)0xa60)->s_tmp.tmp_int.in_dno;
- inthandler(devtyp, devnum + PRINT0);
- LDST((state_t *)0xa60);
- }
- /* disk interrupt handler */
- void static intdiskhandler () {
- int devtyp = DISK;
- int devnum = ((state_t *)0xaf8)->s_tmp.tmp_int.in_dno;
- inthandler(devtyp, devnum + DISK0);
- LDST((state_t *)0xaf8);
- }
- /* floppy interrupt handler */
- void static intfloppyhandler () {
- int devtyp = FLOPPY;
- int devnum = ((state_t *)0xb90)->s_tmp.tmp_int.in_dno;
- inthandler(devtyp, devnum + FLOPPY0);
- LDST((state_t *)0xb90);
- }
- /* clock interrupt handler */
- void static intclockhandler () {
- proc_t *head = headQueue(RQ);
- long current_time = 0;
- STCK(¤t_time);
- if (head != (proc_t *)NULL) {
- /* restore the current status into the process */
- head->p_s = *(state_t *)0xc28;
- head->acc_time += current_time - head->start_time;
- removeProc(&RQ);
- insertProc(&RQ, head);
- schedule();
- }
- /* V the pseudoclock if nessecery */
- if (pseudoclock < 0) {
- if(current_time - last_check_time >= DELAY) {
- intsemop(&pseudoclock, UNLOCK);
- last_check_time = current_time;
- }
- }
- LDST((state_t *)0xc28);
- }
- /* initialize interrupt area */
- void intinit () {
- int i;
- /* set the new area for terminal interrupt */
- ((state_t *)(0x9c8 + sizeof(state_t)))->s_sp = mem_size;
- ((state_t *)(0x9c8 + sizeof(state_t)))->s_pc = (int)intterminalhandler;
- ((state_t *)(0x9c8 + sizeof(state_t)))->s_sr.ps_s = 1;
- ((state_t *)(0x9c8 + sizeof(state_t)))->s_sr.ps_int = 7;
- /* set the new area for printer interrupt */
- ((state_t *)(0xa60 + sizeof(state_t)))->s_sp = mem_size;
- ((state_t *)(0xa60 + sizeof(state_t)))->s_pc = (int)intprinterhandler;
- ((state_t *)(0xa60 + sizeof(state_t)))->s_sr.ps_s = 1;
- ((state_t *)(0xa60 + sizeof(state_t)))->s_sr.ps_int = 7;
- /* set the new area for disk interrupt */
- ((state_t *)(0xaf8 + sizeof(state_t)))->s_sp = mem_size;
- ((state_t *)(0xaf8 + sizeof(state_t)))->s_pc = (int)intdiskhandler;
- ((state_t *)(0xaf8 + sizeof(state_t)))->s_sr.ps_s = 1;
- ((state_t *)(0xaf8 + sizeof(state_t)))->s_sr.ps_int = 7;
- /* set the new area for floppy interrupt */
- ((state_t *)(0xb90 + sizeof(state_t)))->s_sp = mem_size;
- ((state_t *)(0xb90 + sizeof(state_t)))->s_pc = (int)intfloppyhandler;
- ((state_t *)(0xb90 + sizeof(state_t)))->s_sr.ps_s = 1;
- ((state_t *)(0xb90 + sizeof(state_t)))->s_sr.ps_int = 7;
- /* set the new area for clock interrupt */
- ((state_t *)(0xc28 + sizeof(state_t)))->s_sp = mem_size;
- ((state_t *)(0xc28 + sizeof(state_t)))->s_pc = (int)intclockhandler;
- ((state_t *)(0xc28 + sizeof(state_t)))->s_sr.ps_s = 1;
- ((state_t *)(0xc28 + sizeof(state_t)))->s_sr.ps_int = 7;
- /* initialize the interrupt table */
- for (i = 0; i < NUM_DEV; i++) {
- devsemtable[i].devsem = 0;
- devsemtable[i].devreg_p = (devreg_t *)(0x1400 + 0x10 * i);
- devsemtable[i].devinfo.io_len = 0;
- devsemtable[i].devinfo.io_sta = NULL; /* normal status: 0-9 */
- }
- /* initilize the psudoclock */
- pseudoclock = 0;
- }
- /* SYS7: wait on clock */
- void waitforpclock (state_t *oldzone) {
- /* restore the oldzone */
- headQueue(RQ)->p_s = *oldzone;
- /* p the pseudoclock */
- intsemop(&pseudoclock, LOCK);
- }
- /* SYS8: wait on an interrupt */
- void waitforio (state_t *oldzone) {
- int d4 = oldzone->s_r[4]; /* for device number */
- int *d2 = &(oldzone->s_r[2]); /* length reg */
- int *d3 = &(oldzone->s_r[3]); /* status reg */
- /* if an interrupt has already occured */
- if (devsemtable[d4].devsem > 0) {
- devsemtable[d4].devsem += LOCK;
- *d2 = devsemtable[d4].devinfo.io_len;
- *d3 = devsemtable[d4].devinfo.io_sta;
- }
- /* wait for interrupt */
- else {
- headQueue(RQ)->p_s = *oldzone;
- intsemop(&(devsemtable[d4].devsem), LOCK);
- }
- }
Add Comment
Please, Sign In to add comment