/* Process that handles clock ticks */ void timerproc(int i,void *v1,void *v2) { register struct timer *t; int32 bugfix; struct timeval tv; for(;;){ fflush(stdout); /* And flush out stdout too */ gettimeofday(&tv, 0); Secclock = tv.tv_sec; Msclock = 1000 * Secclock + tv.tv_usec / 1000; while((t = Timers) && (bugfix = t->expiration - Msclock) <= 0) { if ((Timers = t->next)) Timers->prev = NULL; t->state = TIMER_EXPIRE; if(t->func){ (*t->func)(t->arg); } } #ifndef SINGLE_THREADED kwait(NULL); /* Let them run before handling more ticks */ #else return; #endif } }
void floppy_reset(void) { int a; prepare_wait_irq(FLOPPY_IRQ); outportb((FLOPPY_FIRST + DIGITAL_OUTPUT_REGISTER), 0x00); /*disable controller*/ kwait(0, 1000 * 50); outportb((FLOPPY_FIRST + DIGITAL_OUTPUT_REGISTER), 0x0c); /*enable controller*/ kprintf("FDD: Reseted controller\n"); wait_irq(FLOPPY_IRQ); kprintf("FDD: Waited for it\n"); for(a = 0; a < 4; a++) { floppy_sense_interrupt(); } outportb(FLOPPY_FIRST + CONFIGURATION_CONTROL_REGISTER, 0); floppy_configure(); if (floppy_drives[0].type) { floppy_calibrate(0); } if (floppy_drives[1].type) { floppy_calibrate(1); } kprintf("FDD: Calibrated drives\n"); }
int so_tcp_send(struct usock *up,struct mbuf **bpp,struct sockaddr *to) { struct tcb *tcb; long cnt; if((tcb = up->cb.tcb) == NULL){ free_p(bpp); errno = ENOTCONN; return -1; } cnt = send_tcp(tcb,bpp); while((tcb = up->cb.tcb) != NULL && tcb->sndcnt > tcb->window){ /* Send queue is full */ if(up->noblock){ errno = EWOULDBLOCK; return -1; } else if((errno = kwait(up)) != 0){ return -1; } } if(tcb == NULL){ errno = ENOTCONN; return -1; } return cnt; }
int so_tcp_recv(struct usock *up,struct mbuf **bpp,struct sockaddr *from, int *fromlen) { long cnt; struct tcb *tcb; while((tcb = up->cb.tcb) != NULL && tcb->r_upcall != trdiscard && (cnt = recv_tcp(tcb,bpp,0)) == -1){ if(up->noblock){ errno = EWOULDBLOCK; return -1; } else if((errno = kwait(up)) != 0){ return -1; } } if(tcb == NULL){ /* Connection went away */ errno = ENOTCONN; return -1; } else if(tcb->r_upcall == trdiscard){ /* Receive shutdown has been done */ errno = ENOTCONN; /* CHANGE */ return -1; } return cnt; }
/* TCP transmit upcall routine */ static void s_ttcall(struct tcb *tcb,int32 cnt) { /* Wake up anybody waiting to send data, and let them run */ ksignal(itop(tcb->user),1); kwait(NULL); }
/************** 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); }
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; }
// waits a process int kkwait(int *status) { int pid, c; pid = kwait(&c); put_word(c, running->uss, status); return pid; }
int do_wait() { int child, status; child = kwait(&status); if (child<0){ printf("KillModule %d wait error : no child\n", running->pid); return -1; } printf("KillModule %d found a ZOMBIE child %d exitValue=%d\n", running->pid, child, status); return child; }
do_wait(){ int pid, status; pid = kwait(&status); if(pid < 0){ printf("running %d has no children to wait for\n", running->pid); } printf("dead child pid: %d | exitStatus: %d", pid, status); }
int so_tcp_conn(struct usock *up) { int s; struct tcb *tcb; struct socket lsock,fsock; struct sockaddr_in *local,*remote; if(up->name == NULL){ autobind(up); } if(checkipaddr(up->peername,up->peernamelen) == -1){ errno = EAFNOSUPPORT; return -1; } s = up->index; /* Construct the TCP-style ports from the sockaddr structs */ local = (struct sockaddr_in *)up->name; remote = (struct sockaddr_in *)up->peername; if(local->sin_addr.s_addr == INADDR_ANY) /* Choose a local address */ local->sin_addr.s_addr = locaddr(remote->sin_addr.s_addr); lsock.address = local->sin_addr.s_addr; lsock.port = local->sin_port; fsock.address = remote->sin_addr.s_addr; fsock.port = remote->sin_port; /* Open the TCB in active mode */ up->cb.tcb = open_tcp(&lsock,&fsock,TCP_ACTIVE,0, s_trcall,s_ttcall,s_tscall,up->tos,s); /* Wait for the connection to complete */ while((tcb = up->cb.tcb) != NULL && tcb->state != TCP_ESTABLISHED){ if(up->noblock){ errno = EWOULDBLOCK; return -1; } else if((errno = kwait(up)) != 0){ return -1; } } if(tcb == NULL){ /* Probably got refused */ FREE(up->peername); errno = ECONNREFUSED; return -1; } return 0; }
/* Process SLIP line input */ void slip_rx( struct iface *iface) { int c; struct mbuf *bp; register struct slip *sp; int cdev; uint8 *cp; uint8 buf[4096]; int cnt; int xdev; xdev = iface->xdev; sp = &Slip[xdev]; cdev = sp->iface->dev; cnt = (*sp->get)(cdev,cp=buf,sizeof(buf)); while(--cnt >= 0){ if((bp = slip_decode(sp,*cp++)) == NULL) continue; /* More to come */ if (sp->iface->trace & IF_TRACE_RAW) raw_dump(sp->iface,IF_TRACE_IN,bp); if(sp->slcomp){ if ((c = bp->data[0]) & SL_TYPE_COMPRESSED_TCP) { if ( slhc_uncompress(sp->slcomp, &bp) <= 0 ) { free_p(&bp); sp->errors++; continue; } } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) { bp->data[0] &= 0x4f; if ( slhc_remember(sp->slcomp, &bp) <= 0 ) { free_p(&bp); sp->errors++; continue; } } } net_route( sp->iface, &bp); /* Especially on slow machines, serial I/O can be quite * compute intensive, so release the machine before we * do the next packet. This will allow this packet to * go on toward its ultimate destination. [Karn] */ kwait(NULL); } }
int do_wait(int *ustatus) { int child, status; child = kwait(&status); if (child<0){ printf("proc %d wait error : no child\n", running->pid); return -1; } printf("proc %d found a ZOMBIE child %d exitValue=%d\n", running->pid, child, status); // write status to Umode *ustatus put_word(status, running->uss, ustatus); return child; }
void floppy_motor_on(uint_t drive) { if (drive >= MAX_DRIVES || floppy_drives[drive].motor) { return; } if (floppy_drives[drive].motor_off_timer) { ktimer_stop(floppy_drives[drive].motor_off_timer); floppy_drives[drive].motor_off_timer = 0; } floppy_drives[drive].motor = 1; floppy_motors |= (1 << drive); outportb(FLOPPY_FIRST + DIGITAL_OUTPUT_REGISTER, 0xC + (floppy_motors << 4)); /* motor on */ kwait(0, 1000 * 500); /* wait it spins up */ }
/* Wait for a connection. Valid only for connection-oriented sockets. */ int accept( int s, /* Socket index */ struct sockaddr *peername, /* Peer name */ int *peernamelen /* Length of peer name */ ){ int i; register struct usock *up; struct socklink *sp; if((up = itop(s)) == NULL){ errno = EBADF; return -1; } if(up->cb.p == NULL){ errno = EOPNOTSUPP; return -1; } sp = up->sp; /* Fail if accept flag isn't set */ if(sp->accept == FALSE){ errno = EOPNOTSUPP; return -1; } /* Wait for the state-change upcall routine to signal us */ while(up->cb.p != NULL && up->rdysock == -1){ if(up->noblock){ errno = EWOULDBLOCK; return -1; } else if((errno = kwait(up)) != 0){ return -1; } } if(up->cb.p == NULL){ /* Blown away */ errno = EBADF; return -1; } i = up->rdysock; up->rdysock = -1; up = itop(i); if(peername != NULL && peernamelen != NULL){ *peernamelen = min(up->peernamelen,*peernamelen); memcpy(peername,up->peername,*peernamelen); } return i; }
/* Delay process for specified number of milliseconds. * Normally returns 0; returns -1 if aborted by alarm. */ int ppause(int32 ms) { int val = 0; if(Curproc == NULL || ms <= 0) return 0; kalarm(ms); /* The actual event doesn't matter, since we'll be alerted */ while(Curproc->alarm.state == TIMER_RUN){ if((val = kwait(Curproc)) != 0) break; } kalarm(0L); /* Make sure it's stopped, in case we were killed */ return (val == EALARM) ? 0 : -1; }
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); }
int kcinth() { u16 segment, offset; int a,b,c,d,r; segment = running->uss; offset = running->usp; a = get_word(segment, offset + 2*PA); b = get_word(segment, offset + 2*(PA+1)); c = get_word(segment, offset + 2*(PA+2)); d = get_word(segment, offset + 2*(PA+3)); switch(a) { case 0: r = getpid(); break; case 1: r = kps(); break; case 2: k = kchname(); break; case 3: r = kkfork(); break; case 4: r = kswitch(); break; case 5: r = kwait(b); break; case 6: kexit(); break; default: printf("invalid syscall %d\n", a); } put_word(r, segment, offset + 2*AX); }
int kkwait(int *ustatus) { //use YOUR kwait() in LAB3; //return values to Umode!!! int child, status; child = kwait(&status); if (child<0){ printf("proc %d wait error : no child\n", running->pid); return -1; } printf("proc %d found a ZOMBIE child %d with exitValue=%d\n", running->pid, child, status); // write status to Umode *ustatus put_word(status, running->uss, ustatus); return child; }
int body() { char c; printf("proc %d resumes to body()\n", running->pid); while(1) { printLists(); printf("proc %d[%d] running: parent=%d\n", running->pid, running->priority, running->ppid); printf("enter a char [Debug|Fork|Umode|Ps|Quit|Sleep|Wait] : "); c = getc(); printf("%c\n", c); switch(c) { case 's' : tswitch(); break; case 'f' : kfork(); break; case 'q' : kexit(); break; case 'p' : kps(); break; case 'w' : kwait(); break; case 'd' : debugStatement(); break; case 'u' : goUmode(); break; } } }
int floppy_rw_sector(uint_t drive, uint8_t sector, uint8_t head, uint8_t cylinder, uintptr_t buffer, int write) { int a; alku: if (drive >= MAX_DRIVES || !floppy_drives[drive].type) { return -1; } if (inportb(FLOPPY_FIRST + DIGITAL_INPUT_REGISTER) & 0x80) { /* disk was changed */ floppy_seek_track(drive, 1); floppy_calibrate(drive); floppy_motor_off(drive); if (inportb(FLOPPY_FIRST + DIGITAL_INPUT_REGISTER) & 0x80) { kprintf("FDD: No floppy in fd%u\n", drive); return -2; } else { kprintf("FDD: Floppy changed, trying again...\n"); goto alku; } } if (floppy_seek_track(drive, cylinder)) if (floppy_seek_track(drive, cylinder)) if (floppy_seek_track(drive, cylinder)) { return -1; /* three seeks? */ } /* floppy_seek_track actually starts motor already, but... */ floppy_motor_on(drive); if (!(inportb(FLOPPY_FIRST + MAIN_STATUS_REGISTER) & 0x20)) { panic("Non-dma floppy transfer?\n"); } /* block size */ floppy_init_dma(buffer, 512, write); kwait(0, 1000 * floppy_params.head_settle_time); floppy_wait(); prepare_wait_irq(FLOPPY_IRQ); floppy_command(write ? WRITE_DATA : READ_DATA); floppy_command((head << 2) | drive); floppy_command(cylinder); floppy_command(head); floppy_command(sector); floppy_command(floppy_params.bytes_per_sector); /*sector size = 128*2^size*/ floppy_command(floppy_params.sectors_per_track); /*last sector*/ floppy_command(floppy_params.gap_length); /*27 default gap3 value*/ floppy_command(floppy_params.data_length); /*default value for data length*/ //kprintf("FDD: BPS: %u, SPT: %u, GL: %u, DL: %u\n", floppy_params.bytes_per_sector, floppy_params.sectors_per_track, floppy_params.gap_length, floppy_params.data_length); wait_irq(FLOPPY_IRQ); //kprintf("We got values "); for (a = 0; a < 7; a++) { /* TODO: Put these values somewhere? */ floppy_wait_data(); inportb(FLOPPY_FIRST + DATA_FIFO); //kprintf("%d ", inportb(FLOPPY_FIRST + DATA_FIFO)); } //kprintf(" from floppy controller after reading\n"); floppy_prepare_motor_off(drive); return 0; }
int do_wait(){ int pid, status; pid = kwait(&status); printf("pid = %d, status = %d\n", pid, status); }