int P2_MboxCreate(int slots, int size){ if(permissionCheck()){ return -1; } P1_P(mBoxSemaphore); if(slots <= 0 || size < 0){ P1_V(mBoxSemaphore); return -2; } int i; for(i = 0; i < P2_MAX_MBOX;i++){ if(mailboxes[i].inUse == 0){ mailboxes[i].inUse = 1; mailboxes[i].maxSlots = slots; mailboxes[i].maximumMessageSize = size; mailboxes[i].mutex = P1_SemCreate(1); mailboxes[i].empties = P1_SemCreate(slots); mailboxes[i].fulls = P1_SemCreate(0); mailboxes[i].queue = NULL; mailboxes[i].activeSlots = 0; P1_V(mBoxSemaphore); return i; } } P1_V(mBoxSemaphore); return -1; }
int P2_Startup(void *arg){ USLOSS_Console(" \n---------Starting Test 9 ----------\n"); sem = P1_SemCreate(0); int childpid1, child_status1, exit_childpid1; int childpid2, child_status2, exit_childpid2; childpid1 = P1_Fork("child_p", child_p, NULL, USLOSS_MIN_STACK * 4, 2); USLOSS_Console("Child PID created %d \n", childpid1); childpid2 = P1_Fork("killer", killer, &childpid1, USLOSS_MIN_STACK * 4, 3); USLOSS_Console("Child PID created %d \n", childpid2); exit_childpid1 = P1_Join(&child_status1); exit_childpid2 = P1_Join(&child_status2); USLOSS_Console("end first %d (should be %d) status %d (should be 444)\nend second %d (should be %d) status %d (should be -4)\n", exit_childpid1,childpid1,child_status1,exit_childpid2,childpid2, child_status2); USLOSS_Console(" ---------Ending Test 9 ----------\n"); return 0; }
int TermDriver(void *arg){ int unit = (int) arg; termReaderMB[unit] = P2_MboxCreate(1,INT_SIZE); termLookAhead[unit] = P2_MboxCreate(10,MAX_LINE); termCharToWrite[unit] = P2_MboxCreate(1,INT_SIZE); termWriteSem[unit] = P1_SemCreate(1); termRunningSem[unit] = P1_SemCreate(0); P1_Fork("Term Reader", TermReader, (void *) unit,USLOSS_MIN_STACK, 2); P1_P(termRunningSem[unit]); /*Turn on Terminal interrupts*/ int ctrl = 0; int ctrl2 = 0; ctrl = USLOSS_TERM_CTRL_RECV_INT(ctrl); USLOSS_DeviceOutput(USLOSS_TERM_DEV,unit,(void *)ctrl); P1_V(running); int status = 0; int c = 0; int result; while(1){ result = P1_WaitDevice(USLOSS_TERM_DEV,unit,&status); if(result != 0 || done != 0){ break; } if(USLOSS_TERM_STAT_RECV(status) == USLOSS_DEV_BUSY){ P2_MboxSend(termReaderMB[unit],&status,&INT_SIZE); } if(USLOSS_TERM_STAT_XMIT(status) == USLOSS_DEV_READY){ if(P2_MboxCondReceive(termCharToWrite[unit],&c,&INT_SIZE) != -2){ ctrl2 = 0; ctrl2 = USLOSS_TERM_CTRL_XMIT_INT(ctrl2); ctrl2 = USLOSS_TERM_CTRL_RECV_INT(ctrl2); ctrl2 = USLOSS_TERM_CTRL_CHAR(ctrl2, c); ctrl2 = USLOSS_TERM_CTRL_XMIT_CHAR(ctrl2); USLOSS_DeviceOutput(USLOSS_TERM_DEV, unit, (void *)ctrl2); }else{ ctrl2 = 0; ctrl2 = USLOSS_TERM_CTRL_RECV_INT(ctrl2); USLOSS_DeviceOutput(USLOSS_TERM_DEV, unit, (void *)ctrl2); } } } status = 0; P2_MboxCondSend(termReaderMB[unit],&ctrl,&status); P1_Join(&status); return unit; }
int P2_Startup(void *arg){ USLOSS_Console(" \n---------Starting Test 7 ----------\n"); int childpid = P1_Fork("child", child, NULL, USLOSS_MIN_STACK * 4, 2); sem1 = P1_SemCreate(-1); P1_P(sem1); USLOSS_Console(" %d \n", 1); USLOSS_Console(" ---------Ending Test 7 ----------\n"); P1_Quit(0); }
int P2_Sleep(int seconds){ if(permissionCheck() || seconds < 0){ return -1; } P1_Semaphore s = P1_SemCreate(0); P1_P(clockListSemaphore); int i; for(i = 0; i < P1_MAXPROC;i++){ if(clockList[i].inUse == 0){ clockList[i].inUse = 1; clockList[i].sem = s; clockList[i].startTime = USLOSS_Clock(); clockList[i].waitingTime = seconds * US_IN_S; break; } } P1_V(clockListSemaphore); P1_P(s); P1_SemFree(s); return 0; }
void sysHandler(int type,void *arg) { if(arg == NULL){ USLOSS_Console("USLOSS_Sysargs is NULL!\n"); return; } USLOSS_Sysargs *sysArgs = (USLOSS_Sysargs *) arg; int retVal = 0; int retVal2 = 0; int sectSize = 0; int sectors = 0; int tracks = 0; interruptsOn(); switch (sysArgs->number) { case SYS_TERMREAD: retVal = P2_TermRead((int)sysArgs->arg3, (int)sysArgs->arg2, sysArgs->arg1); if(retVal >= 0){ sysArgs->arg4 = (void *)0; sysArgs->arg2 = (void *)retVal; }else{ sysArgs->arg4 = (void *)-1; } break; case SYS_TERMWRITE: retVal = P2_TermWrite((int)sysArgs->arg3,(int)sysArgs->arg2,(char *)sysArgs->arg1); if(retVal >= 0){ sysArgs->arg4 = (void *)0; sysArgs->arg2 = (void *)retVal; }else{ sysArgs->arg4 = (void *)-1; } break; case SYS_SPAWN: //Part 1 retVal = P2_Spawn(sysArgs->arg5, sysArgs->arg1, sysArgs->arg2, (int) sysArgs->arg3, (int) sysArgs->arg4); if (retVal == -3 || retVal == -2) { sysArgs->arg4 = (void *) -1; sysArgs->arg1 = (void *) -1; } else { sysArgs->arg1 = (void *) retVal; sysArgs->arg4 = (void *) 0; } break; case SYS_WAIT: //Part 1 retVal = P2_Wait(&retVal2); if(retVal == -1){ sysArgs->arg1 = (void *)-1; sysArgs->arg4 = (void *)-1; sysArgs->arg2 = (void *)-1; }else{ sysArgs->arg1 = (void *)retVal; sysArgs->arg2 = (void *)retVal2; sysArgs->arg4 = (void *)0; } break; case SYS_TERMINATE: //Part 1 P2_Terminate((int)sysArgs->arg1); break; case SYS_SLEEP: // Part 1 retVal = P2_Sleep((int)sysArgs->arg1); sysArgs->arg4 = (void *) retVal; break; case SYS_DISKREAD: retVal = P2_DiskRead((int)sysArgs->arg5,(int)sysArgs->arg3,(int) sysArgs->arg4,(int)sysArgs->arg2,(void *)sysArgs->arg1); if (retVal == -1) { sysArgs->arg1 = (void *)retVal; sysArgs->arg4 = (void *)-1; } else if (retVal == 0) { sysArgs->arg1 = (void *)0; sysArgs->arg4 = (void *)0; }else { sysArgs->arg1 = (void *)retVal; //output is the disk's status register sysArgs->arg4 = (void *)0; } break; case SYS_DISKWRITE: retVal = P2_DiskWrite((int)sysArgs->arg5,(int)sysArgs->arg3,(int) sysArgs->arg4,(int)sysArgs->arg2,(void *)sysArgs->arg1); if (retVal == -1) { sysArgs->arg1 = (void *)retVal; sysArgs->arg4 = (void *)-1; } else if (retVal == 0) { sysArgs->arg1 = (void *)0; sysArgs->arg4 = (void *)0; }else { sysArgs->arg1 = (void *)retVal; //output is the disk's status register sysArgs->arg4 = (void *)0; } break; case SYS_DISKSIZE: retVal = P2_DiskSize((int)sysArgs->arg1,§Size,§ors,&tracks); if (retVal == -1) { sysArgs->arg4 = (void *)-1; }else { sysArgs->arg4 = (void *)0; sysArgs->arg1 = (void *)sectSize; sysArgs->arg2 = (void *)sectors; sysArgs->arg3 = (void *)tracks; } break; case SYS_GETTIMEOFDAY: //Part 1 sysArgs->arg1 = (void *)USLOSS_Clock(); break; case SYS_CPUTIME: //Part 1 sysArgs->arg1 = (void *)P1_ReadTime(); break; case SYS_DUMPPROCESSES: //Part 1 P1_DumpProcesses(); break; case SYS_GETPID: //Part 1 sysArgs->arg1 = (void *) P1_GetPID(); break; case SYS_SEMCREATE: //Part 1 retVal = (int)sysArgs->arg1; if(retVal < 0){ sysArgs->arg4 = (void *)-1; }else{ sysArgs->arg4 = (void *)0; sysArgs->arg1 = (void *) semAdd(P1_SemCreate(retVal)); } break; case SYS_SEMP: // Part 1 if(validSem((int)sysArgs->arg1) == 0){ sysArgs->arg4 = (void *) -1; return; } retVal = P1_P(userSemList[(int)sysArgs->arg1].sem); if(retVal < 0){ sysArgs->arg4 = (void *) -1; } else{ sysArgs->arg4 = (void *) 0; } break; case SYS_SEMV: // Part 1 if(validSem((int)sysArgs->arg1) == 0){ sysArgs->arg4 = (void *) -1; return; } retVal = P1_V(userSemList[(int)sysArgs->arg1].sem); if(retVal < 0){ sysArgs->arg4 = (void *) -1; } else{ sysArgs->arg4 = (void *) 0; } break; case SYS_SEMFREE: // Part 1 if(validSem((int)sysArgs->arg1) == 0){ sysArgs->arg4 = (void *) -1; return; } retVal = semDelete((int)sysArgs->arg1); if(retVal < 0){ sysArgs->arg4 = (void *) -1; } else{ sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXCREATE: //Part 1 retVal = P2_MboxCreate((int)sysArgs->arg1,(int)sysArgs->arg2); if(retVal == -2){ sysArgs->arg1 = (void *) -1; sysArgs->arg4 = (void *) -1; }else{ sysArgs->arg1 = (void *) retVal; sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXRELEASE: // Part 1 retVal = P2_MboxRelease((int)sysArgs->arg1); if(retVal < 0){ sysArgs->arg4 = (void *) -1; }else{ sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXSEND: // Part 1 retVal = P2_MboxSend((int)sysArgs->arg1,sysArgs->arg2,(int *)&sysArgs->arg3); if(retVal < 0){ sysArgs->arg4 = (void *) -1; }else{ sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXRECEIVE: // Part 1 retVal = P2_MboxReceive((int)sysArgs->arg1,sysArgs->arg2,(int *)&sysArgs->arg3); if(retVal < 0){ sysArgs->arg4 = (void *) -1; }else{ sysArgs->arg4 = (void *) 0; sysArgs->arg2 = (void *) retVal; } break; case SYS_MBOXCONDSEND: // Part 1 retVal = P2_MboxCondSend((int)sysArgs->arg1,sysArgs->arg2,(int *)&sysArgs->arg3); if(retVal == -1){ sysArgs->arg4 = (void *) -1; }else if(retVal == -2){ sysArgs->arg4 = (void *) 1; } else{ sysArgs->arg4 = (void *) 0; } break; case SYS_MBOXCONDRECEIVE: // Part 1 retVal = P2_MboxCondReceive((int)sysArgs->arg1,sysArgs->arg2,(int *)&sysArgs->arg3); if(retVal == -1){ sysArgs->arg4 = (void *) -1; }else if(retVal == -2){ sysArgs->arg4 = (void *) 1; } else{ sysArgs->arg4 = (void *) 0; sysArgs->arg2 = (void *) retVal; } break; default: P1_Quit(1); } }
int P2_Startup(void *arg) { USLOSS_IntVec[USLOSS_SYSCALL_INT] = sysHandler; /*Init all mailboxes*/ int i; for(i = 0; i < P2_MAX_MBOX;i++){ mailboxes[i].id = i; mailboxes[i].inUse = 0; mailboxes[i].queue = NULL; mailboxes[i].activeSlots = 0; } for(i = 0; i < P1_MAXPROC;i++){ clockList[i].inUse = 0; } for(i = 0; i < P1_MAXSEM;i++){ userSemList[i].id = i; userSemList[i].inUse = 0; } mBoxSemaphore = P1_SemCreate(1); clockListSemaphore = P1_SemCreate(1); semGuard = P1_SemCreate(1); running = P1_SemCreate(0); int status; int pid; int clockPID; /* * Create clock device driver */ clockPID = P1_Fork("Clock driver", ClockDriver, (void *) running, USLOSS_MIN_STACK, 2); if (clockPID == -1) { USLOSS_Console("Can't create clock driver\n"); } /* * Wait for the clock driver to start. */ P1_P(running); for(i = 0; i < USLOSS_TERM_UNITS;i++){ termPids[i] = P1_Fork("Term driver", TermDriver, (void *) i,USLOSS_MIN_STACK, 2); if (termPids[i] == -1) { USLOSS_Console("Can't create term driver. Unit = %d\n",i); } P1_P(running); } int sector,track,disk; for (i = 0; i < USLOSS_DISK_UNITS;i++) { diskSem[i] = P1_SemCreate(1); P2_DiskSize(i,§or,&track,&disk); DISK_TRACKS[i] = disk; } pid = P2_Spawn("P3_Startup", P3_Startup, NULL, 4 * USLOSS_MIN_STACK, 3); pid = P2_Wait(&status); /* * Kill the device drivers */ P1_Kill(clockPID); /*Let everyone know we are done.*/ done = 1; /*Interrupt all terminals*/ int ctrl = 0; ctrl = USLOSS_TERM_CTRL_XMIT_INT(ctrl); ctrl = USLOSS_TERM_CTRL_RECV_INT(ctrl); for(i = 0 ; i < USLOSS_TERM_UNITS;i++){ P1_Kill(termPids[i]); USLOSS_DeviceOutput(USLOSS_TERM_DEV, i, (void *)ctrl); P2_Wait(&status); } /*Interrupt any disk requests*/ USLOSS_DeviceRequest seekRequest; seekRequest.opr = USLOSS_DISK_SEEK; seekRequest.reg1 = (void *)0; for(i = 0 ; i < USLOSS_DISK_UNITS;i++){ USLOSS_DeviceOutput(USLOSS_DISK_DEV,i,(void *)&seekRequest); P2_Wait(&status); } /*Finally wait for the clock driver to be done*/ P2_Wait(&status); return 0; }
/* ------------------------------------------------------------------------ Name - startup Purpose - Initializes semaphores, process lists and interrupt vector. Start up sentinel process and the P2_Startup process. Parameters - none, called by USLOSS Returns - nothing Side Effects - lots, starts the whole thing ----------------------------------------------------------------------- */ void startup() { Check_Your_Privilege(); // int_disable(); int i; /* initialize the process table here */ for(i = 0; i < P1_MAXPROC; i++){ PCB dummy; procTable[i]=dummy; //USLOSS_Context DummyCon; procTable[i].priority = -1; //procTable[i].context=DummyCon; } /* Initialize the Ready list, Blocked list, etc. here */ readyHead.prevPCB=NULL; readyHead.nextPCB=NULL; blockedHead.prevPCB=NULL; blockedHead.nextPCB=NULL; quitListHead.nextPCB=NULL; quitListHead.prevPCB=NULL; /* Initialize the interrupt vector here */ USLOSS_IntVec[USLOSS_CLOCK_INT] = &clockHandler; USLOSS_IntVec[USLOSS_ALARM_INT] = &tempAlarmHandler; USLOSS_IntVec[USLOSS_DISK_INT] = &tempDiskHandler; USLOSS_IntVec[USLOSS_TERM_INT] = &tempTermHandler; USLOSS_IntVec[USLOSS_MMU_INT] = &tempMMUHandler; USLOSS_IntVec[USLOSS_SYSCALL_INT] = &tempSyscallHandler; /* Initialize the semaphores here */ /*initialize the semaphore table*/ for(i=0; i< P1_MAXSEM; i++){ Semaphore *dummy = malloc(sizeof(Semaphore)); PCB listHead; dummy->queue=&listHead; semTable[i] = *dummy; semTable[i].value = -1; semTable[i].valid = 0; semTable[i].queue = malloc(sizeof(PCB)); } /*Fork Semaphore*/ P1_SemCreate(1); /* semaphores for the processes */ for(i=1; i < 50; i++){ P1_SemCreate(0); } /* semaphores for the 6 devices */ for(i=0; i < 6; i++){ P1_SemCreate(0); } /* startup a sentinel process */ /* HINT: you don't want any forked processes to run until startup is finished. * You'll need to do something in your dispatcher to prevent that from happening. * Otherwise your sentinel will start running right now and it will call P1_Halt. */ P1_Fork("sentinel", sentinel, NULL, USLOSS_MIN_STACK, 6); /* start the P2_Startup process */ P1_Fork("P2_Startup", P2_Startup, NULL, 4 * USLOSS_MIN_STACK, 1); // int_enable(); // USLOSS_Console("Startup finished\n"); dispatcher(); /* Should never get here (sentinel will call USLOSS_Halt) */ return; } /* End of startup */