CS 416 - Operating System Design: The saga continues, this time Chris and Mike learn about operating systems.
Program that uses a signal handler to recover from a segmentation fault.
+ +
| . |
| . |
| . |
+--------------+
| Instruction |
|return address|
&signum + 0xCC +--> +--------------+
| . |
| . |
| . |
| . |
+--------------+
| signum |
&signum +--> +--------------+
Using the signal variable sent to our signal handler, we can traverse up the stack and edit the return address to the instruction that we failed on.
Program that calls finds the average time of a system call. This average is calculated by doing a system call > 1000 times. Result is in microseconds.
Program that simply spins up two seperate threads, and uses mutexes to
increment a shared global variable to an inputted amount.
E.g. ./threads 10 will increment a global variable to 10 then exit.
A simple thread library implemented at the user level using two different types of queues.
Round robin holds a pointer to a current task and simply goes around a list picking up the next task to run.
task_1<----task_4
| ^
| |
v |
running---> task_2---->task_3
MLFQ uses multiple queues within an array. The lower the value of the queue number the higher the priority of the task, and they are run first. If there are multiple tasks in a queue to be run, they run in round robin. Once they stop or become blocked, the queue goes to lower levels and runs those tasks.
+------------------+
| |
|1->task_1 |
| |
|2->task_2->task_3 |
| |
|3-> |
| |
|4->task_4 |
| |
+------------------+
Malloc library that allocates memory in pages. Simulates memory allocation at the OS level.
Our memory allocation table uses a multi level page table in a simulated 32-bit system. Therefore:
32-bit addresses
# bits for offset in a page = log_2(PAGE_SIZE)
# bits for page table index = log_2(PAGE_SIZE) / sizeof(page_table_entry)
# bits for page directory index = 32 - (# page table bits) - (# offset bits)
With this setup when a user requests, for example 8192 bytes and 4096 byte pages, we allocate them two full pages and make two valid entries in the page table. Also, if we want to read or write to the pages we use:
put_value(virt_addr, value, size)
get_value(virt_addr, buffer, size)
We use the above functions because since we return a virtual address to the user they
cannot directly do *ptr = 3, instead we use put_value()
to edit memory.
int *ptr;
int x = 3, y;
ptr = a_malloc(sizeof(int));
/* Put 3 into the location that ptr points to */
put_value(ptr, &x, sizeof(int));
/* If we get the value from the ptr and store it in y, y = 3 */
get_value(ptr, &y, sizeof(int));
Implemented a tiny file system using FUSE.
To mount the filesystem, compile and run the filesystem on the desired mount point.
$ make
$ ./tfs -s [mount point]
Once the filesystem is mounted, you can use it as if it was any other filesystem.
Simple command line programs like mkdir
, touch
, rmdir
, and more work as expected.
Also, a file named DISKFILE
will be created which contains all the contents of
the filesystem.
To unmount the filesystem you can perform:
$ fusermount -u [mount point]
If you want to completely reset and clear the file system, simply delete
DISKFILE
that is created.