//**************************************************************************** void MakeReadyToRun() { PCB* pcb = NULL; pcb = gProcessManager->GetReadyQueueProcess(0); if( pcb ) { // Process in ready queue shouln't be dead. This must be an error! if( pcb->state == PROCESS_STATE_DEAD ) { assert(0); } // Check if a dispatching cycle has ended. If yes, restart a new cycle. if( pcb->readyQueueKey > LEGAL_PRIORITY_MAX ) { gProcessManager->ResetReadyQueueKeys(); } // Prepare to dispatch this process. gProcessManager->PopFromReadyQueue(&pcb); gProcessManager->SetRunningProcess(pcb); // Adjust dynamic priority. pcb->readyQueueKey += pcb->priority; #ifdef PRINT_STATE gProcessManager->PrintState(); #endif // Dispatch. LeaveCriticalSection(0); Z502SwitchContext(SWITCH_CONTEXT_SAVE_MODE, &pcb->context); } }
void start_timer( int delaytime ) { int Status; PCB *head; Temp = delaytime; //MEM_READ( Z502TimerStatus, &Status); //READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_LOCK, SUSPEND_UNTIL_LOCKED,&LockResult); if(Running == NULL) { dispatcher(); Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &(Running->context) ); } MEM_READ(Z502ClockStatus, &Time); MEM_WRITE( Z502TimerStart, &Temp); Running->wakeuptime = Time+Temp; add_to_timerQ(); dispatcher(); //READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,&LockResult); if(Running == NULL) { CALL(Z502Idle()); } //Z502Idle(); }
//**************************************************************************** void OnProcessSleep() { // Dispatch a process that is ready. if( gProcessManager->GetReadyQueueProcessCount() > 0 ) { MakeReadyToRun(); } else { // No process is ready, swtich to scheduler process. LeaveCriticalSection(0); Z502SwitchContext(SWITCH_CONTEXT_SAVE_MODE, &gScheduler->schedulerPCB->context); } }
void os_create_process( char* process_name, void* scontext, long Prio ) { void *next_context; PCB *pcb = (PCB *)malloc(sizeof(PCB)); strcpy(pcb->Processname , process_name); pcb->status = 0; pcb->Priority = Prio; pcb->context = scontext; pcb->pid = Pid; //readyfront = pcb; //readyrear = pcb; pcb->next=NULL; pcb->status=CURRENT_RUNNING; Running = pcb; Pid++; Z502MakeContext( &next_context, pcb->context, USER_MODE ); Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &next_context ); }
void dispatcher() { PCB *head; while(readyfront==NULL&&readyrear==NULL) { CALL(Z502Idle()); } os_out_ready(readyfront); /*printf("\n"); printf("cunrrent running pid %d\n",Running->pid); printf("\n"); head = readyfront; printf("readyqueue:"); while(head!=NULL){ printf("%d(%d)\t",head->pid,head->Priority); head=head->next; } printf("\n"); printf("\n"); head = timerfront; printf("timerqueue:"); while(head!=NULL){ printf("%d(%d)\t",head->pid,head->Priority); head=head->next; } printf("\n"); printf("\n"); head=diskfront; printf("suspendqueue:"); while(head!=NULL){ printf("%d(%d)\t",head->pid,head->Priority); head=head->next; } printf("\n"); printf("\n");*/ if(Running!=NULL) { Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &(Running->context) ); } }
void osInit( int argc, char *argv[] ) { void *next_context; INT32 i; void *process_ptr; INT32 j; /* Demonstrates how calling arguments are passed thru to here */ printf( "Program called with %d arguments:", argc ); for ( i = 0; i < argc; i++ ) printf( " %s", argv[i] ); printf( "\n" ); printf( "Calling with argument 'sample' executes the sample program.\n" ); /* Setup so handlers will come to code in base.c */ TO_VECTOR[TO_VECTOR_INT_HANDLER_ADDR] = (void *)interrupt_handler; TO_VECTOR[TO_VECTOR_FAULT_HANDLER_ADDR] = (void *)fault_handler; TO_VECTOR[TO_VECTOR_TRAP_HANDLER_ADDR] = (void *)svc; /* Determine if the switch was set, and if so go to demo routine. */ if (( argc > 1 ) && ( strcmp( argv[1], "sample" ) == 0 ) ) { Z502MakeContext( &next_context, (void *)sample_code, KERNEL_MODE ); Z502SwitchContext( SWITCH_CONTEXT_KILL_MODE, &next_context ); } /* This routine should never return!! */ /* This should be done by a "os_make_process" routine, so that test0 runs on a process recognized by the operating system. */ else if(( argc > 1 ) && ( strcmp( argv[1], "test1a" ) == 0 ) ) { process_ptr = test1a; os_create_process("test1a", process_ptr, LEGAL,&j, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1b" ) == 0 ) ) { process_ptr = test1b; os_create_process("test1b", process_ptr, LEGAL ,&j, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1c" ) == 0 ) ) { process_ptr = test1c; os_create_process("test1c", process_ptr, LEGAL ,&i, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1d" ) == 0 ) ) { process_ptr = test1d; os_create_process("test1d", process_ptr, LEGAL ,&i, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1e" ) == 0 ) ) { process_ptr = test1e; os_create_process("test1e", process_ptr, LEGAL ,&i, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1f" ) == 0 ) ) { process_ptr = test1f; os_create_process("test1f", process_ptr, LEGAL ,&i, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1g" ) == 0 ) ) { process_ptr = test1g; os_create_process("test1g", process_ptr, LEGAL ,&i, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1h" ) == 0 ) ) { process_ptr = test1h; os_create_process("test1h", process_ptr, LEGAL ,&i, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1i" ) == 0 ) ) { process_ptr = test1i; os_create_process("test1i", process_ptr, LEGAL ,&i, &j,RUN); } else if(( argc > 1 ) && ( strcmp( argv[1], "test1j" ) == 0 ) ) { process_ptr = test1j; os_create_process("test1j", process_ptr, LEGAL ,&i, &j,RUN); } else { process_ptr = test1l; os_create_process("test1l", process_ptr, LEGAL ,&i, &j,RUN); } }
void switch_context_kill (S_PCB *PCB_PTR ) { CALL(Z502SwitchContext( SWITCH_CONTEXT_KILL_MODE, &PCB_PTR->context )); }
void switch_context (S_PCB *PCB_PTR ) { CALL(Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &PCB_PTR->context )); }
void osInit( int argc, char *argv[] ) { void *next_context; INT32 i; void *scontext = (void *)test1a; int Prio = 8; int j,frameindex = 0; PCB *pcb = (PCB *)malloc(sizeof(PCB)); char name[20] ="testbase"; char test[20]; Frame *frame; /*let's just initialize all the frames here*/ for(j=0; j<64; j++) { frame = (Frame *)malloc(sizeof(Frame)); frame->framenumber = frameindex; frame->framestatus = 0; frame->next = NULL; if(framefront == NULL) { framefront = frame; framerear = frame; } else { framerear->next = frame; framerear = frame; } frameindex++; } shadowinit(); frameinit(); /* Demonstrates how calling arguments are passed thru to here */ printf( "Program called with %d arguments:", argc ); for ( i = 0; i < argc; i++ ) printf( " %s", argv[i] ); printf( "\n" ); printf( "Calling with argument 'sample' executes the sample program.\n" ); /* Setup so handlers will come to code in base.c */ TO_VECTOR[TO_VECTOR_INT_HANDLER_ADDR] = (void *)interrupt_handler; TO_VECTOR[TO_VECTOR_FAULT_HANDLER_ADDR] = (void *)fault_handler; TO_VECTOR[TO_VECTOR_TRAP_HANDLER_ADDR] = (void *)svc; /* Determine if the switch was set, and if so go to demo routine. */ if (( argc > 1 ) && ( strcmp( argv[1], "sample" ) == 0 ) ) { Z502MakeContext( &next_context, (void *)sample_code, KERNEL_MODE ); Z502SwitchContext( SWITCH_CONTEXT_KILL_MODE, &next_context ); } /* This routine should never return!! */ //os_create_process("testbase", scontext, 10); /* This should be done by a "os_make_process" routine, so that test0 runs on a process recognized by the operating system. */ strcpy(pcb->Processname , name); pcb->status = 0; pcb->Priority = Prio; pcb->pid = Pid; //readyfront = pcb; //readyrear = pcb; pcb->next=NULL; //pcb->status=CURRENT_RUNNING; Running = pcb; Pid++; printf("please input the test you want to enter:\n"); scanf("%s",&test); if(strcmp(test,"test1a")==0) { Z502MakeContext( &next_context, (void *)test1a, USER_MODE ); } else if(strcmp(test,"test1b")==0) { Z502MakeContext( &next_context, (void *)test1b, USER_MODE ); } else if(strcmp(test,"test1c")==0) { Z502MakeContext( &next_context, (void *)test1c, USER_MODE ); } else if(strcmp(test,"test1d")==0) { Z502MakeContext( &next_context, (void *)test1d, USER_MODE ); } else if(strcmp(test,"test1e")==0) { Z502MakeContext( &next_context, (void *)test1e, USER_MODE ); } else if(strcmp(test,"test1f")==0) { Z502MakeContext( &next_context, (void *)test1f, USER_MODE ); } else if(strcmp(test,"test1g")==0) { Z502MakeContext( &next_context, (void *)test1g, USER_MODE ); } else if(strcmp(test,"test1h")==0) { Z502MakeContext( &next_context, (void *)test1h, USER_MODE ); } else if(strcmp(test,"test1i")==0) { Z502MakeContext( &next_context, (void *)test1i, USER_MODE ); } else if(strcmp(test,"test1j")==0) { Z502MakeContext( &next_context, (void *)test1j, USER_MODE ); } else if(strcmp(test,"test1k")==0) { Z502MakeContext( &next_context, (void *)test1k, USER_MODE ); } else if(strcmp(test,"test2a")==0) { Z502MakeContext( &next_context, (void *)test2a, USER_MODE ); } else if(strcmp(test,"test2b")==0) { Z502MakeContext( &next_context, (void *)test2b, USER_MODE ); } else if(strcmp(test,"test2c")==0) { Z502MakeContext( &next_context, (void *)test2c, USER_MODE ); } else if(strcmp(test,"test2d")==0) { Z502MakeContext( &next_context, (void *)test2d, USER_MODE ); } else if(strcmp(test,"test2e")==0) { Z502MakeContext( &next_context, (void *)test2e, USER_MODE ); } else if(strcmp(test,"test2f")==0) { Z502MakeContext( &next_context, (void *)test2f, USER_MODE ); } else if(strcmp(test,"test2g")==0) { Z502MakeContext( &next_context, (void *)test2g, USER_MODE ); } //Z502MakeContext( &next_context, (void *)test1e, USER_MODE ); pcb->context = next_context; Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &next_context ); } // End of osInit
void svc( SYSTEM_CALL_DATA *SystemCallData ) { short call_type; static short do_print = 10; short i; int Time; int ID; int k=0,m=0,n=0; int PR; int sid,tid,mlen; int actual_length; long tmp; INT32 diskstatus; long tmpid; void *next_context; char *tmpmsg; PCB *head; PCB *head1; PCB *pcb = (PCB *)malloc(sizeof(PCB)); call_type = (short)SystemCallData->SystemCallNumber; if ( do_print > 0 ) { printf( "SVC handler: %s\n", call_names[call_type]); for (i = 0; i < SystemCallData->NumberOfArguments - 1; i++ ) { //Value = (long)*SystemCallData->Argument[i]; printf( "Arg %d: Contents = (Decimal) %8ld, (Hex) %8lX\n", i, (unsigned long )SystemCallData->Argument[i], (unsigned long )SystemCallData->Argument[i]); } } switch(call_type) { case SYSNUM_GET_TIME_OF_DAY: MEM_READ(Z502ClockStatus, &Time); //Z502_REG1=Time; *SystemCallData->Argument[0]=Time; break; case SYSNUM_TERMINATE_PROCESS: tmpid = (long)SystemCallData->Argument[0]; if(tmpid>=0) { os_delete_process_ready(tmpid); Z502_REG9 = ERR_SUCCESS; } else if(tmpid == -1) { head =Running; Running = NULL; while(readyfront==NULL&&timerfront==NULL) { Z502Halt(); } //free(head); dispatcher(); Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &(Running->context) ); } else Z502Halt(); break; //the execution of sleep(); case SYSNUM_SLEEP: start_timer( (int)SystemCallData->Argument[0] ); break; case SYSNUM_GET_PROCESS_ID: *SystemCallData->Argument[1] = os_get_process_id((char *)SystemCallData->Argument[0]); break; case SYSNUM_CREATE_PROCESS: strcpy(pcb->Processname , (char *)SystemCallData->Argument[0]); pcb->Priority = (long)SystemCallData->Argument[2]; head = readyfront; head1 = readyfront; if(Pid < 20) { if(pcb->Priority >0) { if(readyfront == NULL&&readyrear == NULL) { readyfront = pcb; readyrear = pcb; //*SystemCallData->Argument[4] = ERR_SUCCESS; Z502_REG9 = ERR_SUCCESS; pcb->pid = Pid; pcb->next=NULL; Toppriority = pcb->Priority; *SystemCallData->Argument[3] = Pid; //pcb->context = (void *)SystemCallData->Argument[1]; Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE ); pcb->context = next_context; Pid++; } else if(readyfront!=NULL&&readyrear!=NULL) { if(checkPCBname(pcb) == 1) { if(pcb->Priority < Toppriority) { Z502_REG9 = ERR_SUCCESS; pcb->next = readyfront; readyfront = pcb; pcb->pid = Pid; pcb->next=NULL; Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE ); pcb->context = next_context; *SystemCallData->Argument[3] = Pid; Pid++; } else { while(head->next!=NULL) { if(pcb->Priority < head->Priority) break; else head = head->next; } if(head->next!=NULL) { while(head1->next!=head) { head1=head1->next; } Z502_REG9 = ERR_SUCCESS; head1->next = pcb; pcb->next=head; pcb->pid = Pid; Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE ); pcb->context = next_context; *SystemCallData->Argument[3] = Pid; Pid++; } else { if(pcb->Priority < head->Priority) { while(head1->next!=head) { head1=head1->next; } Z502_REG9 = ERR_SUCCESS; head1->next=pcb; pcb->next=head; pcb->pid = Pid; Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE ); pcb->context = next_context; *SystemCallData->Argument[3] = Pid; Pid++; } else { Z502_REG9 = ERR_SUCCESS; head->next = pcb; readyrear = pcb; pcb->next=NULL; pcb->pid = Pid; Z502MakeContext( &next_context, (void *)SystemCallData->Argument[1], USER_MODE ); pcb->context = next_context; *SystemCallData->Argument[3] = Pid; Pid++; } } } } else free(pcb); } } else free(pcb); } else { Z502_REG9++; free(pcb); } break; case SYSNUM_SUSPEND_PROCESS: ID = (int)SystemCallData->Argument[0]; head = suspendfront; while(head!=NULL) { if(head->pid == ID) { n = 1; break; } else head = head->next; } if(n!=1) { head = readyfront; while(head!=NULL) { if(head->pid == ID) { Z502_REG9 = ERR_SUCCESS; suspend_process_ready(head); k = 1; break; } else head = head->next; } if(k == 0) { head = timerfront; while(head!=NULL) { if(head->pid == ID) { Z502_REG9 = ERR_SUCCESS; suspend_process_timer(head); m = 1; break; } else head=head->next; } if(m == 0&&k == 0) { printf("illegal PID\n"); } } } if(n == 1) { printf("can not suspend suspended process\n"); } break; case SYSNUM_RESUME_PROCESS: ID = (int)SystemCallData->Argument[0]; head = suspendfront; while(head!=NULL) { if(head->pid == ID) { k=1; break; } else head=head->next; } if(k==1) resume_process(head); else printf("error\n"); break; case SYSNUM_CHANGE_PRIORITY: ID = (int)SystemCallData->Argument[0]; PR = (int)SystemCallData->Argument[1]; if(ID == -1) { Running->Priority = PR; Z502_REG9 = ERR_SUCCESS; } else { if(PR < 100) { if(checkReady(ID) == 1) { head = readyfront; while(head->pid != ID) head=head->next; change_priority_ready(head,PR); Z502_REG9 = ERR_SUCCESS; } else if(checkTimer(ID) == 1) { head = timerfront; while(head->pid != ID) head=head->next; change_priority_timer(head,PR); Z502_REG9 = ERR_SUCCESS; } else if(checkSuspend(ID) == 1) { head = suspendfront; while(head->pid != ID) head = head->next; change_priority_suspend(head,PR); Z502_REG9 = ERR_SUCCESS; } else { printf("ID ERROR!\n"); } } else { printf("illegal Priority"); } } break; case SYSNUM_SEND_MESSAGE: sid = Running->pid; tid = (int)SystemCallData->Argument[0]; tmpmsg =(char *)SystemCallData->Argument[1]; mlen = (int)SystemCallData->Argument[2]; if(maxbuffer < 8) { if(tid < 100) { if(mlen < 100) { if(tid>0) { send_message(sid,tid,mlen,tmpmsg); maxbuffer++; } else if(tid == -1) { send_message_to_all(sid,mlen,tmpmsg); maxbuffer++; } } else { printf("illegal length!\n"); } } else printf("illegal id!\n"); } else { printf("no space!\n"); Z502_REG9++; } break; case SYSNUM_RECEIVE_MESSAGE: sid = (int)SystemCallData->Argument[0]; mlen = (int)SystemCallData->Argument[2]; if(sid < 100) { if(mlen < 100) { if(sid == -1) { receive_message_fromall(); if(msgnum>0) { actual_length = strlen(checkmsg->msg_buffer); if(mlen >actual_length) { msg_out_queue(checkmsg); *SystemCallData->Argument[3] = actual_length; *SystemCallData->Argument[4] = checkmsg->source_pid; strcpy((char *)SystemCallData->Argument[1] ,checkmsg->msg_buffer); Z502_REG9 = ERR_SUCCESS; } else { printf("small buffer!\n"); } } } else { receive_message_fromone(sid); if(msgnum>0) { actual_length = strlen(checkmsg->msg_buffer); if(mlen >actual_length) { msg_out_queue(checkmsg); *SystemCallData->Argument[3] = actual_length; *SystemCallData->Argument[4] = checkmsg->source_pid; strcpy((char *)SystemCallData->Argument[1], checkmsg->msg_buffer); Z502_REG9 = ERR_SUCCESS; } else { printf("small buffer!\n"); } } } } else printf("illegal length!\n"); } else printf("illegal id!\n"); break; case SYSNUM_DISK_READ: disk_read(SystemCallData->Argument[0],SystemCallData->Argument[1],SystemCallData->Argument[2]); break; case SYSNUM_DISK_WRITE: disk_write(SystemCallData->Argument[0],SystemCallData->Argument[1],SystemCallData->Argument[2]); break; default: printf("call_type %d cannot be recognized\n",call_type); break; } do_print--; }
void osInit( int argc, char *argv[] ) { void *next_context; INT32 i; if( argc == 1 ) { printf("Please enter a test you want to run (such as test1c).\n"); return; } /* Demonstrates how calling arguments are passed thru to here */ printf( "Program called with %d arguments:", argc ); for ( i = 0; i < argc; i++ ) printf( " %s", argv[i] ); printf( "\n" ); printf( "Calling with argument 'sample' executes the sample program.\n" ); /* Setup so handlers will come to code in base.c */ TO_VECTOR[TO_VECTOR_INT_HANDLER_ADDR] = (void *)interrupt_handler; TO_VECTOR[TO_VECTOR_FAULT_HANDLER_ADDR] = (void *)fault_handler; TO_VECTOR[TO_VECTOR_TRAP_HANDLER_ADDR] = (void *)svc; /* Determine if the switch was set, and if so go to demo routine. */ if (( argc > 1 ) && ( strcmp( argv[1], "sample" ) == 0 ) ) { Z502MakeContext( &next_context, (void *)sample_code, KERNEL_MODE ); Z502SwitchContext( SWITCH_CONTEXT_KILL_MODE, &next_context ); } /* This routine should never return!! */ // Figure out which test we need to run. int entry = 0; char* entryName = ""; if( argc > 1 ) { if( argv[1][0] == 't' && argv[1][1] == 'e' && argv[1][2] == 's' && argv[1][3] == 't' ) { if( argv[1][4] == '1' || argv[1][4] == '2' ) { entry = argv[1][5] - 'a'; entryName = &argv[1][0]; if( entry > 11 ) { entry = 11; } if( argv[1][4] == '2' ) { entry += 12; } } } } // Initialize global managers. ProcessManagerInitialize(); SchedulerInitialize(); MemoryManagerInitialize(); DiskManagerInitialize(); // Create main user process. PCB* pcb = gProcessManager->CreateProcess(entryName, 1, tests[entry], 20, 0, 0); gScheduler->Dispatch(); } // End of osInit