Tyler Gaynair Lab 6 Score is out of 20

Similar documents
Diego Gamboa. cse 460: Operating Systems. Dr. Yu. Lab 8: Dining Philosophers and XV6 Process Priority.

Paging. CS143A: Principles of operating systems - Fall 17. UC Irvine, California

Compile and execute fifo1.cpp listed above. Try the Balady's anomaly examples discussed in class. Did you observe the Belady's anomaly?

Gabrielle Evaristo CSE 460. Lab Dining Philosophers and Deadlock

The Process Abstraction. CMPU 334 Operating Systems Jason Waterman

Processes & Threads. Today. Next Time. ! Process concept! Process model! Implementing processes! Multiprocessing once again. ! More of the same J

Processes and Threads

A: We see the ps auxw execute and print on screen. The program holds the command in buffer then it is printed on screen.

1 Programs and Processes

CS 385 Operating Systems Fall 2013 Homework Assignment 2 Inter-Process Communications and Synchronization

CS 385 Operating Systems Spring 2013 Homework Assignment 2 Third Draft Inter-Process Communications and Synchronization

Gabrielle Evaristo CSE 460. Lab Shared Memory

Processes. Today. Next Time. ! Process concept! Process model! Implementing processes! Multiprocessing once again. ! Scheduling processes

Processes. q Process concept q Process model and implementation q Multiprocessing once again q Next Time: Scheduling

Processes (Intro) Yannis Smaragdakis, U. Athens

Concurrent Servers. Overview. In our current assignment we have the following changes:

4. The Abstraction: The Process

Using IPC: semaphores Interprocess communication using semaphores. Lecturer: Erick Fredj

Changes made in this version not seen in first lecture:

Introduction. This project will focus primarily on processes.

Processes. Today. Next Time. Process concept Process model Implementing processes Multiprocessing once again. Scheduling processes

Threads. Threads (continued)

CS5460/6460: Operating Systems. Lecture 9: First process. Anton Burtsev January, 2014

Threads. What is a thread? Motivation. Single and Multithreaded Processes. Benefits

CS3210: Isolation Mechanisms

CSPP System V IPC 1. System V IPC. Unix Systems Programming CSPP 51081

518 Lecture Notes Week 3

CS 537: Introduction to Operating Systems (Summer 2017) University of Wisconsin-Madison Department of Computer Sciences.

CS 3305 Intro to Threads. Lecture 6

CS510 Operating System Foundations. Jonathan Walpole

Operating Systems, Final exam May 2016 Bachelor's Degree in Computer Science and Engineering

OPERATING SYSTEMS 3rd Homework

Lecture 18. Log into Linux. Copy two subdirectories in /home/hwang/cs375/lecture18/ $ cp r /home/hwang/cs375/lecture18/*.

PROCESSES. Jo, Heeseung

Processes. Jo, Heeseung

PRACTICAL NO : 1. AIM: To study various file management system calls in UNIX.

Project 3 Improved Process Management

COP 4604 UNIX System Programming IPC. Dr. Sam Hsu Computer Science & Engineering Florida Atlantic University

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

Operating systems fundamentals - B06

INTER-PROCESS COMMUNICATION. UNIX Programming 2015 Fall by Euiseong Seo

Message Queues, Semaphores, Shared Memory

Reading Assignment 4. n Chapter 4 Threads, due 2/7. 1/31/13 CSE325 - Processes 1

CS Lab 1 xv6 Introduction Setup and exercise

Project 1 System Calls

CS 350 : COMPUTER SYSTEM CONCEPTS SAMPLE TEST 2 (OPERATING SYSTEMS PART) Student s Name: MAXIMUM MARK: 100 Time allowed: 70 minutes

System Programming. Process Control II

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

Week 2 Intro to the Shell with Fork, Exec, Wait. Sarah Diesburg Operating Systems CS 3430

Introduction to OS Processes in Unix, Linux, and Windows MOS 2.1 Mahmoud El-Gayyar

Part II Processes and Threads Process Basics

CITS2002 Systems Programming. Creating a new process using fork() 1 next CITS2002 CITS2002 schedule

CSCI 4210 Operating Systems CSCI 6140 Computer Operating Systems Sample Final Exam Questions (document version 1.1) WITH SELECTED SOLUTIONS

Lecture 4 Threads. (chapter 4)

PROCESS MANAGEMENT. Operating Systems 2015 Spring by Euiseong Seo

Unix-Linux 2. Unix is supposed to leave room in the process table for a superuser process that could be used to kill errant processes.

Processes. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

This is an open book, open notes exam. But no online or in-class chatting.

POSIX threads CS 241. February 17, Copyright University of Illinois CS 241 Staff

Multithreaded Programming

UNIX IPC. Unix Semaphore Unix Message queue

EPL372 Lab Exercise 2: Threads and pthreads. Εργαστήριο 2. Πέτρος Παναγή

Introduction to Operating Systems Prof. Chester Rebeiro Department of Computer Science and Engineering Indian Institute of Technology, Madras

Interrupts, Fork, I/O Basics

CSE 380: Homework 2: Synchronization

Windows architecture. user. mode. Env. subsystems. Executive. Device drivers Kernel. kernel. mode HAL. Hardware. Process B. Process C.

Operating Systems, laboratory exercises. List 2.

CSCI 4210 Operating Systems CSCI 6140 Computer Operating Systems Sample Midterm Exam Questions (document version 1.1)

Compile the Hello World program

CISC2200 Threads Spring 2015

CS 33. Architecture and the OS. CS33 Intro to Computer Systems XIX 1 Copyright 2018 Thomas W. Doeppner. All rights reserved.

OS Lab Tutorial 1. Spawning processes Shared memory

CPSC 341 OS & Networks. Threads. Dr. Yingwu Zhu

CS 33. Architecture and the OS. CS33 Intro to Computer Systems XIX 1 Copyright 2017 Thomas W. Doeppner. All rights reserved.

Interprocess Communication. Bosky Agarwal CS 518

POSIX Semaphores. Operations on semaphores (taken from the Linux man page)

Shared Memory Semaphores. Goals of this Lecture

CS Operating Systems Lab 3: UNIX Processes

pthreads CS449 Fall 2017

NYU Poly s Policy on Academic Misconduct:

Operating Systems. Lab. Class Project #5

Operating Systems Lab

Project 2: Shell with History1

CS 475. Process = Address space + one thread of control Concurrent program = multiple threads of control

CS333 Project 1 Test Report Your Name Here

Shared Memory Memory mapped files

CS 3113 Introduction to Operating Systems Midterm October 11, 2018

CS 3113 Introduction to Operating Systems Midterm October 11, 2018

Creating a Shell or Command Interperter Program CSCI411 Lab

Processes. Chester Rebeiro IIT Madras

This is an open book, open notes exam. But no online or in-class chatting.

Note: The following (with modifications) is adapted from Silberschatz (our course textbook), Project: Producer-Consumer Problem.

Concurrent Programming. Concurrent Programming with Processes and Threads

LSN 13 Linux Concurrency Mechanisms

Processes. Johan Montelius KTH

#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *stat_loc); pid_t waitpid(pid_t pid, int *stat_loc, int options);

CS342 - Spring 2019 Project #3 Synchronization and Deadlocks

Operating systems and concurrency - B03

A process. the stack

CSC 1600 Unix Processes. Goals of This Lecture

Transcription:

Tyler Gaynair Lab 6 Score is out of 20 1.) Try the pthreads.cpp and sdlthreads_demo.cpp programs presented in Introduction. Modify the programs so that they run 3 threads ( instead of two ) and each thread runs a different function, displaying a different message. Copy-and-paste the source code as well as the outputs into your report. *Pthread Modified for 3 threads instead of 2 #include <pthread.h> #include <stdio.h> using namespace std; //The thread void *runner ( void *data ) char *tname = ( char * )data; printf("i am %s\n", tname ); pthread_exit ( 0 ); void *walker (void *data ) char *tname = (char * )data; printf("hows it %s\n", tname ); pthread_exit (0); void *jogger (void *data ) char *tname = (char * )data; printf("what is %s\n", tname ); pthread_exit (0); int main () pthread_t id1, id2, id3; //thread identifiers pthread_attr_t attr1, attr2, attr3; //set of thread attributes char *tnames[3] = "Thread 1", "going", "up" ; //names of threads //get the default attributes pthread_attr_init ( &attr1 ); pthread_attr_init ( &attr2 ); pthread_attr_init ( &attr3 ); //create the threads pthread_create ( &id1, &attr1, runner, tnames[0] ); pthread_create ( &id2, &attr2, walker, tnames[1] ); pthread_create ( &id3, &attr3, jogger, tnames[2] );

//wait for the threads to exit pthread_join ( id1, NULL ); pthread_join ( id2, NULL ); pthread_join ( id3, NULL ); *Pthread modified executed [005283235@csusb.edu@jbh3-1 Lab6]$ vi sdlthread_demomod.cpp [005283235@csusb.edu@jbh3-1 Lab6]$./pthreads_demomod I am Thread 1 Hows it going What is up [005283235@csusb.edu@jbh3-1 Lab6]$ *Sdl thread modified for 3 threads instead of 2. #include <SDL/SDL.h> #include <SDL/SDL_thread.h> #include <stdio.h> using namespace std; //The thread int runner ( void *data ) char *tname = ( char * )data; printf("i am %s\n", tname ); int walker ( void *data ) char *tname = ( char * )data; printf("howdy %s\n", tname ); int jogger (void *data ) char *tname = (char * )data; printf("my name is %s\n", tname ); int main () SDL_Thread *id1, *id2, *id3; //thread identifiers char *tnames[3] = "Thread 1", "Partner", "Tyler" ; //names of threads //create the threads id1 = SDL_CreateThread ( runner, tnames[0] ); id2 = SDL_CreateThread ( walker, tnames[1] );

id3 = SDL_CreateThread ( jogger, tnames[2] ); //wait for the threads to exit SDL_WaitThread ( id1, NULL ); SDL_WaitThread ( id2, NULL ); SDL_WaitThread ( id3, NULL ); *SDL modified thread running [005283235@csusb.edu@jb358-3 Lab6]$./sdlthread_demomod I am Thread 1 Howdy Partner My name is Tyler [005283235@csusb.edu@jb358-3 Lab6]$ The following example, sema1.cpp demonstrates the use of semaphores; it prints an "E" when entering and an "L" when leaving a critical section if the program is invoked with one or more parameters, otherwise it prints an "e" and an "l" respectively. In the program, SEM_DOWN() changes the semaphore sem_op to -1 ( waiting ), which decrements the semaphore value, and SEM_UP() changes it to 1, which increments the semaphore value so that the semaphore becomes available. Note that this sample program allows only a single binary semaphore per program, although we could extend it to pass the semaphore variable if we need more semaphores. The function set_semvalue( value ) initializes the semaphore value; if we set it to 0 and the first process executes a SEM_DOWN() then it has to wait until another process would execute a SEM_UP() to unlock the semaphore. Of course, here we only deal with one process; there's no need to use any semaphore. So the code is mainly to demonstrate the coding of semaphores. Sema1.cpp //sema1.cpp #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <iostream> #include <stdio.h> using namespace std; static int sem_id; //semaphore id #if defined( GNU_LIBRARY ) &&!defined(_sem_semun_undefined) /* union semun is defined by including <sys/sem.h> */ #else /* according to X/OPEN we have to define it ourselves */ union semun

int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* array for GETALL, SETALL */ /* Linux specific part: */ struct seminfo * buf; /* buffer for IPC_INFO */ ; #endif //initializes semaphore using SETVAL static int set_semvalue ( int val ) union semun sem_union;// sem_union; sem_union.val = val; if ( semctl ( sem_id, 0, SETVAL, sem_union ) == -1 ) return ( 0 ); return 1; //delete semaphore static int del_semvalue () union semun sem_union;// sem_union; sem_union.val = 1; if ( semctl ( sem_id, 0, IPC_RMID, sem_union ) == -1 ) return ( 0 ); return 1; static int SEM_DOWN () struct sembuf b; b.sem_num = 0; b.sem_op = -1; //P(), i.e. down() b.sem_flg = SEM_UNDO; if ( semop ( sem_id, &b, 1 ) == -1 ) cout << "Semaphore DOWN() failed!" << endl; return 1; static int SEM_UP() struct sembuf b; b.sem_num = 0; b.sem_op = 1; //V(), i.e. UP() b.sem_flg = SEM_UNDO; if ( semop ( sem_id, &b, 1 ) == -1 ) cout << "Semaphore UP() failed!" << endl; return 1; int main ( int argc, char *argv[] ) int i, pause_time;

char ce = 'e', cl = 'l'; srand ( ( unsigned int ) getpid() ); //seed RNG with process id sem_id = semget ( (key_t) 1234, 1, 0666 IPC_CREAT ); if ( argc > 0 ) if (!set_semvalue( 1 ) ) //process can enter CS cout << "Semaphore initialized failed!" << endl; exit ( EXIT_FAILURE ); if ( argc > 1 ) ce = 'E'; cl = 'L'; sleep ( 1 ); else if (!set_semvalue( 0 ) ) cout << "Semaphore initialized failed!" << endl; exit ( EXIT_FAILURE ); sleep ( 1 ); //process will be blocked initially //enter and leave critical section 10 times for ( i = 0; i < 10; i++ ) if (!SEM_DOWN () ) exit ( EXIT_FAILURE ); cout << ce; fflush ( stdout ); //entering critical section pause_time = rand() % 3; //simulate critical section sleep ( pause_time ); cout << cl; fflush ( stdout ); //leaving critical section if (!SEM_UP() ) exit ( EXIT_FAILURE ); pause_time = rand() % 2; sleep ( pause_time ); cout << endl << getpid() << " finished!" << endl; if ( argc > 0 ) sleep ( 2 ); del_semvalue (); exit ( EXIT_SUCCESS ); //signal other waiting process *Execute with./sema1 & [005283235@csusb.edu@jb358-2 Lab6]$./sema1 & [1] 9969 [005283235@csusb.edu@jb358-2 Lab6]$ elelelelelelelelelel 9969 finished! *Execute with./sema1 a [005283235@csusb.edu@jb358-2 Lab6]$./sema1 a ELELELELELELELELELEL 10056 finished! [005283235@csusb.edu@jb358-2 Lab6]$

sema1mod.cpp modified programs #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <iostream> #include <stdio.h> using namespace std; static int sem_id; //semaphore id #if defined( GNU_LIBRARY ) &&!defined(_sem_semun_undefined) /* union semun is defined by including <sys/sem.h> */ #else /* according to X/OPEN we have to define it ourselves */ union semun int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* array for GETALL, SETALL */ /* Linux specific part: */ struct seminfo * buf; /* buffer for IPC_INFO */ ; #endif //initializes semaphore using SETVAL static int set_semvalue ( int val ) union semun sem_union;// sem_union; sem_union.val = val; if ( semctl ( sem_id, 0, SETVAL, sem_union ) == -1 ) return ( 0 ); return 1; //delete semaphore static int del_semvalue () union semun sem_union;// sem_union; sem_union.val = 1; if ( semctl ( sem_id, 0, IPC_RMID, sem_union ) == -1 ) return ( 0 ); return 1; static int SEM_DOWN ()

struct sembuf b; b.sem_num = 0; b.sem_op = -1; //P(), i.e. down() b.sem_flg = SEM_UNDO; if ( semop ( sem_id, &b, 1 ) == -1 ) cout << "Semaphore DOWN() failed!" << endl; return 1; static int SEM_UP() struct sembuf b; b.sem_num = 0; b.sem_op = 1; //V(), i.e. UP() b.sem_flg = SEM_UNDO; if ( semop ( sem_id, &b, 1 ) == -1 ) cout << "Semaphore UP() failed!" << endl; return 1; int main ( int argc, char *argv[] ) int i, pause_time; char ce = 'e', cl = 'l'; srand ( ( unsigned int ) getpid() ); //seed RNG with process id sem_id = semget ( (key_t) 1234, 1, 0666 IPC_CREAT ); if ( argc > 1 ) argc = atoi(argv[1]); //if 1, proceed if (argc ==1) if (!set_semvalue( 1 ) ) //process can enter CS cout << "Semaphore initialized failed!" << endl; exit ( EXIT_FAILURE ); ce = 'E';

cl = 'L'; sleep ( 1 ); else if (!set_semvalue( 0 ) ) //process will be blocked initially cout << "Semaphore initialized failed!" << endl; exit ( EXIT_FAILURE ); sleep ( 1 ); //enter and leave critical section 10 times for ( i = 0; i < 10; i++ ) if (!SEM_DOWN () ) exit ( EXIT_FAILURE ); cout << ce; fflush ( stdout ); //entering critical section pause_time = rand() % 3; //simulate critical section sleep ( pause_time ); cout << cl; fflush ( stdout ); //leaving critical section if (!SEM_UP() ) exit ( EXIT_FAILURE ); //signal other waiting process pause_time = rand() % 2; sleep ( pause_time ); cout << endl << getpid() << " finished!" << endl; if ( argc > 0 ) sleep ( 2 ); del_semvalue (); exit ( EXIT_SUCCESS ); *Executed./sema1mod 0 then./sema1mod 1./sema1mod 0 ^C [1]+ Done./sema1 [005283235@csusb.edu@jb358-2 Lab6]$./sema1mod 1 ELELELELELELELELELEL 11366 finished! [005283235@csusb.edu@jb358-2 Lab6]$ XV6 Scheduling Proc.c modified printf cprintf("process %s with pid %d running\n", p->name, p->pid);

[005283235@csusb.edu@jb359-1 Lab3]$ vi proc.c [005283235@csusb.edu@jb359-1 Lab3]$ make qemu-nox gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall-Werror -fno-omitframe-pointer -fno-stack-protector -c -o pro proc.c: In function scheduler : proc.c:347:7: error: expected ; before swtch swtch(&(c->scheduler), p->context); ^~~~~ make: *** [<builtin>: proc.o] Error 1 [005283235@csusb.edu@jb359-1 Lab3]$ vi proc.c [005283235@csusb.edu@jb359-1 Lab3]$ make qemu-nox gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall-Werror -fno-omitframe-pointer -fno-stack-protector -c -o pro ld -m elf_i386 -T kernel.ld -o kernel entry.o bio.o console.os.o ide.o ioapic.o kalloc.o kbd.o lapic.o log.o main.o mp.o pici.o sleeplock.o spinlock.o string.o swtch.o syscall.o sysfile.o s.o trap.o uart.o vectors.o vm.o -b binary initcode entryother objdump -S kernel > kernel.asm objdump -t kernel sed '1,/SYMBOL TABLE/d; s/.* / /; /^$/d' > dd if=/dev/zero of=xv6.img count=10000 10000+0 records in 10000+0 records out 5120000 bytes (5.1 MB, 4.9 MiB) copied, 0.257629 s, 19.9 MB/s dd if=bootblock of=xv6.img conv=notrunc 1+0 records in 1+0 records out 512 bytes copied, 0.00143718 s, 356 kb/s dd if=kernel of=xv6.img seek=1 conv=notrunc 350+1 records in 350+1 records out 179212 bytes (179 kb, 175 KiB) copied, 0.00471889 s, 38.0 MB/s which: no qemu in (/usr/local/matlab/r2018a/bin:/share/bin:/usr/:/opt/xilinx/14.7/ise_ds/ise/bin/ lin64:/opt/xilinx/14.7/ise_ds/c/opt/xilinx/docnav:/opt/xilinx/vivado/2017.2/bin:/ opt/xilinx/vivin:/opt/xilinx/vivado/2017.2/bin:/opt/xilinx/vivado_hls/2017.2/ bstudio/bin:/opt/android-sdk-linux/tools:/opt/android-sdk-linux/psr/java/latest/ bin:/usr/local/matlab/r2018a/bin:/share/bin:/usr/:/opt/xilinx/14.7/ise_ds/ise/bin/ lin64:/opt/xilinx/14.7/ise_ds/c/opt/xilinx/docnav:/opt/xilinx/vivado/2017.2/bin:/ opt/xilinx/vivin:/opt/xilinx/vivado/2017.2/bin:/opt/xilinx/vivado_hls/2017.2/ bstudio/bin:/opt/android-sdk-linux/tools:/opt/android-sdk-linux/psr/java/latest/ bin:/usr/lib64/qt-3.3/bin:/usr/lib64/ccache:/usr/in:/usr/local/sbin:/usr/sbin:/ home/csusb.edu/005283235/bin) qemu-system-i386 -nographic -drive file=fs.img,index=1,media=disive file=xv6.img,index=0,media=disk,format=raw -smp 2 -m 512 xv6... cpu1: starting 1 cpu0: starting 0 sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestt 58 Process initcode with pid 1 running

Process init with pid 1 running Process init with pid 1 running Process init with pid 1 running init: starting sh Process init with pid 1 running

$ ls Process sh with pid 2 running P ailedcess sh with pid 5 running Process sh with pid 2 running $ ec: fail with pid 3 running exec ss sh with pid 3 running. 1 1 512.. Process ls with pid 3 running 1 1 512 Process ls with pid 3 running Process ls with pid 3 running Process ls with pid 3 running README 2 2 2290 cat 2 3 13692 Process ls with pid 3 running echo 2 4 12700 forktest 2 5 8132 grep 2 6 15568 init 2 7 13284 kill 2 8 12752 ln 2 9 12652 Process ls with pid 3 running ls 2 10 14840

mkdir 2 11 12832 rm 2 12 12812 sh 2 13 23300 stressfs 2 14 13480 usertests 2 15 56Process ls with pid 3 running 416 wc 2 16 14228 cp 2 17 13448 zombie 2 18 12476 console 3 19 0 myfile 2 20 2290 Process sh with pid 2 running Process sh with pid 2 running Now we write a dummy program named foo.c that creates some child processes and consumes some computing time: #include "types.h" #include "stat.h" #include "user.h" #include "fcntl.h" int main(int argc, char *argv[]) int k, n, id; double x = 0, z; if(argc < 2 ) n = 1; //default value else n = atoi ( argv[1] ); //from command line if ( n < 0 n > 20 ) n = 2; x = 0; id = 0; for ( k = 0; k < n; k++ ) id = fork (); if ( id < 0 ) printf(1, "%d failed in fork!\n", getpid() ); else if ( id > 0 ) //parent printf(1, "Parent %d creating child %d\n", getpid(), id ); // wait (); else // child printf(1, "Child %d created\n",getpid() ); break; for ( z = 0; z < 300000.0; z += 0.1 ) x = x + 3.14 * 89.64; // useless calculations to consume CPU time exit(); After Makefile is updated. [005283235@csusb.edu@jb359-1 Lab3]$ vim Makefile

[005283235@csusb.edu@jb359-1 Lab3]$ make ld -m elf_i386 -T kernel.ld -o kernel entry.o bio.o console.o exec.o file.o fs.o ide.o ioapic.o kalloc.o kbd.o lapic.o log.o main.o mp.o picirq.o pipe.o proc.o sleeplock.o spinlock.o string.o swtch.o syscall.o sysfile.o sysproc.o trapasm.o trap.o uart.o vectors.o vm.o -b binary initcode entryother objdump -S kernel > kernel.asm objdump -t kernel sed '1,/SYMBOL TABLE/d; s/.* / /; /^$/d' > kernel.sym gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 - Werror -fno-omit-frame-pointer -fno-stack-protector -c -o foo.o foo.c ld -m elf_i386 -N -e main -Ttext 0 -o _foo foo.o ulib.o usys.o printf.o umalloc.o objdump -S _foo > foo.asm objdump -t _foo sed '1,/SYMBOL TABLE/d; s/.* / /; /^$/d' > foo.sym./mkfs fs.img README _cat _echo _forktest _grep _init _kill _ln _ls _mkdir _rm _sh _stressfs _usertests _wc _cp _foo _zombie nmeta 59 (boot, super, log blocks 30 inode blocks 26, bitmap blocks 1) blocks 941 total 1000 balloc: first 629 blocks have been allocated balloc: write bitmap block at sector 58 dd if=/dev/zero of=xv6.img count=10000 10000+0 records in 10000+0 records out 5120000 bytes (5.1 MB, 4.9 MiB) copied, 0.24472 s, 20.9 MB/s dd if=bootblock of=xv6.img conv=notrunc 1+0 records in 1+0 records out 512 bytes copied, 0.0022678 s, 226 kb/s dd if=kernel of=xv6.img seek=1 conv=notrunc 350+1 records in 350+1 records out 179212 bytes (179 kb, 175 KiB) copied, 0.00566428 s, 31.6 MB/s After running foo 4 in qemu-nox $ foo 4 Process sh with pid 2 running Process sh with pid 2 running

Process foo with pid 3 running Parent 3 creating child 4 Parent 3 creating child 5 Parent 3 creating child 6 Process foo with pid 5 running Process foo with pid 6 running Child 6 created Process foo with pid 5 running Process foo with pid 3 running Process foo with pid 5 running Process foo with pid 6 running Process foo with pid 5 running Process foo with pid 3 running Parent 3 creating chilprocess foo with pid 7 running Process foo with pid 5 running Process foo with pid 6 running Process foo with pid 7 running Process foo with pid 3 running d 7 Process foo with pid 7 running Process foo with pid 5 running Child 5 created Process foo with pid 6 running Process foo with pid 7 running Child 7 created Process foo with pid 6 running Process foo with pid 3 running Child 4 created Process foo with pid 3 running Process foo with pid 5 running

Process foo with pid 6 running Process foo with pid 5 running Process foo with pid 7 running Process foo with pid 3 running Process foo with pid 7 running Process foo with pid 5 running Process foo with pid 6 running Add in the file proc.h the struct proc> the timestamps and the priority: struct proc uint sz; // Size of process memory (bytes) pde_t* pgdir; // Page table char *kstack; // Bottom of kernel stack for this process enum procstate state; // Process state int pid; // Process ID struct proc *parent; // Parent process struct trapframe *tf; // Trap frame for current syscall struct context *context; // swtch() here to run process void *chan; // If non-zero, sleeping on chan int killed; // If non-zero, have been killed struct file *ofile[nofile]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) //add timestamps and others uint createtime; //process creation time int sleeptime; //process sleeping time int readytime; //process ready (RUNNABLE) time int runtime; //process running time int priority; //process priority int tickcounter; char dum[8]; Add to the function allocproc() in proc.c the timestamp statements (highlighted in blue): static struct proc* allocproc(void) struct proc *p; char *sp; acquire(&ptable.lock);

for(p = ptable.proc; p < &ptable.proc[nproc]; p++) if(p->state == UNUSED) goto found; release(&ptable.lock); found: p->state = EMBRYO; p->pid = nextpid++; p->createtime = ticks; p->readytime = 0; p->runtime = 0; p->sleeptime = 0; release(&ptable.lock); Running foo after updating the printf in proc.c cprintf("process %s with pid %d running with createtime %d\n", p->name, p->pid, p->createtime); $ foo 4 Process sh with pid 2 running with creattime 22 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 with creattime 997 Parent 3 creating child 4 Parent 3 creating child 5 Child 4 created Child 5 created

Parent 3 creating child 6 Parent 3 creating child 7 Process foo with pid 7 running with creattime 1008 Process foo with pid 7 running with creattime 1008 Child 7 created Child 6 created Process foo with pid 7 running with creattime 1008 Process foo with pid 7 running with creattime 1008 Process foo with pid 7 running with creattime 1008 Process foo with pid 7 running with creattime 1008 Process foo with pid 7 running with creattime 1008 Process foo with pid 7 running with creattime 1008 Process foo with pid 7 running with creattime 1008

Process Creation time looks consistent with process ids. Evaluation: I feel like I deserve a 20/20 on this project because I did every part fully and put a lot of effort into it. I learned how to further manipulate a makefile and read creationtimes on process ids. Score: 20/20