// *********************************************************************** // *********************************************************************** // list tasks command int P2_listTasks(int argc, char* argv[]) { int i; // ?? 1) List all tasks in all queues // ?? 2) Show the task stake (new, running, blocked, ready) // ?? 3) If blocked, indicate which semaphore my_printf("\n\tReady Queue:\n"); for(i=1; i <= rq[0]; i++){ int tasknum = rq[i]; printf("\n%4d/%-4d%20s%4d ", tasknum, tcb[tasknum].parent, tcb[tasknum].name, tcb[tasknum].priority); if (tcb[tasknum].signal & mySIGSTOP) my_printf("Paused"); else if (tcb[tasknum].state == S_NEW) my_printf("New"); else if (tcb[tasknum].state == S_READY) my_printf("Ready"); else if (tcb[tasknum].state == S_RUNNING) my_printf("Running"); else if (tcb[tasknum].state == S_BLOCKED) my_printf("Blocked %s", tcb[tasknum].event->name); else if (tcb[tasknum].state == S_EXIT) my_printf("Exiting"); swapTask(); } my_printf("\n"); //traverse all semaphores to list items blocked on them Semaphore* sem = semaphoreList; Semaphore** semLink = &semaphoreList; while (sem) { if(sem->q[0]>0) my_printf("\n\tQueue for semaphore %s:\n", sem->name); for(i = 1; i <= sem->q[0]; i++){ int tasknum = sem->q[i]; printf("\n%4d/%-4d%20s%4d ", tasknum, tcb[tasknum].parent, tcb[tasknum].name, tcb[tasknum].priority); if (tcb[tasknum].signal & mySIGSTOP) my_printf("Paused"); else if (tcb[tasknum].state == S_NEW) my_printf("New"); else if (tcb[tasknum].state == S_READY) my_printf("Ready"); else if (tcb[tasknum].state == S_RUNNING) my_printf("Running"); else if (tcb[tasknum].state == S_BLOCKED) my_printf("Blocked %s", tcb[tasknum].event->name); else if (tcb[tasknum].state == S_EXIT) my_printf("Exiting"); swapTask(); } if(sem->q[0]>0) my_printf("\n"); // move to next semaphore semLink = (Semaphore**)&sem->semLink; sem = (Semaphore*)sem->semLink; } return 0; } // end P2_listTasks
// ********************************************************************** // ********************************************************************** // signal semaphore // // if task blocked by semaphore, then clear semaphore and wakeup task // else signal semaphore // void semSignal(Semaphore* s) { int i; // assert there is a semaphore and it is a legal type assert("semSignal Error" && s && ((s->type == 0) || (s->type == 1))); // check semaphore type if (s->type == 0) { // binary semaphore // look through tasks for one suspended on this semaphore for (i=0; i<MAX_TASKS; i++) // look for suspended task { if (tcb[i].event == s) { s->state = 0; // clear semaphore tcb[i].event = 0; // clear event pointer tcb[i].state = S_READY; // unblock task if(DeQ(s->q,i) >= 0) { enQ(rq,i,tcb[i].priority); } if (!superMode) swapTask(); return; } } // nothing waiting on semaphore, go ahead and just signal s->state = 1; // nothing waiting, signal if (!superMode) swapTask(); return; } else { // counting semaphore if (++s->state > 0) { return; } else { int nextTask = DeQ(s->q,-1); enQ(rq, nextTask, tcb[nextTask].priority); tcb[nextTask].state = S_READY; tcb[nextTask].event = 0; return; } } } // end semSignal
// ********************************************************************** // ********************************************************************** // signal semaphore // // if task blocked by semaphore, then clear semaphore and wakeup task // else signal semaphore // Essentially, the semaphore is a stop light. This function could be called // "green light." // void semSignal(Semaphore* s) { int i; // assert there is a semaphore and it is a legal type //printf("\nSemaphore: %s %d %d", s->name, s->type, s->state); assert("semSignal Error" && s && ((s->type == BINARY) || (s->type == COUNTING))); // check semaphore type if (s->type == 0) { // binary semaphore // look through tasks for one suspended on this semaphore for (i=0; i<MAX_TASKS; i++) // look for suspended task // look through tasks for tasks with the indicated semaphore { if (tcb[i].event == s) { s->state = 0; // clear semaphore tcb[i].event = 0; // clear event pointer tcb[i].state = S_READY; // unblock task // ?? move task from blocked to ready queue enqueue(rq, dequeue(s->q, i), tcb[i].priority); if (!superMode) swapTask(); return; } } // nothing waiting on semaphore, go ahead and just signal s->state = 1; // nothing waiting, signal if (!superMode) swapTask(); return; } else { // counting semaphore if(++s->state>0) return; int tid = dequeue(s->q, -1); tcb[tid].state=S_READY; tcb[tid].event=0; enqueue(rq, tid, tcb[tid].priority); return; } } // end semSignal
// *********************************************************************** // *********************************************************************** // list tasks command int P2_listTasks(int argc, char* argv[]) { int i, j, p; // ?? 1) List all tasks in all queues // ?? 2) Show the task state (new, running, blocked, ready) // ?? 3) If blocked, indicate which semaphore for (j=0; j<5; j++) { if( j == 0 ) p = 99; if( j == 1 ) p = 20; if( j == 2 ) p = 10; if( j == 3 ) p = 5; if( j == 4 ) p = 1; for (i=0; i<MAX_TASKS; i++) { if (tcb[i].name && tcb[i].priority == p) { printf("\n%4d/%-4d%20s%4d ", i, tcb[i].parent, tcb[i].name, tcb[i].priority); if (tcb[i].signal & mySIGSTOP) my_printf("Paused"); else if (tcb[i].state == S_NEW) my_printf("New"); else if (tcb[i].state == S_READY) my_printf("Ready"); else if (tcb[i].state == S_RUNNING) my_printf("Running"); else if (tcb[i].state == S_BLOCKED) my_printf("Blocked %s", tcb[i].event->name); else if (tcb[i].state == S_EXIT) my_printf("Exiting"); swapTask(); } } } return 0; } // end P2_listTasks
int P2_tensec(int argc, char* argv[]){ while(1){ SEM_WAIT(tics10sec); printf("\nHello from %s (task %d)!\n", tcb[curTask].name, curTask); swapTask(); } return 0; }
// ********************************************************************** // ********************************************************************** // create task int createTask(char* name, // task name int (*task)(int, char**), // task address int priority, // task priority int argc, // task argument count char* argv[]) // task argument pointers { int tid; // find an open tcb entry slot for (tid = 0; tid < MAX_TASKS; tid++) { if (tcb[tid].name == 0) { char buf[8]; // create task semaphore if (taskSems[tid]) deleteSemaphore(&taskSems[tid]); sprintf(buf, "task%d", tid); taskSems[tid] = createSemaphore(buf, 0, 0); taskSems[tid]->taskNum = 0; // assign to shell // copy task name tcb[tid].name = (char*)malloc(strlen(name)+1); strcpy(tcb[tid].name, name); // set task address and other parameters tcb[tid].task = task; // task address tcb[tid].state = S_NEW; // NEW task state tcb[tid].priority = priority; // task priority tcb[tid].parent = curTask; // parent tcb[tid].argc = argc; // argument count // ?? malloc new argv parameters tcb[tid].argv = malloc(argc*sizeof(char *)); int i; for (i = 0; i < argc; i++) tcb[tid].argv[i] = argv[i]; // argument pointers tcb[tid].event = 0; // suspend semaphore tcb[tid].RPT = 0; // root page table (project 5) tcb[tid].cdir = CDIR; // inherit parent cDir (project 6) // define task signals createTaskSigHandlers(tid); // Each task must have its own stack and stack pointer. tcb[tid].stack = malloc(STACK_SIZE * sizeof(int)); // ?? may require inserting task into "ready" queue if (tid) swapTask(); // do context switch (if not cli) return tid; // return tcb index (curTask) } } // tcb full! return -1; } // end createTask
// *********************************************************************** // *********************************************************************** // I'm alive task int ImAliveTask(int argc, char* argv[]) { int i; // local task variable while (1) { printf("\n(%d) I'm Still Alive!", curTask); for (i=0; i<500000; i++) swapTask(); } return 0; // terminate task } // end ImAliveTask
// ********************************************************************** // ********************************************************************** // wait on semaphore // // if semaphore is signaled, return immediately // else block task // int semWait(Semaphore* s) { assert("semWait Error" && s); // assert semaphore assert("semWait Error" && ((s->type == 0) || (s->type == 1))); // assert legal type assert("semWait Error" && !superMode); // assert user mode // check semaphore type if (s->type == 0) { // binary semaphore // if state is zero, then block task if (s->state == 0) { tcb[curTask].event = s; // block task tcb[curTask].state = S_BLOCKED; enqueue(s->q, dequeue(rq, curTask), tcb[curTask].priority); swapTask(); // reschedule the tasks return 1; } // state is non-zero (semaphore already signaled) s->state = 0; // reset state, and don't block return 0; } else // counting semaphore { if(--s->state >= 0) return 0; //remove from ready queue, put on semaphore queue, set state to blocked int tid = dequeue(rq, curTask); tcb[tid].state = S_BLOCKED; tcb[tid].event = s; enqueue(s->q, tid, tcb[tid].priority); //put task on semaphore queue swapTask(); return 1; } } // end semWait
int semWait(Semaphore* s) { assert("semWait Error" && s); // assert semaphore assert("semWait Error" && ((s->type == 0) || (s->type == 1))); // assert legal type assert("semWait Error" && !superMode); // assert user mode // check semaphore type if (s->type == BINARY) { if (s->state == 0) { tcb[curTask].event = s; // block task tcb[curTask].state = S_BLOCKED; takeout(curTask, &READY_QUEUE); enqueue(curTask, &(s->bq)); swapTask(); // reschedule the tasks return 1; } s->state = 0; // reset state, and don't block return 0; } else if(s->type == COUNTING) { if(s->state <= 0) { s->state = s->state - 1; tcb[curTask].event = s; // block task tcb[curTask].state = S_BLOCKED; takeout(curTask, &READY_QUEUE); enqueue(curTask, &(s->bq)); swapTask(); // reschedule the tasks return 1; } else { s->state = s->state - 1; return 0; } } return 0; } // end semWait
// ********************************************************************** // ********************************************************************** // wait on semaphore // // if semaphore is signaled, return immediately // else block task // int semWait(Semaphore* s) { assert("semWait Error" && s); // assert semaphore assert("semWait Error" && ((s->type == 0) || (s->type == 1))); // assert legal type assert("semWait Error" && !superMode); // assert user mode // check semaphore type if (s->type == 0) { // binary semaphore // if state is zero, then block task if (s->state == 0) { tcb[curTask].event = s; // block task tcb[curTask].state = S_BLOCKED; DeQ(rq,curTask); enQ(s->q, curTask,tcb[curTask].priority); swapTask(); // reschedule the tasks return 1; } // state is non-zero (semaphore already signaled) s->state = 0; // reset state, and don't block return 0; } else { s->state--; if (s->state >= 0) return; tcb[curTask].event = s; // block task tcb[curTask].state = S_BLOCKED; DeQ(rq,curTask); enQ(s->q, curTask,tcb[curTask].priority); swapTask(); // reschedule the tasks return 1; } } // end semWait
// ********************************************************************** // ********************************************************************** // signal semaphore // // if task blocked by semaphore, then clear semaphore and wakeup task // else signal semaphore // void semSignal(Semaphore* s) { assert("semSignal Error" && s && ((s->type == 0) || (s->type == 1))); int taskId = dequeue(&s->bq); if (s->type == BINARY) { int i; for (i=0; i<MAX_TASKS; i++) // look for suspended task { if (tcb[i].event == s) { s->state = 0; // clear semaphore tcb[i].event = 0; // clear event pointer tcb[i].state = S_READY; // unblock task takeout(i, &(s->bq)); enqueue(i, &READY_QUEUE); if (!superMode) swapTask(); return; } } s->state = 1; // nothing waiting, signal if (!superMode) swapTask(); return; } else if(s->type == COUNTING) { s->state = s->state + 1; if(taskId != -1) { tcb[taskId].state = S_READY; tcb[taskId].event = 0; enqueue(taskId, &READY_QUEUE); } if (!superMode) swapTask(); return; } } // end semSignal
/** * ImAliveTask */ int ImAliveTask(int argc, char* argv[]) { int i; int curTask = gettid(); while (1) { printf("\n\t(Task %d) I'm Alive!\n", curTask); for (i = 0; i < 100000; i++) { swapTask(); } } return 0; }
// *********************************************************************** // *********************************************************************** // list tasks command int P2_listTasks(int argc, char* argv[]) { int i; // List all tasks in all queues printf("\nReady Queue "); print(rq); Semaphore* sem = semaphoreList; while(sem) { printf("\n%s Queue ", sem->name); print(sem->blockedTasks); sem = (Semaphore*)sem->semLink; } // Show the tcb, including state (new, running, blocked, ready) // If blocked, indicate which semaphore for (i=0; i<MAX_TASKS; i++) { if (tcb[i].name) { printf("\n%4d/%-4d%20s%4d ", i, tcb[i].parent, tcb[i].name, tcb[i].priority); if (tcb[i].signal & mySIGSTOP) my_printf("Paused"); else if (tcb[i].state == S_NEW) my_printf("New"); else if (tcb[i].state == S_READY) my_printf("Ready"); else if (tcb[i].state == S_RUNNING) my_printf("Running"); else if (tcb[i].state == S_BLOCKED) my_printf("Blocked %s", tcb[i].event->name); else if (tcb[i].state == S_EXIT) my_printf("Exiting"); swapTask(); } } return 0; } // end P2_listTasks
// *********************************************************************** // *********************************************************************** // lc3 simulator task // // argc = 2 // argv[0] = 0 - load from system // 1 - load from FAT // int lc3Task(int argc, char* argv[]) { int DR, oldpc, ir; // local variables int i; int LC3_REGS[8]; // General purpose registers int LC3_CC = 0x02; // NZP condition codes int LC3_PC = 0x3000; // program counter int ips = 0; // instructions per swapTask(); int curTask = gettid(); // Initialize LC3 Simulator // clear registers for (i=0; i<8; i++) LC3_REGS[i] = 0; // set condition codes to nZp LC3_CC = 0x02; // load program if ((LC3_PC = loadLC3Program(argv)) < 0) { return -1; } // Execute LC3 program while(1) { oldpc = LC3_PC; // save old pc for debug message ir = getMemoryData(LC3_PC); // load ir and increment pc LC3_PC = LC3_PC + 1; // increment program counter DR = GET_DR; // preload destination register # switch(GET_OPCODE) { case LC3_ADD: // ADD instruction if (!GET_IMMEDIATE_BIT) { if (LC3_DEBUG&0x01) printf(ADD_MSG, oldpc, DR, GET_SR1, GET_SR2); LC3_REGS[DR] = MASKTO16BITS(LC3_REGS[GET_SR1] + LC3_REGS[GET_SR2]); } else { if (LC3_DEBUG&0x01) printf(ADDI_MSG, oldpc, DR, GET_SR1, MASKTO16BITS(SEXT5(ir))); LC3_REGS[DR] = MASKTO16BITS(LC3_REGS[GET_SR1] + SEXT5(ir)); } SET_CC(LC3_REGS[DR]); break; case LC3_AND: // AND instruction if (!GET_IMMEDIATE_BIT) { if (LC3_DEBUG&0x01) printf(AND_MSG, oldpc, DR, GET_SR1, GET_SR2); LC3_REGS[DR] = MASKTO16BITS(LC3_REGS[GET_SR1] & LC3_REGS[GET_SR2]); } else { if (LC3_DEBUG&0x01) printf(ANDI_MSG, oldpc, DR, GET_SR1, MASKTO16BITS(SEXT5(ir))); LC3_REGS[DR] = MASKTO16BITS(LC3_REGS[GET_SR1] & SEXT5(ir)); } SET_CC(LC3_REGS[DR]); break; case LC3_BR: // BR instruction if (ir == 0) { printf("\n**(%d) Illegal instruction 0x%04x at 0x%04x (frame %d)", LC3_TID, ir, LC3_PC, LC3_PC>>6); return -1; // abort! } if ((LC3_CC&0x04 && GET_N) || (LC3_CC&0x02 && GET_Z) || (LC3_CC&0x01 && GET_P)) LC3_PC = LC3_PC + SEXT9(ir); if (LC3_DEBUG&0x01) { char cchr[4]; cchr[0] = 0; if (GET_N) strcat(cchr, "N"); if (GET_Z) strcat(cchr, "Z"); if (GET_P) strcat(cchr, "P"); printf(BR_MSG, oldpc, cchr, LC3_PC); } break; case LC3_JMP: // JMP instruction if (LC3_DEBUG&0x01) { if (GET_BASER == 7) printf(RET_MSG, oldpc); else printf(JMP_MSG, oldpc, GET_BASER); } LC3_PC = LC3_REGS[GET_BASER]; break; case LC3_JSR: // JSR instruction LC3_REGS[7] = MASKTO16BITS(LC3_PC); if (GET_ADDR_BIT == 0) { if (LC3_DEBUG&0x01) printf(JSRR_MSG, oldpc, GET_BASER); LC3_PC = LC3_REGS[GET_BASER]; } else { if (LC3_DEBUG&0x01) printf(JSR_MSG, oldpc, LC3_PC + SEXT11(ir)); LC3_PC = LC3_PC + SEXT11(ir); } break; case LC3_LD: // LD instruction if (LC3_DEBUG&0x01) printf(LD_MSG, oldpc, DR, SEXT9(ir)); LC3_REGS[DR] = MASKTO16BITS(getMemoryData(LC3_PC + SEXT9(ir))); SET_CC(LC3_REGS[DR]); break; case LC3_LDI: // LDI instruction if (LC3_DEBUG&0x01) printf(LDI_MSG, oldpc, DR, SEXT9(ir)); LC3_REGS[DR] = MASKTO16BITS(getMemoryData(getMemoryData(LC3_PC + SEXT9(ir)))); SET_CC(LC3_REGS[DR]); break; case LC3_LDR: // LDR instruction if (LC3_DEBUG&0x01) printf(LDR_MSG, oldpc, DR, GET_BASER, SEXT6(ir)); LC3_REGS[DR] = MASKTO16BITS(getMemoryData(LC3_REGS[GET_BASER] + SEXT6(ir))); SET_CC(LC3_REGS[DR]); break; case LC3_LEA: // LEA instruction if (LC3_DEBUG&0x01) printf(LEA_MSG, oldpc, DR, LC3_PC + SEXT9(ir)); LC3_REGS[DR] = MASKTO16BITS(LC3_PC + SEXT9(ir)); SET_CC(LC3_REGS[DR]); break; case LC3_NOT: // NOT instruction if (LC3_DEBUG&0x01) printf(NOT_MSG, oldpc, DR, GET_SR1); LC3_REGS[DR] = MASKTO16BITS(~LC3_REGS[GET_SR1]); SET_CC(LC3_REGS[DR]); break; case LC3_ST: // ST instruction if (LC3_DEBUG&0x01) printf(ST_MSG, oldpc, GET_SR, LC3_PC + SEXT9(ir)); setMemoryData(LC3_PC + SEXT9(ir), LC3_REGS[GET_SR]); break; case LC3_STI: // STI instruction if (LC3_DEBUG&0x01) printf(STI_MSG, oldpc, GET_SR, SEXT9(ir)); setMemoryData(getMemoryData(LC3_PC + SEXT9(ir)), LC3_REGS[GET_SR]); break; case LC3_STR: // STR instruction if (LC3_DEBUG&0x01) printf(STR_MSG, oldpc, GET_SR, GET_BASER, SEXT6(ir)); setMemoryData(LC3_REGS[GET_BASER] + SEXT6(ir), LC3_REGS[GET_SR]); break; case LC3_TRAP: // TRAP instruction { int trapv = getMemoryData(GET_TRAPVECT8); // access trap vector getMemoryData(trapv); // access system routine switch(GET_TRAPVECT8) { // @DISABLE_SWAPS int tmp, string_address; // @ENABLE_SWAPS case LC3_GETID: { // Note: This function not supported by simulator. if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "GETTID"); //printf("\nLC3_TID = %d (%d)", LC3_TID, curTask); LC3_REGS[0] = LC3_TID; LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_GETC: { // Note: This does not function quite like GETC. if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "GETC"); LC3_REGS[0] = MASKTO8BITS(getCharacter()); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_OUT: { if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "OUT"); putchar(LC3_REGS[0]); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_PUTSP: { if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "PUTSP"); putchar(' '); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_PUTS: { if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "PUTS"); string_address = LC3_REGS[0]; while((tmp=getMemoryData(string_address++)) != 0) putchar(tmp); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_IN: { // Note: This does not function quite like IN. if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "IN"); putchar(':'); LC3_REGS[0] = MASKTO8BITS(getCharacter()); LC3_REGS[7] = MASKTO16BITS(LC3_PC); break; } case LC3_HALT: { LC3_REGS[7] = MASKTO16BITS(LC3_PC); if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "HALT"); printf("\nProcess #%d Halted at 0x%04x\n", LC3_TID, LC3_PC); charFlag = 0; // release input return 0; } case LC3_getNextDirEntry: { // Note: This function not supported by simulator. // IN: R0 = int *dirNum // R1 = char* mask // R2 = DirEntry* dirEntry // R3 = int cDir // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsGetNextDirEntry"); LC3_REGS[0] = fmsGetNextDirEntry((int*)getMemAdr(LC3_REGS[0], 1), // int *dirNum (char*)getMemAdr(LC3_REGS[1], 0), // char* mask (DirEntry*)getMemAdr(LC3_REGS[2], 1), // DirEntry* dirEntry (short int)LC3_REGS[3]); // int cDir swapTask(); break; } case LC3_closeFile: { // Note: This function not supported by simulator. // IN: R0 = int fileDescriptor // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsCloseFile"); LC3_REGS[0] = fmsCloseFile((short int)LC3_REGS[0]); // int fileDescriptor swapTask(); break; } case LC3_defineFile: { // Note: This function not supported by simulator. // IN: R0 = char* fileName // OUT: R0 = 0-success, otherwise error char fileName[32]; char* s = (char*)getMemAdr(LC3_REGS[0], 0); int j = i = 0; if(!s[j]) j++; while((fileName[i++] = s[j])) j+=2; if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsCreateFile"); LC3_REGS[0] = fmsDefineFile(fileName, 0); // char* fileName swapTask(); break; } case LC3_deleteFile: { // Note: This function not supported by simulator. // IN: R0 = char* fileName // OUT: R0 = 0-success, otherwise error char fileName[32]; char* s = (char*)getMemAdr(LC3_REGS[0], 0); int j = i = 0; if(!s[j]) j++; while((fileName[i++] = s[j])) j+=2; if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsDeleteFile"); LC3_REGS[0] = fmsDeleteFile(fileName); // char* fileName swapTask(); break; } case LC3_openFile: { // Note: This function not supported by simulator. // IN: R0 = char* fileName // R1 = int rwMode // OUT: R0 = 0-success, otherwise error char fileName[32]; char* s = (char*)getMemAdr(LC3_REGS[0], 0); int j = i = 0; if(!s[j]) j++; while((fileName[i++] = s[j])) j+=2; if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsOpenFile"); LC3_REGS[0] = fmsOpenFile(fileName, // char* fileName (short int)LC3_REGS[1]); // int rwMode swapTask(); break; } case LC3_readFile: { // Note: This function not supported by simulator. // IN: R0 = int fileDescriptor // R1 = char* buffer // R2 = int nBytes // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsReadFile"); LC3_REGS[0] = fmsReadFile((short int)LC3_REGS[0], // int fileDescriptor (char*)getMemAdr(LC3_REGS[1], 0), // char* buffer (short int)LC3_REGS[2]); // int nBytes swapTask(); break; } case LC3_seekFile: { // Note: This function not supported by simulator. // IN: R0 = int fileDescriptor // R1 = int index // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsSeekFile"); LC3_REGS[0] = fmsSeekFile((short int)LC3_REGS[0], // int fileDescriptor (short int)LC3_REGS[1]); // int index swapTask(); break; } case LC3_writeFile: { // Note: This function not supported by simulator. // IN: R0 = int fileDescriptor // R1 = char* buffer // R2 = int nBytes // OUT: R0 = 0-success, otherwise error if (LC3_DEBUG&0x01) printf(TRAP_MSG, oldpc, "fmsWriteFile"); LC3_REGS[0] = fmsWriteFile((short int)LC3_REGS[0], // int fileDescriptor (char*)getMemAdr(LC3_REGS[1], 0), // char* buffer (short int)LC3_REGS[2]); // int nBytes swapTask(); break; } default: printf(TRAP_ERROR_MSG, GET_TRAPVECT8); break; } break; } default: printf(UNDEFINED_OPCODE_MSG, GET_OPCODE); return -1; // abort! } if (LC3_DEBUG&0x02) // debug mode { char cchr[4]; // \n--PC:3000 IR:193b Nzp - 0000 0001 0002 0003 0004 0005 0006 0007 printf("\n--PC:%04x IR:%04x ",LC3_PC, ir); cchr[0] = (LC3_CC&0x04)?'N':'n'; cchr[1] = (LC3_CC&0x02)?'Z':'z'; cchr[2] = (LC3_CC&0x01)?'P':'p'; cchr[3] = 0; printf("%s -", &cchr[0]); for (i=0; i<8; i++) printf(" %04x", LC3_REGS[i]); //getchar(); // enable to single step } // swapTask(); tasks every INSTRUCTIONS_PER_swapTask(); instructions if (ips++ > INSTRUCTIONS_PER_SWAP) { ips = 0; swapTask(); } } // end while(1) execution loop
// ********************************************************************** // ********************************************************************** // create task int createTask(char* name, // task name int (*task)(int, char**), // task address int priority, // task priority int argc, // task argument count char* argv[]) // task argument pointers { int tid; // find an open tcb entry slot for (tid = 0; tid < MAX_TASKS; tid++) { if (tcb[tid].name == 0) { char buf[8]; // create task semaphore if (taskSems[tid]) deleteSemaphore(&taskSems[tid]); sprintf(buf, "task%d", tid); taskSems[tid] = createSemaphore(buf, 0, 0); taskSems[tid]->taskNum = 0; // assign to shell // copy task name tcb[tid].name = (char*)malloc(strlen(name)+1); strcpy(tcb[tid].name, name); // set task address and other parameters tcb[tid].taskTime = 0; // SCOTT - p5 tcb[tid].task = task; // task address tcb[tid].state = S_NEW; // NEW task state tcb[tid].priority = priority; // task priority tcb[tid].parent = curTask; // parent tcb[tid].argc = argc; // argument count // SCOTT malloc new argv parameters char** mallocdArgv = malloc(sizeof(char*) * MAX_ARGS); int i; for (i = 0; i < argc; i++) { mallocdArgv[i] = malloc(sizeof(char) * MAX_ARG_LENGTH); // max arg length = 50 strcpy(mallocdArgv[i], argv[i]); } tcb[tid].argv = mallocdArgv; // argument pointers // change this line // end malloc SCOTT tcb[tid].event = 0; // suspend semaphore // SCOTT - set RPT //tcb[tid].RPT = 0; // root page table (project 5) 4?? tcb[tid].RPT = LC3_RPT + ((tid) ? ((tid - 1) << 6) : 0); // from slide 35 tcb[tid].cdir = CDIR; // inherit parent cDir (project 6) // define task signals createTaskSigHandlers(tid); // Each task must have its own stack and stack pointer. tcb[tid].stack = malloc(STACK_SIZE * sizeof(int)); // ?? may require inserting task into "ready" queue enqueue(readyQueue, tid, tcb[tid].priority); // SCOTT if (tid) swapTask(); // do context switch (if not cli) return tid; // return tcb index (curTask) } } // tcb full! return -1; } // end createTask
// ********************************************************************** // ********************************************************************** // create task int createTask(char* name, // task name int (*task)(int, char**), // task address int priority, // task priority int argc, // task argument count char* argv[]) // task argument pointers { int tid; // find an open tcb entry slot for (tid = 0; tid < MAX_TASKS; tid++) { if (tcb[tid].name == 0) { int i = 0; char** newArgv = malloc(argc * sizeof(char*)); for(i = 0; i < argc; i++) { newArgv[i] = malloc(sizeof(char) * (strlen(argv[i]) + 1)); strcpy(newArgv[i], argv[i]); } char buf[8]; // create task semaphore if (taskSems[tid]) deleteSemaphore(&taskSems[tid]); sprintf(buf, "task%d", tid); taskSems[tid] = createSemaphore(buf, 0, 0); taskSems[tid]->taskNum = 0; // assign to shell // copy task name tcb[tid].name = (char*)malloc(strlen(name)+1); strcpy(tcb[tid].name, name); // set task address and other parameters tcb[tid].task = task; // task address tcb[tid].state = S_NEW; // NEW task state tcb[tid].priority = priority; // task priority tcb[tid].time = 0; // time tcb[tid].parent = curTask; // parent //printf("\nCurTask: %d, Name: %s", curTask, tcb[curTask].name); //printf("\nNewTask: %d, Name: %s", tid, tcb[tid].name); tcb[tid].argc = argc; // argument count // ?? malloc new argv parameters tcb[tid].argv = newArgv; // argument pointers tcb[tid].event = 0; // suspend semaphore tcb[tid].RPT = 0x2440;//(tid - 1) * 64 + 0x2400; // root page table (project 5) tcb[tid].cdir = CDIR; // inherit parent cDir (project 6) // signals tcb[tid].signal = 0; if (tid) { // inherit parent signal handlers tcb[tid].sigContHandler = tcb[curTask].sigContHandler; // task mySIGCONT handler tcb[tid].sigIntHandler = tcb[curTask].sigIntHandler; // mySIGINT handler tcb[tid].sigTermHandler = tcb[curTask].sigTermHandler; // task mySIGTERM handler tcb[tid].sigTstpHandler = tcb[curTask].sigTstpHandler; // task mySIGTSTP handler } else { // otherwise use defaults tcb[tid].sigContHandler = defaultSigContHandler; // task mySIGINT handler tcb[tid].sigIntHandler = defaultSigIntHandler; // task mySIGINT handler tcb[tid].sigTermHandler = defaultSigTermHandler; // task mySIGINT handler tcb[tid].sigTstpHandler = defaultSigTstpHandler; // task mySIGINT handler } // Each task must have its own stack and stack pointer. tcb[tid].stack = malloc(STACK_SIZE * sizeof(int)); // ?? may require inserting task into "ready" queue enqueue(tid, &READY_QUEUE); if (tid) swapTask(); // do context switch (if not cli) return tid; // return tcb index (curTask) } } // tcb full! return -1; } // end createTask