//turns process into zombie. if it has children, all its children go to p1 int kexit(int exitValue) { int i; PROC *p; for (i = 0; i < NFD; i++) { if(running->fd[i] != 0) close_pipe(i); } //send children (dead or alive) to P1's orphanage for (i = 1; i < NPROC; i++) { p = &proc[i]; if(p->status != FREE && p->ppid == running->pid) { p->ppid = 1; p->parent = &proc[1]; } } //restore name string strcpy(running->name, pname[running->pid]); //record exitValue and become a ZOMBIE running->exitCode = exitValue; running->status = ZOMBIE; //wakeup parent and P1 kwakeup(running->parent); kwakeup(&proc[1]); tswitch(); }
//stops process to wait for an event int ksleep(int event) { running->status = SLEEP; // change status to SLEEP running->event = event; // record event in PROC.event enqueue(&sleepList, running);//enter sleepList tswitch(); // give up CPU, switch process }
/****************** syscall handler in C ***************************/ int kcinth(){ u16 segment, offset; int a,b,c,d, r; segment = running->uss; offset = running->usp; /** get syscall parameters from ustack **/ a = get_word(segment, offset + 2*PA); b = get_word(segment, offset + 2*PB); c = get_word(segment, offset + 2*PC); d = get_word(segment, offset + 2*PD); //printf("proc%d syscall a=%d b=%d c=%d d=%d\n", running->pid, a,b,c,d); switch(a){ case 0 : r = running->pid; break; case 1 : r = do_ps(); break; case 2 : r = chname(b); break; case 3 : r = kmode(); break; case 4 : r = tswitch(); break; case 5 : r = do_wait(b); break; case 6 : r = do_exit(b); break; case 90: r = getc(); break; case 91: r = putc(b); break; case 99: do_exit(b); break; default: printf("invalid syscall # : %d\n", a); } put_word(r, segment, offset + 2*AX); }
int body(void) { char c, str[64]; printf("proc %d resumes to body()\n\r", running->pid); showLists(); while(1) { printf("\rproc %d running : enter a key [s|f|z|a|w|q|u|p|l]: ", running->pid); c = getc(); printf("%c\n\r", c); switch(c) { case 's': tswitch(); break; case 'q': do_exit(); break; case 'f': kfork("/bin/u1"); break; case 'z': do_sleep(); break; case 'a': do_wake(); break; case 'w': do_wait(); break; case 'u': goUmode(); break; case 'p': do_ps(); break; case 'l': showLists();break; default: break; } } }
//changes running process status to ZOMBIE, then calls tswitch() to give up CPU int my_exit() { printf("process [%d] is now a zombie\n", running->pid); running->status = ZOMBIE; tswitch(); return 0; }
//main function, execution starts here main() { int i = 0; vid_init();//initialize video printf("MTX starts in main()\n"); init(); // initialize and create P0 as running set_vector(80, int80h); kfork("/bin/u1"); // P0 kfork() P1 set_vector(9, kbinth); kbd_init(); //timer init lock(); set_vector(8,tinth); timer_init(); while(1) { unlock(); if(readyQueue) tswitch(); else halt(); } }
main() { /* initialize(); PROC p[5]; int i=0; for(i=0;i<5;i++){ p[i].priority = i; p[i].pid = 5-i; enqueue(&p[i], &readyQueue); } */ printf("\nWelcome to the 460 Multitasking System\n"); initialize(); printf("P0 forks P1\n"); kfork(); // fork P1 printf("P0 switches to P1... calling tswitch()\n"); tswitch(); // switches running to P1 // Switch, Quit & Fork processes until all of them are dead except P0 printf("Almost done... running is P%d\n", running->pid); printf("P0 resumes: all dead, happy ending\n"); // printf("Lets go to the %s to get %d %s for %d %ss\n", "store", 5, "steaks", 8, "dinner"); }
int kexit(int exitValue){ int i, wakeupP1 = 0; PROC *p; if (running->pid == 1 && nproc > 2 ){ //nproc = number of active PROCS printf("other procs still exist, P1 can't die yet\n"); return -1; } /* send children (dead or alive) to P1's orphanage */ for (i = 1; i < NPROC; i++){ p = &proc[i]; if(p->status != FREE && p->ppid == running->pid){ p->ppid = 1; p->parent = &proc[1]; wakeupP1++; } } /*record exitValue and become a ZOMBIE */ running->exitCode = exitValue; running->status = ZOMBIE; /*wakeup parent and also P1 if necessary */ kwakeup(running->parent); //parent sleeps on its PROC address if(wakeupP1){ kwakeup(&proc[1]); } tswitch(); //give up CPU return 0; }
int body() { char c; int event; while(1){ printf("\n***************************************\n"); print(); printf("\nI am task %d My parent=%d\n", running->pid, running->ppid); printf("input a char [fork:f|switch:s|exit:q|sleep:z|wakeup:a|wait:w] : "); c = getchar(); switch(c){ case 'f': kfork(); break; case 's': tswitch(); break; case 'q': kexit(0); break; case 'z': {printf("enter event to put process to sleep"); scanf("%d",&event); ksleep(event);} break; case 'a': {printf("enter event to wake up process"); scanf("%d",&event); kwakeup(event);} break; case 'w': kwait(0); break; default: printf("invalid char\n"); break; } } return; }
int kexit(int exitValue) { int i, wakeupP1 = 0; PROC *p; if(running->pid==1 && nproc > 2) { printf("other procs still exist, P1 can't die yet\n"); return -1; } //give children to p1 for(i = 1; i < NPROC; i++) { p = &proc[i]; if(p->status != FREE && p->ppid == running->pid) { p->ppid = 1; p->parent = &proc[1]; wakeupP1++; } } //record exitValue and become a Zome running->status = ZOMBIE; running->exitCode = exitValue; kwakeup(running->parent); //wake up parent if sleep to tell them you died //parrent sleep //wakeup parent if(wakeupP1) { kwakeup(&proc[1]); } tswitch(); }
/************** syscall routing table ***********/ int kcinth() { u16 x, y, z, w, r; u16 seg, off; seg = running->uss; off = running->usp; x = get_word(seg, off+13*2); y = get_word(seg, off+14*2); z = get_word(seg, off+15*2); w = get_word(seg, off+16*2); switch(x){ case 0 : r = running->pid; break; case 1 : r = kps(); break; case 2 : r = chname(y); break; case 3 : r = kmode(); break; case 4 : r = tswitch(); break; case 5 : r = kwait(); break; case 6 : r = kexit(); break; case 7 : r = fork(); break; case 8 : r = kexec(y); break; case 9 : r = sout(y); break; case 10: r = sin(y); break; case 99: r = kexit(); break; default: printf("invalid syscall # : %d\n", x); } put_word(r, seg, off+2*8); }
// figure out what the user wants to do! int body() { char c; while(1) { color = 0x01 + (running->pid % NPROC); // change the text color based on the process id! printf("\n******************************\n"); printf("Currently Running Process #%d", running->pid); printf("\nReady Queue: "); printQueue(readyQueue); printf("******************************\n"); printf("Input a command [s | q | f | r | ?]:"); c = getc(); printf("\n"); switch (c) { case 's': tswitch(); break; case 'q': zombify(); break; case 'f': kfork(); break; case 'r': resurrect(); break; case '?': help(); break; default: break; } } }
// turns the living into the undead zombify() { printf("\nProcess [%d] is now undead!", running->pid); running->status = ZOMBIE; tswitch(); }
int ksleep(int event) { running->event = event; running->status = SLEEP; tswitch(); }
int kexit(int event) { int i, hc = 0; running->exitCode = event; //run through each proc list to find any children for(i = 0; i < NPROC; i++) { if(proc[i].ppid == running->pid) //child found { hc = 1; if(running->pid == 1) {break;} proc[i].ppid = 1; //change parent to proc1 } } if(running->pid == 1 && hc) //Can't let proc1 die { printf("Proc 1 still has children! Cannot die\n"); return -1; } running->status = ZOMBIE; if(hc) {kwakeup(1);} kwakeup(running->ppid); tswitch(); }
//kills a process int grave(){ int i,parent; if (running->pid == 1) { for (i = 2;i<NPROC;i++) { if ((&proc[i])->status != FREE) return; } } if (running->pid != 1) { running->exitCode = 0; for (i = 2;i<NPROC;i++) { if ((&proc[i])->ppid == running->pid) (&proc[i])->ppid = 1; } } running->status = ZOMBIE; parent = running->ppid; wakeup((int)(&proc[parent])); printf("\n*****************************************\n"); printf("Task %d %s\n", running->pid,gasp[(running->pid) % 4]); printf("*****************************************\n"); tswitch(); /* journey of no return */ }
//makes a proc sleep until woken by the specified event int sleep(int event) { running->event = event; running->status = SLEEP; enqueue(&sleepList,running); printf("sleeping on event: %d",event); tswitch(); }
/******************************************************************** Copyright 2010-2015 K.C. Wang, <*****@*****.**> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ********************************************************************/ int ksleep(int event) { running->status = SLEEP; running->event = event; // enter sleepList FIFO enqueue(&sleepList, running); tswitch(); }
int ksleep(int event) { running->event = event; //Record event in PROC running->status = SLEEP; // mark itself SLEEP // For fairness, put running into a FIFO sleepList so that they will wakeup in order enqueue(&sleepList, running); tswitch(); // not in readyQueue anymore }
int ksleep(int event) { running->event = event; running->status = SLEEP; //printf("Set proc %d to status = %s in sleep function\n", running->pid, statusStr[running->status]); //FOR TESTING proc[running->pid].status = SLEEP; tswitch(); }
int ksleep(int event){ running->event = event; // record event in PROC.event running->status = SLEEP; // change status to SLEEP enqueue(&sleepList, running); nproc--; tswitch(); }
int grave(){ printf("\n*****************************************\n"); printf("Task %d %s\n", running->pid,gasp[(running->pid) % 4]); printf("*****************************************\n"); running->status = DEAD; enqueue(running, &freeList); tswitch(); /* journey of no return */ }
main() { printf("MTX starts in main()\n"); init(); kfork(); tswitch(); body(); while(1){ printf("proc 0 running : enter a key : \n"); getc(); if (readyQueue){ tswitch(); } else{ printf("proc 0 running: enter a key: \n"); } } }
int ksleep(int event){ printf("setting running (proccess %d)'s event to %d\n", running->pid, event); running->event = event; //record event in PROC.event running->status = SLEEP; // change status to sleeping enqueue(&sleepList, running); //put into sleep list tswitch(); //give up CPU }
main() { myprintf("MTX starts in main()\n"); init(); // initialize and create P0 as running kfork(); // P0 creates child P1 while(1){ // P0 switches if readyQueue not empty if (readyQueue) tswitch(); } }
int kexit(int exitvalue) { int i, count, foundChildren; PROC *temp; temp = readyQueue; foundChildren = 0; // Record value in its PROC.exitValue; running->exitCode = exitvalue; // Give away children (dead or alive) to P1. while(temp != 0) { if(temp->ppid == running->pid) { // Sets the temp's parent id to P1 foundChildren = 1; temp->ppid = 1; } temp = temp->next; } // Make sure P1 does not die if other procs still exist. temp = readyQueue; count = 0; if(running->pid == 1) { while(temp != 0) { count++; temp = temp->next; } if(count >= 1) { printf("Cannot kill P1!\n"); return 0; } } // Issue wakeup(parent) to wake up its parent; kwakeup(&proc[running->ppid]); // Wake up P1 also if it has sent any children to P1; if(foundChildren) { kwakeup(&(proc[1])); } // Mark itself a ZOMBIE; running->status = ZOMBIE; // Call tswitch(); to give up CPU; tswitch(); }
/******************************************************************** Copyright 2010-2015 K.C. Wang, <*****@*****.**> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ********************************************************************/ int ksleep(int event) { int sr = int_off(); running->status = SLEEP; running->event = event; // enter sleepList FIFO enqueue(&sleepList, running); int_on(sr); tswitch(); }
int P(SEMAPHORE *s) { //int sr = int_off(); int i; s->value--; if (s->value < 0){ running->status = BLOCK; enqueue(&(s->queue), running); tswitch(0); int_on(); } }
int write_pipe(int fd, char *buf, int n) { int i, bytes=0; PIPE *pipe; u8 info; printf("fd[%d] buf[%c] n[%d]\n", fd, get_byte(running->uss, buf), n); if(running->fd[fd] ==0){ printf("fd isn't open\n"); return -1; } if(running->fd[fd]->mode != WRITE_PIPE){ printf("fd not in write mode\n"); return -2; } pipe = running->fd[fd]->pipe_ptr; if(pipe->nreader == 0){ printf("NO READER\n"); return -3; } //show_pipe(pipe); if ( pipe->data == 0) { pipe->head = 0; } while( bytes < n ) { if ( pipe->room <= 0 ) { kwakeup(&(pipe->data)); ksleep(&(pipe->room)); } info = get_byte( running->uss, buf); //printf("writing %c to %d\n", info , pipe->head); pipe->buf[pipe->head] = info; pipe->head++; buf++; pipe->room--; pipe->data++; bytes++; pipe->head %= PSIZE; kwakeup(&(pipe->data)); } //show_pipe(pipe); tswitch(); return bytes; }
int ksleep(int event) { //printf("ksleep():\n\r"); running->event = event; // record event in PROC.event running->status = SLEEP; // change status to SLEEP //add proc to sleepList put_proc(&sleepList, running); //printf("after put_proc: pid %d status %d \n\r", running->pid, running->status); // give up CPU tswitch(); }