- Operating System Lab Projects F2023
In these projects, some features were added to the xv6 operating system (x86 architecture).
The name of group members appears as message when the system boots up:
The following keyboard shortcuts are added to the console:
Ctrl+N
: Removes all the digits from the consoleCtrl+R
: Reverses the current lineTab
: Substitutes the current line with a command from the history (if exists)Ctrl+B
: Moves the cursor one character to the leftCtrl+F
: Moves the cursor one character to the rightCtrl+L
: Clears the consoleArrow Up
: Shows the previous command in the historyArrow Down
: Shows the next command in the history
A strdiff
program is added to the system.
This program finds the difference between two strings.
The program is called as follows:
strdiff a b
The result is then printed in the strdiff_result.txt
file.
The find_digit_root
system call is added to the system.
This system call finds the largest prime factor of a given number.
The system call is called as follows:
int find_digit_root(void);
The parameter (an integer) should be passed in the ebx
register.
- The
copy_file
system call is added to the system.
This system call copies a file to another location.
int copy_file(char *path, int size);
- The
get_uncle_count
system call is added to the system.
This system call returns the number of uncle processes of the current process.
void get_uncle_count(void);
- The
get_process_lifetime
system call is added to the system.
This system call returns the lifetime of the current process.
int get_process_lifetime(void);
An MLFQ scheduler is added to the system.
The scheduler has 3 queues with the first one having the highest priority.
The following queueing policies are used:
- The first queue is a round-robin queue with a time quantum of 1 tick.
- The second queue is LCFS (Last-Come-First-Served) which means the process that came last is executed first.
- The third queue is a BJF (Best-Job-First) queue in which the process with the lowest rank is executed.
All processes are started in the second queue (except the init
and sh
processes).
If a runnable process has not been executed for 8000 ticks, it is moved to the first queue.
The following system calls are added to the system:
change_scheduling_queue
: Changes the scheduling queue of a process.
int change_scheduling_queue(int pid, int queue);
set_bjf_params_process
: Sets the parameters of the BJF algorithm for a process.
int set_bjf_params_process(int pid, float priority_ratio, float arrival_time_ratio, float executed_cycles_ratio);
set_bjf_params_system
: Sets the parameters of the BJF algorithm for the system.
int set_bjf_params_system(float priority_ratio, float arrival_time_ratio, float executed_cycles_ratio);
print_process_info
: Prints the information of processes in a table.
void print_process_info(void);
All of the aforementioned system calls are accessible using the schedule
user program:
usage: schedule command [arg...]
Commands and Arguments:
info
set_queue <pid> <new_queue>
set_process_bjf <pid> <priority_ratio> <arrival_time_ratio> <executed_cycle_ratio>
set_system_bjf <priority_ratio> <arrival_time_ratio> <executed_cycle_ratio>
set_priority_bjf <pid> <priority>
As a part of the synchronization experiment, the number of system calls is counted. First we make sure to run the operating system on 4 cores, then we run the getnsyscalls
program. The program is called as follows:
int getnsyscalls();
This result of counting number of system calls in each core and summation of them is printed to the console. To make sure that the system calls are counted correctly, we used spin locks to prevent any process from being interrupted while counting the system calls.
A priority lock is added to the system. It follows the spin lock policy. The following system calls are added to the system:
void acquirepriority(struct prioritylock* lk);
void releasepriority(struct prioritylock* lk);
The prioritylock
structure is defined as follows:
struct prioritylock {
uint locked; // Is the lock held?
struct spinlock lk; // spinlock protecting this priority lock
int inqueue; // number of processes waiting in queue
int lockreq[NPROC]; // pid of processes which requested priority lock
int pid; // Process holding lock
char* name; // Name of lock
};
Then for testing the priority lock, we used the prio
user program. The program is called as follows:
prio
The program creates 10 processes and each process tries to acquire the priority lock. The process with the highest priority should be able to acquire the lock first. The process with the lowest priority should be able to acquire the lock last. The program prints the order of the processes that acquired the lock to the console.
In this experiment, A shared memory system is added to the system. shpage
and shmemtable
were added for managing the shared memory also the following system calls are added to the system to interact with them, each process stores its shared memory in the shmemtable
and the shpage
is used to manage the shared memory.
char* openshmem(int id);
int closeshmem(int id);
To test the shared memory system, we used the shmem_test
user program. It creates multiple process and each process changes the value of a shared memory and prints the value of the shared memory to the console. The program is called as follows:
shmem_test