Overview

The first project is to build a basic shell that serves as a multi-core process queue called pqsh. This program allows the user to enter in a series of commands and then schedules the specified jobs to run on multiple CPU cores as separate processes.

As shown above, the process queue shell has a queue of running jobs (ie. tasks that are actively assigned CPU time), and a queue of waiting jobs (ie. tasks that haven't started yet or have been preempted). Its purpose is to schedule as many running jobs as there are CPU cores using either the FIFO or Round Robin scheduling policies.

Unlike a regular shell, commands in pqsh are not executed right away. Instead, new jobs are added to a waiting queue, where they will be processed by an internal scheduling policy such as FIFO or Round Robin. When there are available resouces (ie. CPUs), the scheduler will move the job from the waiting queue to the running queue. When the job terminates, it will then move to the finished queue.

Working individually or in pairs, you are to utilize low-level system calls to create this pqsh shell by noon on Saturday, August 29, 2020. More details about this project and your deliverables are described below.

Commands

To interact with the shell, the user has access to two commands:

  1. add COMMAND: This command adds the specified COMMAND as a job to the shell's internal waiting queue.

  2. status [QUEUE]: This command displays metrics from the internal scheduler (ie. number of jobs in each queue, average turnaround time, and average response time), including the jobs in each of the internal running, waiting, and finished queues (if a QUEUE is specified then only that queue is displayed, otherwise all queues are shown).

Scheduling

The order in which jobs should be executed is determined by one of the following scheduling policies:

  1. FIFO: Execute jobs in the order in each they arrival in the process queue.

  2. Round Robin: Execute jobs in a round robin fashion.

You must implement both scheduling disciplines along with any accounting and preemption mechanisms required to build these algorithms.

Pseudo-Solutions

This project relates directly to our discussion on schedulers. Refer to your textbook, Operating Systems: Three Easy Pieces and the slides on scheduling: Scheduling (FIFO, Round Robin) and Scheduling (MLFQ, Lottery).

Usage

The full set of pqsh command-line options are shown below:

$ bin/pqsh -h
Usage: ./bin/pqsh [options]

Options:
    -n CORES           Number of CPU cores to utilize
    -p POLICY          Scheduling policy (fifo, rdrn)
    -t MICROSECONDS    Timer interrupt interval
    -h                 Print this help message

The number of CPU CORES and the scheduling POLICY can be specified by the user when the shell is started, but cannot change once it is active. By default, the shell assumes one core and the FIFO scheduling policy.

Here is an example of pqsh running one command using the FIFO scheduler on one CORE:

$ bin/pqsh

PQSH> help
Commands:
  add    command    Add command to waiting queue.
  status [queue]    Display status of specified queue (default is all).
  help              Display help message.
  exit|quit         Exit shell.

PQSH> add bin/worksim 10
Added process "bin/worksim 10" to waiting queue.

PQSH> status
Running =    1, Waiting =    0, Finished =    0, Turnaround =  -nan, Response =  -nan

Running Queue:
  PID COMMAND                        ARRIVAL       START         END
10071 bin/worksim 10                 1568055878.75 1568055878.95          0.00

PQSH> status
Running =    0, Waiting =    0, Finished =    1, Turnaround = 10.00, Response = 00.00

Finished Queue:
  PID COMMAND                        ARRIVAL       START         END
10071 bin/worksim 10                 1568055878.75 1568055878.95 1568055889.19

Here is a video example using of pqsh and the output of its test programs:

Reference Implementation

You can find a reference implementation of pqsh in the following location on the student machines:

/escnfs/home/pbui/pub/bin/pqsh

Feel free to play around with this in order to explore how pqsh should behave.

Balancing the Load

While it is unlikely that you will write an operating system scheduler in your career, you may need to implement or at least interact with things like load balancers or batch queues, especially in parallel or distributed environments such as the cloud.

For instance, many websites use Cloudflare which performs load balance to prevent denial-of-service attacks. Similarly, the CRC uses systems such as HTCondor to schedule many jobs on the distributed computing cluster at Notre Dame. In both of these situations some decision making is required to map jobs to a particular set of resources.

This project will allow to explore the challenges in this type of decision making by having you implementing and test different types of scheduling policies for a process queue.

Deliverables

As noted above, you are to work individually or in pairs to implement pqsh. You must use (C99) (not C++) as the implementation language for pqsh itself, while any test scripts are to be written in any reasonable scripting language.

Timeline

Here is a timeline of events related to this project:

Date Event
Sunday, August 09 Project description and repository are available.
Sunday, August 23 Brainstorming should be completed.
Saturday, August 29 Implementation of pqsh must be completed.

Final Submission

For the final submission, please open a Pull Request on your repository (for your pqsh branch to the master branch) and assign it to your grader from the Reading 03 TA List.

Repository

To start this project, you must create a Project 01 repository on GitHub using the following template:

https://classroom.github.com/g/PtopWGks

Note: Do your work in a separate git branch that can be later merged into the master branch (ie. make a pqsh branch, DO NOT COMMIT OR MERGE TO MASTER).

Documentation

The Project 01 repository includes a README.md file with the following sections:

  1. Students: This should be your name and email address.

  2. Brainstorming: This contains questions that should help you design and plan your approach to the project. You do not need to fill these out, but they are meant to be helpful.

  3. Errata: This should contain a description of any known errors or deficiencies in your implementation.

You must complete this document report as part of your project.

Source Code

As you can see, the base Project 01 repository contains a README.md file and the following folder hierarchy:

project01
    \_ Makefile     # This is the project Makefile
    \_ bin          # This contains the executables
    \_ include      # This contains the header files
    \_ lib          # This contains the libraries
    \_ src          # This contains the C99 source code
    \_ tests        # This contains test scripts and source code

You must maintain this folder structure for your project and place files in their appropriate place.

K.I.S.S.

While the exact organization of the project code is up to you, keep in mind that you will be graded in part on coding style, cleaniness, and organization. This means your code should be consistently formatted, not contain any dead code, have reasonable comments, and appropriate naming among other things:

Please refer to these Coding Style slides for some tips and guidelines on coding style expectations.

Compiling

To help you get started, we have provided a Makefile that will build the pq application for you:

$ make                      # Build pq executable
Compiling src/pqsh.o
Compiling src/options.o
Compiling src/process.o
Compiling src/queue.o
Compiling src/signal.o
Compiling src/scheduler.o
Compiling src/scheduler_fifo.o
Compiling src/scheduler_rdrn.o
Compiling src/timestamp.o
Linking lib/libpqsh.a
Linking bin/pqsh

Running

Once you have the pqsh executable, you can run the shell with different number of CORES or with a different scheduling POLICY:

$ ./bin/pqsh -p fifo        # Run shell with FIFO policy

$ ./bin/pqsh -p rdrn -n 2   # Run shell with Round Robin policy and two cores

To help you test your process queue, the bin/worksim script is provided to you. This script is a workload simulator and uou can use it to create a job that simulates a job that runs for a specified duration. For example, to create a job that runs for 10 seconds:

$ ./bin/worksim 10

This script will be useful for testing the different scheduling policies.

Implementation

All of the C99 header files are in the include/pq folder while the C99 source code is contained in the src directory. To help you get started, parts of the project are already implemented:

[x] options.c               # PQSH parsing options (implemented)
[~] pqsh.c                  # PQSH main executable (partially implemented)
[ ] process.c               # PQSH process structure (not implemented)
[ ] queue.c                 # PQSH queue structure (not implemented)
[ ] scheduler.c             # PQSH scheduler structure (not implemented)
[ ] scheduler_fifo.c        # PQSH FIFO scheduler policy (not implemented)
[ ] scheduler_rdrn.c        # PQSH Round Robin scheduler policy (not implemented)
[~] signal.c                # PQSH signal handlers (partially implemented)
[ ] timestamp.c             # PQSH timerstamp (not implemented)

Basically, some of pqsh shell code, signal utilities, and command-line parsing functions are provided to you, but the scheduling and process management functions are not. Each of the functions in the incomplete files above have comments that describe what needs to be done.

You will need to examine these source files and complete the implementation of the shell. To do so, you will first need to implement a basic Process structure and a corresponding Queue structure:

Hints

Here are some hints to help you get started with the project:

Testing

To verify the correctness of the Process, Queue, and timestamp functions, three test programs are provided:

$ make test-units

Testing test_process

Testing test_queue

Testing test_timestamp

Likewise, to verify the behavior of your pqsh shell, we have provided you a series of test scripts:

$ make test-scripts

Testing test_fifo_checklist ...
Running PQSH commands ... SUCCESS
Verifying PQSH output ... SUCCESS
Verifying PQSH memory ... SUCCESS

Testing test_fifo_multicore ...
Running PQSH commands ... SUCCESS
Verifying PQSH output ... SUCCESS
Verifying PQSH memory ... SUCCESS

Testing test_fifo ...
Running PQSH commands ... SUCCESS
Verifying PQSH output ... SUCCESS
Verifying PQSH memory ... SUCCESS

Testing test_rdrn_checklist ...
Running PQSH commands ... SUCCESS
Verifying PQSH output ... SUCCESS
Verifying PQSH memory ... SUCCESS

Testing test_rdrn_multicore ...
Running PQSH commands ... SUCCESS
Verifying PQSH output ... SUCCESS
Verifying PQSH memory ... SUCCESS

Testing test_rdrn ...
Running PQSH commands ... SUCCESS
Verifying PQSH output ... SUCCESS
Verifying PQSH memory ... SUCCESS

Note, you can always run a specific test directory:

$ ./tests/test_fifo.sh      # Run FIFO test script

If necessary, you should not hesitate in create your own additional test programs or scripts to facilitate verification and debugging.

Reflection

To reflect on the project and the concepts involved, you will need to create a group video demonstration of your software artifact and complete an individual quiz (each member will submit their own answers to their own private assignments repository).

Video Demonstration

As part of your grade, your group will need to create a video that demonstrates and discusses the following:

  1. Your project passing the automated tests.

  2. Your project working with manual input.

  3. Any errata, quirks, or unresolved issues in your project.

  4. What you learned by doing this project.

The video should include narration to describe what is being presented and should cover the requirements enumerated above. It should be no longer than 5 minutes.

Please upload the video to either YouTube or Google Drive and provide a link to it in your README.md.

Individual Quiz

Once you have completed the project, answer the following Project 01 Quiz questions individually in your own personal assignments repository on GitHub:

The results of the quiz should look like the following:

Submitting project01 assignment ...
Submitting project01 quiz ...
      Q1 0.40
      Q2 0.40
      Q3 0.40
      Q4 0.50
      Q5 0.90
      Q6 1.40
   Score 4.00

Assignments Repository

Each group member should do the quiz on their own and record their answers in the project01 folder in their assignments GitHub repository.

Grading

Your project will be graded on the following metrics:

Metric Points
Source Code
  1. General
    • Builds and cleans without warnings or errors
    • Uses system calls appropriately
    • Manages resources such as memory and files appropriately
    • Is consistent, readable, and organized
    • Has regular commits and submitted on-time.

  2. Structures / Functions
    • Implements Process structure properly.
    • Implements Queue structure properly.
    • Implements Timestamp function properly.

  3. Scheduler
    • Implements Add command properly.
    • Implements Status command properly.
    • Implements Wait function properly.
    • Implements Timer behavior properly.
    • Implements FIFO scheduler behavior properly.
    • Implements RDRN scheduler behavior properly.
22.0
  1. 4.5
    • 0.5
    • 1.0
    • 1.0
    • 1.0
    • 1.0

  2. 6.5
    • 2.0
    • 4.0
    • 0.5

  3. 11.0
    • 1.0
    • 1.0
    • 2.0
    • 1.0
    • 2.0
    • 4.0
Reflection
  1. Group Video Demonstration
    • Exhibits reasonable audio and video quality
    • Demonstrates passing automated tests
    • Demonstrates working with manual input
    • Discusses errata, quirks, or unresolved issues
    • Discusses what the group learned from the project

  2. Individual Quiz
8.0
  1. 4.0
    • 0.50
    • 1.00
    • 1.00
    • 0.75
    • 0.75

  2. 4.0

Commit History

To encourage you to work on the project regularly (rather than leaving it until the last second) and to practice performing incremental development, part of your grade will be based on whether or not you have regular and reasonably sized commits in your git log.

That is, you will lose a point if you commit everything at once near the project deadline.

Error Handling

In addition to meeting the functional requirements of the project (as described above), your program must not exhibit any memory leaks or invalid memory accesses as would be detected by Valgrind.

Additionally, because system calls can fail, your program must implement robust error handling and ensure your code checks the status of system calls when reasonable.

Moreover, you code must compile without any warnings (and -Wall must be one of the CFLAGS).