static void child(int n) { // Only first 2 children participate in first pingpong test cprintf("in child %d\n", n); if (n < 2) { int i; for (i = 0; i < 10; i++) { cprintf("in child %d count %d\n", n, i); while (pingpong != n) pause(); xchg(&pingpong, !pingpong); } sys_ret(); } // Second test, round-robin pingpong between all 4 children int i; for (i = 0; i < 10; i++) { cprintf("in child %d count %d\n", n, i); while (pingpong != n) pause(); xchg(&pingpong, (pingpong + 1) % 4); } sys_ret(); // Only "child 0" (or the proc that thinks it's child 0), trap check... if (n == 0) { assert(recovargs == NULL); trap_check(&recovargs); assert(recovargs == NULL); sys_ret(); } panic("child(): shouldn't have gotten here"); }
// Flush any outstanding writes on this file to our parent process. // (XXX should flushes propagate across multiple levels?) int fileino_flush(int ino) { assert(fileino_isvalid(ino)); if (files->fi[ino].size > files->fi[ino].rlen) sys_ret(); // synchronize and reconcile with parent return 0; }
void gcc_noreturn exit(int status) { // To exit a PIOS user process, by convention, // we just set our exit status in our filestate area // and return to our parent process. files->status = status; files->exited = 1; sys_ret(); panic("exit: sys_ret shouldn't have returned"); }
// Read up to 'count' data elements each of size 'eltsize', // starting at absolute byte offset 'ofs' within the file in inode 'ino'. // Returns the number of elements (NOT the number of bytes!) actually read, // or if an error occurs, returns -1 and sets errno appropriately. // The number of elements returned is normally equal to the 'count' parameter, // but may be less (without resulting in an error) // if the file is not large enough to read that many elements. ssize_t fileino_read(int ino, off_t ofs, void *buf, size_t eltsize, size_t count) { assert(fileino_isreg(ino)); assert(ofs >= 0); assert(eltsize > 0); fileinode *fi = &files->fi[ino]; #if LAB >= 9 // XXX hack: allow reading init-files bigger than 4MB #else assert(fi->size <= FILE_MAXSIZE); #endif #if SOL >= 4 ssize_t actual = 0; while (count > 0) { // Read as many elements as we can from the file. // Note: fd->ofs could well point beyond the end of file, // which means that avail will be negative - but that's OK. ssize_t avail = MIN(count, (fi->size - ofs) / eltsize); if (ofs >= fi->size) avail = 0; if (avail > 0) { memmove(buf, FILEDATA(ino) + ofs, avail * eltsize); buf += avail * eltsize; actual += avail; count -= avail; } // If there's no more we can read, stop now. if (count == 0 || !(fi->mode & S_IFPART)) break; // Wait for our parent to extend (or close) the file. #if LAB >= 99 cprintf("fileino_read: waiting for input on file %d\n", fd - files->fd); #endif sys_ret(); } return actual; #else // ! SOL >= 4 // Lab 4: insert your file reading code here. warn("fileino_read() not implemented"); errno = EINVAL; return -1; #endif // ! SOL >= 4 }