int P2_MboxRelease(int mbox){ if(permissionCheck()){ return -1; } P1_P(mBoxSemaphore); int i; for(i = 0; i < P2_MAX_MBOX;i++){ if(mailboxes[i].inUse && mailboxes[i].id == mbox){ if(P1_SemFree(mailboxes[i].mutex) != 0){ USLOSS_Console("Processes waiting on mailbox. Halting.\n"); USLOSS_Halt(1); } if(P1_SemFree(mailboxes[i].fulls) != 0){ USLOSS_Console("Processes waiting on mailbox. Halting.\n"); USLOSS_Halt(1); } if(P1_SemFree(mailboxes[i].empties) != 0){ USLOSS_Console("Processes waiting on mailbox. Halting.\n"); USLOSS_Halt(1); } while(mailboxes[i].queue != NULL){ message *m = queuePop(&(mailboxes[i].queue)); free(m->buf); free(m); } mailboxes[i].inUse = 0; P1_V(mBoxSemaphore); return 0; } } P1_V(mBoxSemaphore); return -1; }
static void terminalHandler(int dev, void *arg) { long unit = (long) arg; if (debugflag2 && DEBUG2) { USLOSS_Console("terminalHandler(): dev = %d\n", dev); USLOSS_Console("terminalHandler(): unit = %d\n", unit); } int termResult; // check for valid values if (dev != USLOSS_TERM_DEV || unit < 0 || unit > USLOSS_TERM_UNITS) { USLOSS_Console("termHandler(): Bad values\n"); USLOSS_Halt(1); } // make sure our box still exists if (termBoxes[unit].mboxID == -1) { USLOSS_Console("Term mailbox does not exist, unit\n"); USLOSS_Halt(1); // might need to reutn instead } int result = USLOSS_DeviceInput(USLOSS_TERM_DEV, unit, &termResult); // if (debugflag2 && DEBUG2) { // USLOSS_Console("terminalHandler(): sending now from dev %d to mbox %d value %s\n", dev, termBoxes[unit].mboxID, termResult); // } MboxCondSend(termBoxes[unit].mboxID, &termResult, sizeof(termResult)); if (result != USLOSS_DEV_OK) { USLOSS_Console("termHandler(): USLOSS_DeviceInput is not ok.\n"); USLOSS_Halt(1); } }
// // Read characters from the terminals and puts them in the buffers. // When a buffer is full verify its content against the inputs. // void term_handler(int type, void *arg) { int result; int status; char ch; int unit = (int) arg; int i; // Get the device status for the terminal. result = USLOSS_DeviceInput(USLOSS_TERM_DEV, unit, &status); if (result != USLOSS_DEV_OK) { USLOSS_Console("Something is wrong with terminal %d!!", unit); USLOSS_Halt(1); } // If the status is "USLOSS_DEV_BUSY" then a character has been received. if (USLOSS_TERM_STAT_RECV(status) == USLOSS_DEV_BUSY) { ch = USLOSS_TERM_STAT_CHAR(status); // Get the characte USLOSS_Console("%d: %c\n", unit, ch); i = counts[unit]++; buffers[unit][i] = ch; if (i == NUMCHARS-1) { assert(!strncmp(inputs[unit], buffers[unit], NUMCHARS)); done++; } } }
static void clockHandler2(int dev, void *arg) { long unit = (long) arg; int clockResult; // check if dispatcher should be called if (readCurStartTime() >= 80000) { timeSlice(); } // inc that a clock interrupt happened clockTicks++; USLOSS_DeviceInput(dev, unit, &clockResult); // every fith interrupt do a conditional send to its mailbox if (clockTicks % 5 == 0) { if (debugflag2 && DEBUG2) { USLOSS_Console("clockHandler2: sending message %s to mbox %d\n", clockResult, clockBox.mboxID); } int sendResult = MboxCondSend(clockBox.mboxID, &clockResult, sizeof(clockResult)); if (debugflag2 && DEBUG2) { USLOSS_Console("clockHandler2: send returned %d\n", sendResult); USLOSS_Halt(1); } } }
static void syscallHandler(int dev, void *args) { // get args systemArgs *sysPtr = (systemArgs *) args; // check if valid dev if (dev != USLOSS_SYSCALL_INT) { USLOSS_Console("syscallHandler(): Bad call\n"); USLOSS_Halt(1); } // check if valid range of args if (sysPtr->number < 0 || sysPtr->number >= MAXSYSCALLS) { USLOSS_Console("syscallHandler(): sys number %d is wrong. Halting...\n", sysPtr->number); USLOSS_Halt(1); } USLOSS_PsrSet( USLOSS_PsrGet() | USLOSS_PSR_CURRENT_INT); sys_vec[sysPtr->number](sysPtr); }
static void diskHandler(int dev, void *arg) { long unit = (long) arg; int diskResult; // check for valid values if (dev != USLOSS_DISK_DEV || unit < 0 || unit > USLOSS_DISK_UNITS) { USLOSS_Console("diskHandler(): Bad values\n"); USLOSS_Halt(1); } // make sure our box still exists if (diskBoxes[unit].mboxID == -1) { USLOSS_Console("Disk mailbox does not exist, unit = %d\n", unit); USLOSS_Halt(1); // might need to reutn instead } USLOSS_DeviceInput(USLOSS_DISK_DEV, unit, &diskResult); MboxCondSend(diskBoxes[unit].mboxID, &diskResult, sizeof(diskResult)); }
/* * Disables the interrupts. */ static void disableInterrupts() { /* turn the interrupts OFF iff we are in kernel mode */ if( (USLOSS_PSR_CURRENT_MODE & USLOSS_PsrGet()) == 0 ) { //not in kernel mode USLOSS_Console("Kernel Error: Not in kernel mode, may not "); USLOSS_Console("disable interrupts\n"); USLOSS_Halt(1); } else /* We ARE in kernel mode */ USLOSS_PsrSet( USLOSS_PsrGet() & ~USLOSS_PSR_CURRENT_INT ); } /* disableInterrupts */
/* ------------------------------------------------------------------------ Name - sentinel Purpose - The purpose of the sentinel routine is two-fold. One responsibility is to keep the system going when all other processes are blocked. The other is to detect and report simple deadlock states. Parameters - none Returns - nothing Side Effects - if system is in deadlock, print appropriate error and halt. ----------------------------------------------------------------------- */ int sentinel (void *notused) { /*No Interupts within Part 1 so commented out*/ // int deadlock=1; int i; // printList(&readyHead); while (numProcs > 1){ USLOSS_Console("in sentinel\n"); //Check for deadlock here for(i=1;i<P1_MAXPROC;i++){ if(procTable[i].state == 4&&procTable[i].waitingOnDevice==0){ USLOSS_Console("Error: Deadlock\n"); USLOSS_Halt(1); } } USLOSS_WaitInt(); } USLOSS_Halt(0); /* Never gets here. */ return 0; } /* End of sentinel */
/* * Enables the interrupts */ static void enableInterrupts(int dev, void *args) { /* turn the interrupts ON iff we are in kernel mode */ if ( (USLOSS_PSR_CURRENT_MODE & USLOSS_PsrGet()) == 0 ) { //not in kernel mode USLOSS_Console("Kernel Error: Not in kernel mode, may not "); USLOSS_Console("disable interrupts\n"); USLOSS_Halt(1); } else { /* We ARE in kernel mode */ USLOSS_PsrSet( USLOSS_PsrGet() | USLOSS_PSR_CURRENT_INT); } }
int P1_SemFree(P1_Semaphore sem){ Check_Your_Privilege(); //if sem is invalid return -1, sem is invalid if it is not created using SemCreate method Semaphore* semP=(Semaphore*)sem; if(semP->value < 0 || semP->valid==0){ USLOSS_Console("Semaphore is invalid\n"); USLOSS_Halt(1); return -1; } semP->value = -1; free(sem); return 0; }
void startup() { int status; int i, j, k; FILE *f; char name[50]; int n; // Compute the inputs and write them to the term*.in file. Each terminal reads unique content. k = 0; for(i = 0; i < USLOSS_TERM_UNITS; i++) { memset(buffers[i], '\0', NUMCHARS); counts[i] = 0; snprintf(name, sizeof(name), "term%d.in", i); f = fopen(name, "w"); assert(f != NULL); for (j = 0; j < NUMCHARS; j++) { inputs[i][j] = 'a' + k++; } n = fwrite(inputs[i], 1, NUMCHARS, f); assert(n == NUMCHARS); fclose(f); } for (i = 0; i < USLOSS_NUM_INTS; i++) { USLOSS_IntVec[i] = dummy_handler; } // Turn on receive interrupts. for(i = 0; i < USLOSS_TERM_UNITS; i++) { status = USLOSS_DeviceOutput(USLOSS_TERM_DEV, i, (void *) USLOSS_TERM_CTRL_RECV_INT(0)); } USLOSS_IntVec[USLOSS_TERM_INT] = term_handler; // Turn on interrupts. USLOSS_PsrSet(USLOSS_PsrGet() | USLOSS_PSR_CURRENT_INT); // Read from the terminals. while(done < USLOSS_TERM_UNITS ) { USLOSS_WaitInt(); } USLOSS_Halt(0); }
// // Read characters from terminal 0 and writes them to the USLOSS_Console. // void term_handler(int type, void *arg) { int result; int status; char ch; int unit = (int) arg; if (unit != 0) { return; } // Get the device status for terminal 0. result = USLOSS_DeviceInput(USLOSS_TERM_DEV, 0, &status); if (result != USLOSS_DEV_OK) { USLOSS_Console("Something is wrong with terminal 0!!"); USLOSS_Halt(1); } // If the status is "USLOSS_DEV_BUSY" then a character has been received. if (USLOSS_TERM_STAT_RECV(status) == USLOSS_DEV_BUSY) { ch = USLOSS_TERM_STAT_CHAR(status); // Get the character USLOSS_Console("%c", ch); } }
int P4_Startup(void *arg) { int i; int rc; int pid; int child; int numChildren = sizeof(names) / sizeof(char *); USLOSS_Console("P4_Startup starting.\n"); rc = Sys_VmInit(PAGES, PAGES, numChildren * PAGES, 1, (void **) &vmRegion); if (rc != 0) { USLOSS_Console("Sys_VmInit failed: %d\n", rc); USLOSS_Halt(1); } pageSize = USLOSS_MmuPageSize(); for (i = 0; i < numChildren; i++) { rc = Sys_Spawn(names[i], Child, (void *) names[i], USLOSS_MIN_STACK * 2, 2, &pid); assert(rc == 0); } for (i = 0; i < numChildren; i++) { rc = Sys_Wait(&pid, &child); assert(rc == 0); } for (i = 0; i < numChildren; i++) { rc = Sys_Spawn(names[i], Child, (void *) names[i], USLOSS_MIN_STACK * 2, 2, &pid); assert(rc == 0); } for (i = 0; i < numChildren; i++) { rc = Sys_Wait(&pid, &child); assert(rc == 0); } Sys_VmDestroy(); USLOSS_Console("P4_Startup done.\n"); return 0; }
void nullsys3(systemArgs *args) { USLOSS_Console("nullsys3(): Invalid syscall %d. Halting...\n", args->number); USLOSS_Halt(1); //Eventually this will need to terminate instead of halting }
static void nullsys(systemArgs *args) { USLOSS_Console("nullsys(): Invalid syscall %d. Halting...\n", args->number); USLOSS_Halt(1); }
/* * Checks if we are in Kernel mode */ void check_kernel_mode(char *name) { if ((USLOSS_PSR_CURRENT_MODE & USLOSS_PsrGet()) == 0) { USLOSS_Console("%s(): Called while in user mode by process %d. Halting...\n", name, getpid()); USLOSS_Halt(1); } }
/* an error method to handle invalid syscalls */ void nullsys(sysargs *args) { USLOSS_Console("nullsys(): Invalid syscall. Halting...\n"); USLOSS_Halt(1); } /* nullsys */