//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(); }
int write_pipe(int fd, char *buf, int n) { // your code for write_pipe() int bytesWritten = 0; PIPE *p = running->fd[fd]->pipe_ptr; printf("Going to write %d bytes to pipe with fd=%d\n", n, fd); //FOR TESTING while(1) { //1. If no readers return error if(p->nreader < 1) { printf("Error: No readers\n"); return BROKEN_PIPE_ERROR; } //2. If pipe has room write nbytes or until until data = PSIZE if(p->room != 0) //There is room { printf("There's room, let's write!\n"); //FOR TESTING write_bytes(p, buf, &bytesWritten, n); printf("We wrote %d bytes\n", bytesWritten); kwakeup(&p->data); if(bytesWritten == n) { return bytesWritten; } } if(p->room == 0) { //wakeup readers & wait kwakeup(&p->data); printf("No room, now we sleep\n"); ksleep(&p->room); } } return -1; }
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 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(); }
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(); }
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(); }
int write_pipe(int fd, char *buf, int n) { // your code for write_pipe() PIPE *pipe; char * offset; int wbytes = 0; u8 byte; offset = buf; pipe = running->fd[fd]->pipe_ptr; if(running->fd[fd] ==0){ printf("Error: fd is not open\n"); return -1; } if(running->fd[fd]->mode != WRITE_PIPE){ printf("Error: fd mode is not write\n"); return -2; } printf("BEFORE WRITE:\n"); show_pipe(pipe); while(wbytes < n){ if(pipe->nreader == 0){ printf("NO READER\n"); return BROKEN_PIPE_ERROR; }else{ if(pipe->room != 0){ byte = get_byte(running->uss, offset); printf("WRITE BYTE: %c[%d]\n", byte, pipe->head); pipe->buf[pipe->head] = byte; pipe->head++; offset++; wbytes++; pipe->room--; pipe->data++; pipe->head %= PIPE_SIZE; kwakeup(&(pipe->data)); }else{ kwakeup(&(pipe->data)); ksleep(&(pipe->room)); } } } printf("AFTER WRITE:\n"); show_pipe(pipe); return wbytes; }
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 read_pipe(int fd, char *buf, int n) { int r = 0; char c; OFT *op; PIPE *p; if (n<=0) return 0; if (fd < 0 || fd > NFD || running->fd[fd] == 0){ printf("bad fd %d\n", fd); return -1; } op = running->fd[fd]; if (op->mode != READ_PIPE){ printf("fd = %d is NOT for read\n", fd); return -1; } p = op->pipe_ptr; printf("pipe before reading\n"); show_pipe(p); while(n){ while(p->data){ c = p->buf[p->tail++]; put_byte(c, running->uss, buf); p->tail %= PSIZE; p->data--; p->room++; n--; r++; buf++; if (n == 0) break; } if (n==0 || r){ kwakeup(&p->room); printf("pipe after reading\n"); show_pipe(p); return r; } // pipe has no data if (p->nwriter){ // if pipe still has writer printf("pipe before reader goes to sleep\n"); show_pipe(p); kwakeup(&p->room); // wakeup ALL writers, if any. ksleep(&p->data); // sleep for data continue; } // pipe has no writer and no data return 0; } }
int read_pipe(int fd, char *buf, int n) { int i, bytes= 0; PIPE* pipe; u8 info; char byte; 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 != READ_PIPE){ printf("fd not in read mode\n"); return -2; } pipe = running->fd[fd]->pipe_ptr; //show_pipe(pipe); if(pipe->nwriter == 0){ printf("No Writer\n"); return -3; } while ( bytes < n) { if( pipe->data <= 0) { kwakeup(&(pipe->room)); ksleep(&(pipe->data)); } byte = pipe->buf[pipe->tail]; put_byte(byte, running->uss, buf); //printf("Byte[%d]:%c\n", pipe->tail, byte); pipe->buf[pipe->tail] = 0; pipe->tail++; pipe->tail %= PSIZE; bytes++; pipe->room++; pipe->data--; buf++; kwakeup(&(pipe->room)); } return bytes; //tswitch(); //show_pipe(pipe); }
/************************************************************************ kbhandler() is the kbd interrupt handler. PC's kbd generates 2 interrupts for each key typed; one when the key is pressed and another one when the key is released. Each key generates a scan code. The scan code of a key release is 0x80 + the scan code of key pressed. When the kbd interrupts, the scan code is in the data port (0x60) of the KBD interface. First, read the scan code from the data port. Then ack the key input by strobing its PORT_B at 0x61. Some special keys generate ESC key sequences,e.g. arrow keys. Then process the scan code: 1. Ignore key releases, thus no special keys, such as shift. For normal keys: translate into LOWER CASE ASCII char. 2. Raise the kbdata flag, allowing a busy waiting process to get the key ************************* Lower half driver ******************************/ int kbhandler() { int scode, value, c; /* Fetch the character from the keyboard hardware and acknowledge it. */ scode = in_byte(KEYBD);/* get the scan code of the key struck */ value = in_byte(PORT_B);/* strobe the keyboard to ack the char */ out_byte(PORT_B, value | KBIT);/* first, strobe the bit high */ out_byte(PORT_B, value); /* then strobe it low */ printf("kb interrupt %x\n", scode); // should see the scand code if (scode & 0x80) // ignore key release goto out; kbc = unshift[scode]; // translate scan code into ASCII char if(data != 128){ buf[head] = kbc; head ++; head %= 128; data ++; kwakeup(&buf); }else{ printf("kbderr"); } out: out_byte(0x20, 0x20); }
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, wake_p1 = 0; PROC *ptr; running->exitCode = exitvalue; // Make sure P1 does not die if other procs still exist. if (running->pid == 1) { printf("waiting for running procs ... \n"); while ((ptr = hasChildren(running)) != 0) { kwait(ptr); } printf(" ... all P1 children done\n"); } // Give away children (dead or alive) to P1. //printf("Finding children:\n"); for (i=2; i<NPROC; i++) { ptr = &proc[i]; if (running->pid == ptr->ppid) { printf("Giving %d to P1\n", ptr->pid); ptr->ppid = 1; ptr->parent = &proc[1]; wake_p1 = 1; } } // Issue wakeup(parent) to wake up its parent printf("Waking parent %d at 0x%x\n", running->ppid, running->parent); kwakeup(running->parent); // Wake up P1 also if it has sent any children to P1 if (wake_p1 && running->ppid != 1) { printf("Also waking P1\n"); kwakeup(&proc[1]); } running->status = ZOMBIE; //printf("I'm a zombie...\n"); //debugStatement(); tswitch(); return(-1); }
do_wakeup(){ int val = 0; bzero(buf, BUF_SIZE); printf("enter wakeup event: "); gets(buf); val = atoi(buf); kwakeup(val); }
int read_pipe(int fd, char *buf, int n) { // int i, bytesRead; // your code for read_pipe() PIPE *p = running->fd[fd]->pipe_ptr; bytesRead = 0; while(1) { if(!p) { printf("ERROR: No pipe at given file descriptor\n"); return -1; } //1. If no writers on pipe read nbytes or as much data as available if(p->nwriter < 1) { read_bytes(p, buf, &bytesRead, n); return bytesRead; } //2. If pipe has data & writers read until nbytes, if not enough data go to 3 if(p->data > 0) { printf("There's data, let's read!\n"); //FOR TESTING read_bytes(p, buf, &bytesRead, n); kwakeup(&p->room); if(bytesRead == n) { return bytesRead; } } //3. If no data in pipe wakeup writers waiting for room, wait for data, then back to step 1 if(p->data == 0) { //Wakeup writers and wait for data kwakeup(&p->room); ksleep(&p->data); } } return -1; }
int kexit(int event) { int hc = 0; PROC *child, *temp; child = temp = 0; running->exitCode = event; //run through each proc list to find any children temp = readyQueue; while(temp) { if(temp->ppid == running->pid) //child found { hc = 1; if(running->pid == 1) {break;} temp->ppid = 1; //change parent to proc1 } temp = temp->next; } temp = sleepList; while(temp) { if(temp->ppid == running->pid) { hc = 1; if(running->pid == 1) {break;} temp->ppid = 1; } temp = temp->next; } 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(); }
int do_wakeup(){ int wakeupValue; char buf[32]; printf("please enter an wakeupValue: "); gets(buf); wakeupValue = stoi(buf); printf("\nWaking up with %d\n", wakeupValue); kwakeup(wakeupValue); }
int close_pipe(int fd) { OFT *op; PIPE *pp; printf("proc %d close_pipe: fd=%d\n", running->pid, fd); op = running->fd[fd]; running->fd[fd] = 0; // clear fd[fd] entry //close READ_PIPE case if (op->mode == READ_PIPE) { pp = op->pipe_ptr; pp->nreader--; // dec n reader by 1 if (--op->refCount == 0) { // last reader if (pp->nwriter <= 0) { // no more writers pp->busy = 0; // free the pipe return; } } kwakeup(&pp->room); return; } //close WRITE_PIPE case if (op->mode == WRITE_PIPE) { pp = op->pipe_ptr; pp->nwriter--; //dec n writer by 1 if (--op->refCount == 0) { //last writer if(pp->nreader <= 0) {//no more readers pp->busy = 0; return; } } kwakeup(&pp->data); return; } return -1; }
int kexit(int exitValue) { int i; PROC *p; /* 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(); }
int kexit(int exitValue) { int i, wakeupP1 = 0; PROC *p; printf("NPROC=%d\nrunning->pid:%d\n", nproc, running->pid); if (running->pid==1 && nproc>2){ //If we still have child PROCS // 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]; //For all PROCS that aren't FREE or whose parent is running, //set their new parent as P1 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; //decrement number of procs nproc--; /* 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 }
int write_pipe(int fd, char *buf, int n) { char c; int r=0; PIPE *p; OFT *op; if (fd < 0 || fd > NFD || running->fd[fd] == 0){ printf("bad fd %d\n", fd); return -1; } op = running->fd[fd]; if (op->mode != WRITE_PIPE){ printf("fd = %d is NOT for write\n", fd); return -1; } p = op->pipe_ptr; printf("pipe before writing\n"); show_pipe(p); while(n){ if (!p->nreader){ // no more readers printf("proc %d : BROKEN_PIPE error\n", running->pid); kexit(0x0D); // simulate SIGPIPE=13 } while(p->room && n){ p->buf[p->head++] = get_byte(running->uss, buf); p->head %= PSIZE; p->data++; p->room--; n--; r++; buf++; } kwakeup(&p->data); // wakeup ALL readers, if any. if (n==0){ printf("pipe after writing\n"); show_pipe(p); return r; // finished writing n bytes } // still has data to write but pipe has no room printf("pipe before writer goes to sleep\n"); show_pipe(p); ksleep(&p->room); // sleep for room } return r; }
int kread_pipe(int fd, char *buf, int n){ int r = 0; OFT *op; PIPE *pp; char c; printf("Attempted to read %d bytes from fd (%d)\n", n, fd); if(n <= 0){ return 0; } if(fd >= NFD || fd < 0){ printf("invalid file descriptor (out of bounds).\n"); return -1; } if(!running->fd[fd]){ printf("invalid file descriptor (not opened).\n"); return -1; } op = running->fd[fd]; pp = op->pipe_ptr; if(op->mode != READ_PIPE){ printf("fd (%d) is not for pipe read\n", fd); return -1; } printf("pipe before reading\n"); show_pipe(pp); while(n){ while(pp->data){ c = pp->buf[(pp->tail)++]; put_byte(c, running->uss, buf); pp->tail = pp->tail % PSIZE; pp->data--; pp->room++; n--; r++; buf++; if(n == 0) break; } if(n == 0 || r){ kwakeup(&(pp->room)); printf("pipe after reading\n"); show_pipe(pp); return r; } //need some but didn't get none if(pp->nwriter){ printf("pipe before reader goes to sleep\n"); show_pipe(pp); kwakeup(&(pp->room)); ksleep(&(pp->data)); continue; } //pipe has no writer and no data printf("pipe had no writer and no data\n"); return 0; } printf("how tf do we get here?\n"); return 0; }
int kbhandler() { int scode, value, c; KBD *kp = &kb; /* Fetch the character from the keyboard hardware and acknowledge it. */ scode = in_byte(KEYBD); /* get the scan code of the key struck */ value = in_byte(PORT_B); /* strobe the keyboard to ack the char */ out_byte(PORT_B, value | KBIT); /* first, strobe the bit high */ out_byte(PORT_B, value); /* then strobe it low */ // printf("scode=%x\n", scode); if (scode == 0xE0) // ESC key esc++; // inc esc count by 1 if (esc && esc < 2) // only the first ESC key, wait for next code goto out; if (esc == 2){ // two 0xE0 means escape sequence key release if (scode == 0xE0) // this is the 2nd E0 itself, real code will come next goto out; // with esc==2, this must be the actual scan code, so handle it scode &= 0x7F; // leading bit off if (scode == 0x38){ // Right Alt alt = 0; goto out; } if (scode == 0x1D){ // Right Control release control = 0; goto out; } if (scode == 0x48){ // up arrow arrowKey = 0x0B; printf("UP arrow key\n"); } esc = 0; goto out; } if (scode & 0x80){ // key release: ONLY catch release of shift, control,alt scode &= 0x7F; // mask out bit 7 if (scode == LSHIFT || scode == RSHIFT) shifted = 0; // released the shift key if (scode == CONTROL) control = 0; // released the Control key if (scode == ALT) alt = 0; // released the ALT key goto out; } // from here on, must be key press if (scode == 1){ // Esc key on keyboard printf("Esc key\n"); goto out; } if (scode == LSHIFT || scode == RSHIFT){ shifted = 1; // set shifted flag goto out; } if (scode == ALT){ alt = 1; goto out; } if (scode == CONTROL){ control = 1; goto out; } if (scode == 0x3A){ capslock = 1 - capslock; // capslock key acts like a toggle goto out; } if (control && alt && scode == DEL){ printf("3-finger salute\n"); goto out; } /************ 5-06-****** add F keys for debuggin *************/ if (scode == F1){ printf("F1 key : "); do_ps(); goto out; } if (scode == F2){ printf("Function Key F2\n"); goto out; } // translate scan code to ASCII, using shift[ ] table if shifted; c = (shifted ? shift[scode] : unshift[scode]); // Convert all to upper case if capslock is on if (capslock){ if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; else if (c >= 'a' && c <= 'z') c -= 'a' - 'A'; } if (control && (c=='c'||c=='C')){ // Control-C keys on PC, these are 2 keys printf("Control-C Keys : Send INTR signal to process\n"); goto out; } if (control && (c=='d'|| c=='D')){ // Control-D, these are 2 keys printf("Control-D keys : set code=4 to let process hanlde KBD EOF\n"); c = 4; // Control-D } /* Store the character in kb.buf[] for process to get */ if (kb.data == KBLEN){ printf("%c\n", BELL); goto out; // kb.buf[] already FULL } kb.buf[kb.head++] = c; kb.head %= KBLEN; kb.data++; kwakeup(&kb.data); out: out_byte(0x20, 0x20); }
/** * Call by the exeption to handle the syscall * \private */ void syscall_handler(registers_t * regs) { int32_t res = 0; int32_t syscall = regs->v_reg[0]; // code of the syscall switch (syscall) { case FOURCHETTE: res = create_proc(get_arg((char **) regs->a_reg[2], 0), regs->a_reg[0], regs->a_reg[1], (char **) regs->a_reg[2]); break; case PRINT: res = print_string((char *) regs->a_reg[0]); return; /* We save the good return value in the pcb */ case READ: res = read_string((char *) regs->a_reg[0], regs->a_reg[1]); return; /* We save the good return value in the pcb */ case FPRINT: if (regs->a_reg[0] == CONSOLE) kprint((char *) regs->a_reg[1]); else kmaltaprint8((char *) regs->a_reg[1]); break; case SLEEP: res = go_to_sleep(regs->a_reg[0]); break; case BLOCK: res = kblock(regs->a_reg[0], BLOCKED); break; case UNBLOCK: kwakeup(regs->a_reg[0]); break; case WAIT: res = waitfor(regs->a_reg[0], (int32_t *) regs->a_reg[1]); break; case SEND: res = send_msg(pcb_get_pid(get_current_pcb()), (msg_arg *) regs->a_reg[0]); break; case RECV: res = recv_msg(pcb_get_pid(get_current_pcb()), (msg_arg *) regs->a_reg[0]); if (res == NOTFOUND) go_to_sleep(((msg_arg *) regs->a_reg[0])->timeout); break; case PERROR: kperror((char *) regs->a_reg[0]); break; case GERROR: res = kgerror(); break; case SERROR: kserror(regs->a_reg[0]); break; case GETPINFO: res = get_pinfo(regs->a_reg[0], (pcbinfo *) regs->a_reg[1]); break; case GETPID: res = pcb_get_pid(get_current_pcb()); break; case GETALLPID: res = get_all_pid((int *) regs->a_reg[0]); break; case CHGPPRI: res = chg_ppri(regs->a_reg[0], regs->a_reg[1]); break; case KILL: res = kkill(regs->a_reg[0]); break; case EXIT: kexit(regs->a_reg[0]); break; default: kprintln("ERROR: Unknown syscall"); break; } // saves the return code regs->v_reg[0] = res; return; }
int kclose_pipe(int fd){ printf("Attempt to close (fd), (%d)\n", fd); if(fd >= NFD || fd < 0){ printf("invalid file descriptor (out of bounds).\n"); return -1; } if(!running->fd[fd]){ printf("invalid file descriptor (not opened).\n"); return -1; } running->fd[fd]->refCount--; if(running->fd[fd]->mode == WRITE_PIPE){ running->fd[fd]->pipe_ptr->nwriter--; printf("Attempt writer close\n"); if(running->fd[fd]->pipe_ptr->nwriter == 0){ //refCount of fd should = nwriter printf("last writer of pipe closing\n"); if(running->fd[fd]->pipe_ptr->nreader <= 0){ //free pipe running->fd[fd]->pipe_ptr->busy = 0; running->fd[fd]->refCount = 0; running->fd[fd] = 0; printf("pipe has been freed\n"); printf("successful closing of fd: %d\n", fd); return 0; } running->fd[fd]->refCount = 0; } //wake up data kwakeup(&(running->fd[fd]->pipe_ptr->data)); } else if(running->fd[fd]->mode == READ_PIPE){ running->fd[fd]->pipe_ptr->nreader--; printf("Attempt reader close\n"); if(running->fd[fd]->pipe_ptr->nreader == 0){ printf("last reader of pipe closing\n"); if(running->fd[fd]->pipe_ptr->nwriter == 0){ running->fd[fd]->pipe_ptr->busy = 0; running->fd[fd]->refCount = 0; running->fd[fd] = 0; printf("pipe has been freed\n"); printf("successful closing of fd: %d\n", fd); return 0; } running->fd[fd]->refCount = 0; } //wake up room kwakeup(&(running->fd[fd]->pipe_ptr->room)); } running->fd[fd] = 0; printf("successful closing of fd: %d\n", fd); return 0; }
int kwrite_pipe(int fd, char *buf, int n){ char c; int r = 0; PIPE *pp; OFT* op; printf("Attempt pipe write of %d bytes to fd (%d)\n", n, fd); // if(n <= 0){ // return 0; // } if(fd >= NFD || fd < 0){ printf("invalid file descriptor (out of bounds).\n"); return -1; } if(!running->fd[fd]){ printf("invalid file descriptor (not opened).\n"); return -1; } op = running->fd[fd]; pp = op->pipe_ptr; if(op->mode != WRITE_PIPE){ printf("fd (%d) is not for pipe read\n", fd); return -1; } printf("pipe before writing\n"); show_pipe(pp); while(n){ if(!pp->nreader){ printf("proc %d : BROKEN_PIPE error\n", running->pid); kexit(0x0D); } while(pp->room && n){ pp->buf[pp->head++] = get_byte(running->uss, buf); pp->head = pp->head % PSIZE; pp->data++; pp->room--; n--; r++; buf++; } kwakeup(&(pp->data)); if(n==0){ printf("pipe after writing\n"); show_pipe(pp); return r; } printf("pipe before writer goes to sleep\n"); show_pipe(pp); ksleep(&(pp->room)); } return r; }
int read_pipe(int fd, char *buf, int n) { // your code for read_pipe() PIPE *pipe; char * offset; int rbytes = 0; u8 byte; offset = buf; pipe = running->fd[fd]->pipe_ptr; if(running->fd[fd] ==0){ printf("Error: fd is not open\n"); return -1; } if(running->fd[fd]->mode != READ_PIPE){ printf("Error: fd mode is not read\n"); return -2; } printf("BEFORE READ:\n"); show_pipe(pipe); while(rbytes < n){ if(pipe->nwriter == 0){ /* read as much as it can; either nbytes or until no more data. return ACTUAL number of bytes read. */ // Put the byte into umode, then destroy it in the pipe printf("NO WRITER\n"); if(pipe->data != 0){ byte = pipe->buf[pipe->tail]; printf("READ BYTE: %c[%d]\n", byte, pipe->tail); put_byte(byte, running->uss, offset); pipe->buf[pipe->tail] = 0; pipe->room++; pipe->data--; rbytes++; offset++; pipe->tail++; pipe->tail %= PIPE_SIZE; }else{ printf("AFTER READ:\n"); show_pipe(pipe); return rbytes; } // ksleep(&(pipe->data)); }else{ if(pipe->data != 0){ byte = pipe->buf[pipe->tail]; printf("READ BYTE: %c[%d]\n", byte, pipe->tail); put_byte(byte, running->uss, offset); pipe->buf[pipe->tail] = 0; pipe->room++; pipe->data--; rbytes++; offset++; pipe->tail++; pipe->tail %= PIPE_SIZE; kwakeup(&(pipe->room)); }else{ kwakeup(&(pipe->room)); ksleep(&(pipe->data)); } } } printf("AFTER READ:\n"); show_pipe(pipe); return rbytes; }