diff --git a/README.md b/README.md index 088b126..d0aa584 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,24 @@ + # Lab 6 In this lab, you will gain familiarity with many concepts pertinent to operating systems and C programming: -* Linked list data structure -* OS scheduling algorithms - * First come first served (FCFS) - * Priority queue - * Priority value is used by the scheduling algorithm to determine which tasks to focus on first. - * For example, an OS would likely give high priority to I/O operations because it's important that the CPU reacts as soon as you type a key. - * A long download may have low priority. - * Round robin -* C structs -* Pointers -* Memory allocation and deallocation +- Linked list data structure +- OS scheduling algorithms + - First come first served (FCFS) + - Priority queue + - Priority value is used by the scheduling algorithm to determine which tasks to focus on first. + - For example, an OS would likely give high priority to I/O operations because it's important that the CPU reacts as soon as you type a key. + - A long download may have low priority. + - Round robin +- C structs +- Pointers +- Memory allocation and deallocation In particular, this lab's goals are -1. Become familiar with the `task_struct` that is used by the OS to manage a program running in memory. Here, we'll use only a subset of fields found in the real Linux `task_struct`, namely the *process id* (pid) and *priority*. If interested, you can view the Linux kernel's real `task_struct` in the [sched.h](https://github.com/torvalds/linux/blob/master/include/linux/sched.h) header file distributed in the newest [Linux kernel code](https://github.com/torvalds/linux). Typically, the pid and priority values are assigned by the OS, but in this lab, you'll simulate this OS operation by manually assigning values to the `task_struct` fields. +1. Become familiar with the `task_struct` that is used by the OS to manage a program running in memory. Here, we'll use only a subset of fields found in the real Linux `task_struct`, namely the _process id_ (pid) and _priority_. If interested, you can view the Linux kernel's real `task_struct` in the [sched.h](https://github.com/torvalds/linux/blob/master/include/linux/sched.h) header file distributed in the newest [Linux kernel code](https://github.com/torvalds/linux). Typically, the pid and priority values are assigned by the OS, but in this lab, you'll simulate this OS operation by manually assigning values to the `task_struct` fields. 2. Gain experience with **singly linked list** in C (code provided), one of the fundamental data structures used in operating systems (and in general). Each element in the linked list is a `task_struct`. A linked list is a suitable data structure choice because of its efficient use of memory and $O(1)$ queue operations (enqueue and dequeue) and stack operations (push and pop). However, a linked list has some disadvantages that you'll soon recall or become familiar with. 3. Simulate **priority queue**, **first come first serve** (**FCFS**) and **round robin** scheduling algorithms. @@ -25,13 +26,13 @@ In particular, this lab's goals are Contents - [Pre-lab knowledge](#pre-lab-knowledge) - - [Background reading](#background-reading) - - [Structure](#structure) + - [Background reading](#background-reading) + - [Structure](#structure) - [Part 0: Understand starter code](#part-0-understand-starter-code) - [Part 1. Min heapify](#part-1-min-heapify) - - [Testing](#testing) + - [Testing](#testing) - [Part 2. Scheduling algorithms](#part-2-scheduling-algorithms) - - [Testing](#testing-1) + - [Testing](#testing-1) - [Submit your assignment](#submit-your-assignment) @@ -40,19 +41,19 @@ In particular, this lab's goals are ### Background reading -* For linked lists and list operations, [Linked List Basics](http://cslibrary.stanford.edu/103/LinkedListBasics.pdf) -* For a review of binary heaps and the heapify algorithm, [Heaps.pdf](Heaps.pdf) included in this repo -* For a few OS scheduling algorithms, [OSTEP Chapter 7](https://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched.pdf) -* C concepts: - * For how header files work in C, chapter 4.5 in *The C Programming Language* - * For pointers, memory allocation, and deallocation, chapter 5 in *The C Programming Language* - * For information about structs, chapter 6 in *The C Programming Language* +- For linked lists and list operations, [Linked List Basics](http://cslibrary.stanford.edu/103/LinkedListBasics.pdf) +- For a review of binary heaps and the heapify algorithm, [Heaps.pdf](Heaps.pdf) included in this repo +- For a few OS scheduling algorithms, [OSTEP Chapter 7](https://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched.pdf) +- C concepts: + - For how header files work in C, chapter 4.5 in _The C Programming Language_ + - For pointers, memory allocation, and deallocation, chapter 5 in _The C Programming Language_ + - For information about structs, chapter 6 in _The C Programming Language_ ### Structure Here is a description of each file and what you are expected to do (if anything) in each: -```text +``` . ├── Heaps.pdf - Background reading about heaps ├── Makefile @@ -92,7 +93,7 @@ Run `make`, then run the program with `./main`. The `main` function accepts input from `stdin` and outputs to `stdout` (no CLI args). An example run is as follows: ```text -Number of tasks: 4 +Number of tasks: 4 pid priority cycles: 12 50 100 pid priority cycles: 13 1 80 pid priority cycles: 14 40 60 @@ -119,11 +120,11 @@ For the scheduling algorithms, pseudocode is provided in `schedule.h`. Additiona In `schedule.c`, implement the following functions: -* `run_to_completion` -* `run_with_quantum` -* `fcfs` -* `priority_queue` -* `round_robin` +- `run_to_completion` +- `run_with_quantum` +- `fcfs` +- `priority_queue` +- `round_robin` ### Testing diff --git a/out.txt b/out.txt new file mode 100644 index 0000000..3cef0f8 --- /dev/null +++ b/out.txt @@ -0,0 +1,5 @@ +Number of tasks: pid priority cycles: pid priority cycles: pid priority cycles: pid priority cycles: pid priority cycles: pid priority cycles: pid priority cycles: ---- Tasks ---- +(num_tasks) [pid:priority:cycles:priority/cycles ...] +(7) [ 1:5:10:0.50 2:16:17:0.94 3:8:24:0.33 4:1:36:0.03 5:99:100:0.99 6:1:62:0.02 0:26:80:0.32 ] +Select scheduling algorithm (0: Display min heap, 1: FCFS, 2: Priority queue, 3: Round robin): ---- Min heap ---- +(7) [ 6:1:62:0.02 4:1:36:0.03 0:26:80:0.32 2:16:17:0.94 5:99:100:0.99 3:8:24:0.33 1:5:10:0.50 ] diff --git a/task.c b/task.c index ee26252..a35947c 100644 --- a/task.c +++ b/task.c @@ -170,10 +170,50 @@ bool swap(unsigned int pid_1, unsigned int pid_2) { return true; } -void min_heapify() { - // TODO: +void heapify(int i) { + bool done = false; + int k = i; + + while (!done && (2 * k + 1) < size()) { + int j = 2 * k + 1; + + + if (j + 1 < size()) { + // two children + + task_struct *left = get_task(j); + task_struct *right = get_task(j + 1); + + float left_ratio = (float)left->priority / (float)left->remaining_cycles; + float right_ratio = (float)right->priority / (float)right->remaining_cycles; + + if (right_ratio < left_ratio) { + j++; + } + } + + task_struct *curr = get_task(k); + task_struct *next = get_task(j); + + float curr_ratio = (float)curr->priority / (float)curr->remaining_cycles; + float next_ratio = (float)next->priority / (float)next->remaining_cycles; + + if (curr_ratio > next_ratio) { + swap(curr->pid, next->pid); + k = j; + } else { + done = true; + } + } } +void min_heapify() { + for (int i = floor((size() - 2) / 2); i >= 0; i--) { + heapify(i); + } +} + + void print_tasks() { // DO NOT MODIFY task_struct* p_task = head;