### Colaborators

Eric Dai
Daniel Alexander
Ashley Francisco
Ian Lamont

### Overview of work accomplished

1. PennOS Kernel  
   1. Process-Related Required Functions (s\_spawn, s\_waitpid, s\_kill, s\_exit, s\_nice, s\_sleep, k\_proc\_create, k\_proc\_cleanup)  
   2. Signals in PennOS (P\_SIGSTOP, P\_SIGCONT, P\_SIGTERM)   
   3. Process Statuses (P\_WIFEXITED(status), P\_WIFSTOPPED(status), P\_WIFSIGNALED(status))  
   4. Init, Zombies, and Waiting (If at any time the parent thread exits prior to waiting on zombie children, the zombie children will have INIT become their new parent. Init reaps zombies through s\_waitpid and will reap the other children once they terminate. The INIT process is the ancestor of all processes and is started on boot. Init will create the shell process. All orphan child processes will have INIT become their new parent, and init will clean up those processes (through something like s\_waitpid())  
   5. Priority Scheduler (switch between running different threads rapidly)  
   6. Programming with spthreads (working with spthreads and their helper functions)  
   7. Clock ticks (SIGALRM and time quantum)  
   8. Priority Queues (Three priority levels, threads scheduled with level 0 should run 1.5 times more often than threads scheduled with priority level 1, which run 1.5 times more often than threads scheduled with priority level 2\. Threads scheduled with level 0 will run 2.25 times more often than threads scheduled with priority level 2\. Within each priority queue, the threads are selected in a round robin format, and each queue must be implemented as a linked list or vector.)  
   9. Idling (Leverage sigsuspend(2), suspend the calling process until a signal is delivered to it, resulting in 0% CPU usage. Scheduler should idle only when all other processes are blocked and the scheduler has no real process to schedule.)  
2. Shell Subroutines  
   1. Job Control  
      1. Tracking all jobs (background and foreground) in vectors  
      2. Assigning each job a unique job ID and storing its command, status, and associated process list.  
      3. Updating job status automatically as processes are stopped, continued, or finished.  
      4. Allowing the user to query, stop, continue, and clean up jobs.  
      5. Functions:  
         1. init\_job\_system()  
            Initializes the job table and status vectors, preparing the system for job management.  
         2. add\_job()  
            Creates a new job structure, assigns it a job ID, stores command info, and adds it to the running jobs vector and job table.  
         3. find\_job\_by\_id() / find\_job\_by\_pid()  
            Retrieves a job by its job ID or by the PID of its main process.  
         4. update\_job\_status()  
            Inspects all processes in a job, determines the correct job status (running, stopped, done), and moves the job between the appropriate status vectors.  
         5. cleanup\_jobs()  
            Removes finished jobs from the job table and clears the finished jobs vector.  
         6. print\_jobs()  
            Prints all jobs in a given status vector, clearly indicating the most recently started job.  
         7. print\_job\_processes()  
            Prints detailed information for each process in a job.  
         8. job\_destroy() (static)  
            Frees all resources used by a job, including its command string and process vector.  
   2. jobs: prints all jobs, grouped by status (Running, Stopped, Done)  
   3. fg: brings a background/stopped job to the foreground, resumes if stopped, and waits for it to finish or stop again  
   4. bg: resumes the specified stopped job in the background. If no job ID is given, resumes the most recently stopped job.  
   5. logout: exits the shell by setting running \= false  
   6. man: prints a help/manual page with all available commands and their descriptions  
   7. nice \<priority\> \<command\> \[args…\]: runs \<command\> with the specified priority (0 \= low, 1 \= medium, 2 \= high)  
   8. nice\_pid \<priority\> \<pid\>: changes the priority of the process with the given PID.  
   9. kill \[-term|-stop|-cont\] \[\<pid\>...\]: send signals to one or more processes, typically to terminate, stop (suspend), or continue (resume) them

3. PennFAT File System  
   1. Implemented file system structure and manipulation functions   
   2. Created file descriptor structure and manipulation functions  
   3. Created file directory structure and manipulation functions   
   4. Developed kernel functions to interact with the fs structures  
   5. Implemented routines that allow the user to interact with the filesystem via abstraction   
   6. Implemented basic shell for users to make and interact with the filesystem that included signal handling for pennfat (SIGINT, SIGSTP)

### Description of code and code layout

Scheduler

1. kernel.c/kernel.h \- This is a file that is used to represent the kernel-level process management of PennOS. It has the essential functions for managing the state and running of processes at the singular process level. k\_proc\_create is used to initialize the process control blocks (PCB). Here, the fields of the process control block are initialized to default values depending on the input to k\_proc\_create. Process creation also involves thread creation, and it controls the addition of the process to the PennOS scheduler environment, which means the enqueuing of the process into the priority queue. Similarly,  k\_proc\_cleanup, k\_proc\_block, k\_proc\_unblock, and k\_proc\_kill all help manage the priority queue enqueuing and dequeuing of the process that is passed into them. This allows for more local control of the scheduler environment depending on the action being performed on a process. These two files are also in charge of the initialization of special processes such as the init process and the shell process through k\_init and k\_shell. The kernel file is also in charge of managing the allocation and reallocation of children in case of orphaning through k\_orphan\_children.  
2. scheduler.c/scheduler.h \- This is a file that specifically manages the round-robin priority scheduler functionality. This is where the time-keeping framework and the time-quantum-based operation of the scheduler are implemented. Here, a clock handler function is created that calls the clock.c and clock.h, which implement the clock ticks. The scheduler.c is also where all the other time-quantum-based functions are located, such as scheduling, checking on the sleeping process, idling, reaping completed background job processes, and handling the signals (since some spthread functions are not signal safe).  
3. clock.c/clock.h \- This is a helper function file that implements a timing mechanism that generates a SIGALRM signal every 100 milliseconds, which will be used by the scheduler as a measurement for the transition between each time quantum.  
4. user.c/user.h \- This file implements user-facing utility commands and test routines for the shell environment. These functions provide process management utilities and system testing tools intended to demonstrate kernel features such as process creation, process states, zombie/orphan handling, and sleeping.  
5. queue.c/queue.h / Vec.c/Vec.h \- queue.c is a helper function file that is used to help implement the functionalities for every queue-like data structure involved in the scheduler side of PennOS. This helper function file uses the vector data structure created in Vec.c to help create and operate on the queues. The first type of data structure created here is a single-level queue. These queues are used in children queues, such as the alive children, zombie children, and waitable children queues to help keep track of the state of multiple children per parent process. The second type of data structure created here is the triple-level queue used as the priority queue, which has a special helper function to aid in the traversal of the priority queue as well as the enqueuing and dequeuing of processes.  
6. job.c/job.h \- This file implements the job control for the shell, providing mechanisms for tracking, managing, and updating the state of jobs (groups of related processes). This enables features like background and foreground execution and job cleanup.  
7. p\_errno.c/p\_errno.h \- This error reporting file is similar to the standard C errno and perror mechanisms. When a function encounters an error, it sets the global P\_ERRNO variable to the appropriate error code. The user-level code can then print a helpful error message to make sure that user-level and system-level utilities have a standard way to report errors.

PennFat

1. pennfat.c/pennfat.h \- Shell code that allows users to interact with the filesystem via routines  
2. routines.c/routines.h \- Functions that allow the user to interact and manipulate the mounted\_fs (mkfs, unmount, mount, touch, mv, rm, cp, cat, chmod, ls, str\_to\_perms)  
3. kernel\_fs.c/kernel\_fs.h \- Contains kernel functions that interact and manipulate the filesystem structures  (k\_write, k\_read, k\_open, k\_close, k\_unlink, k\_lseek, k\_chmod, k\_ls, k\_rename\_file, k\_get\_perms)  
4. dir.c/dir.h \- Contains functions that create root directory structure and manipulate it (mkdir, parse\_dir, commit\_dir, new\_dirent, free\_dir, dir\_len, dir\_get, dir\_data)  
5. fd.c/fd.h \- Contains functions that create a file descriptor table and functions that interact with the table (new\_fdt, free\_fdt, new\_fd, get\_fd, close\_fd, fdt\_len, fdt\_data)  
6. fs.c/fs.h \- Contains functions that create a new file system structure and manipulate it (new\_fs, free\_fs, fat\_next, fat\_expand\_file, fat\_free\_file, get\_block, free\_block)

Integration

1. pennos.c/pennos.h \- Here is where the main function that initializes and starts PennOS resides. This file is also where the shell subroutines are placed, as well as information about all the potential commands. This is also where the command parser is called, as well as command execution. For the FAT side, this file includes setting up the user-inputted file system name and running builtins to interact with the filesystem  
2. system.c/system.h \- For the scheduler side, system.c contains all the essential functions for the management of process life cycle as well as parent process/child process relationships. There is s\_spawn, which is used to spawn a child process from a calling current process that will become the parent. There is also s\_kill, which helps manage the types of signals. In addition, there is the s\_exit function, which is used to regulate what happens to a process when it exits. In this file, there are also helper functions for job control to better see what individual processes in the jobs look like. There are also the crucial functions and helper functions related to s\_waitpid, which manage the steps needed to wait on and reap waitable child processes. For the FAT side, system.c is an abstraction of kernel functions to interact with PennFAT and integrate with process structure (s\_open, s\_read, s\_write, s\_close, s\_unlink, s\_lseek, s\_ls, s\_chmod, s\_get\_permissions, get\_current\_process\_fdt).
3. Builtins.c/Builtins.h \- Functions that allow the user to do file manipulation with the mounted FS
