From 48c6ca4a774c521220718bac39d5162141eb4403 Mon Sep 17 00:00:00 2001 From: "Fareen. L" Date: Fri, 7 Nov 2025 21:32:52 -0500 Subject: [PATCH] Simulation Code added and tested with 3 test cases Signed-off-by: Fareen. L --- .idea/.gitignore | 8 + .idea/dictionaries/project.xml | 10 + .idea/editor.xml | 344 ++++++++++++++++++ .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/part3.iml | 2 + .idea/vcs.xml | 6 + CMakeLists.txt | 14 + .../device_table.txt | 0 .../external_files.txt | 0 input_files/external_files_case1.txt | 1 + input_files/external_files_case2.txt | 2 + input_files/trace.txt | 6 + input_files/trace_case1.txt | 1 + input_files/trace_case2.txt | 7 + .../vector_table.txt | 0 interrupts.cpp | 165 +++++++-- interrupts.hpp | 83 +++-- output_files/execution.txt | 28 ++ output_files/execution_case1.txt | 6 + output_files/execution_case3.txt | 28 ++ output_files/program_child.txt | 3 + output_files/program_large.txt | 3 + output_files/program_parent.txt | 3 + .../sysc4001_a2_p3_report_flavji543.pdf | Bin 0 -> 35234 bytes output_files/system_status.txt | 19 + output_files/system_status_case1.txt | 6 + output_files/system_status_case2.txt | 19 + 28 files changed, 705 insertions(+), 74 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/dictionaries/project.xml create mode 100644 .idea/editor.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/part3.iml create mode 100644 .idea/vcs.xml create mode 100644 CMakeLists.txt rename device_table.txt => input_files/device_table.txt (100%) rename external_files.txt => input_files/external_files.txt (100%) create mode 100644 input_files/external_files_case1.txt create mode 100644 input_files/external_files_case2.txt create mode 100644 input_files/trace.txt create mode 100644 input_files/trace_case1.txt create mode 100644 input_files/trace_case2.txt rename vector_table.txt => input_files/vector_table.txt (100%) create mode 100644 output_files/execution.txt create mode 100644 output_files/execution_case1.txt create mode 100644 output_files/execution_case3.txt create mode 100644 output_files/program_child.txt create mode 100644 output_files/program_large.txt create mode 100644 output_files/program_parent.txt create mode 100644 output_files/sysc4001_a2_p3_report_flavji543.pdf create mode 100644 output_files/system_status.txt create mode 100644 output_files/system_status_case1.txt create mode 100644 output_files/system_status_case2.txt diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml new file mode 100644 index 0000000..23ddc98 --- /dev/null +++ b/.idea/dictionaries/project.xml @@ -0,0 +1,10 @@ + + + + endio + intr + iret + sasisekhar + + + \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..963c96f --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,344 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b76fe5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..97dfc80 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/part3.iml b/.idea/part3.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/part3.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6207bf9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 4.0) +project(part3) + +set(CMAKE_CXX_STANDARD 14) + +include_directories(.) + +add_executable(part3 + build.sh + device_table.txt + external_files.txt + interrupts.cpp + interrupts.hpp + vector_table.txt) diff --git a/device_table.txt b/input_files/device_table.txt similarity index 100% rename from device_table.txt rename to input_files/device_table.txt diff --git a/external_files.txt b/input_files/external_files.txt similarity index 100% rename from external_files.txt rename to input_files/external_files.txt diff --git a/input_files/external_files_case1.txt b/input_files/external_files_case1.txt new file mode 100644 index 0000000..75aa6db --- /dev/null +++ b/input_files/external_files_case1.txt @@ -0,0 +1 @@ +program_large 120 \ No newline at end of file diff --git a/input_files/external_files_case2.txt b/input_files/external_files_case2.txt new file mode 100644 index 0000000..a5161c3 --- /dev/null +++ b/input_files/external_files_case2.txt @@ -0,0 +1,2 @@ +program_child 10 +program_parent 25 \ No newline at end of file diff --git a/input_files/trace.txt b/input_files/trace.txt new file mode 100644 index 0000000..83dcfe4 --- /dev/null +++ b/input_files/trace.txt @@ -0,0 +1,6 @@ +FORK, 10 +IF_CHILD, 0 +EXEC program1, 50 +IF_PARENT, 0 +EXEC program2, 25 +ENDIF, 0 \ No newline at end of file diff --git a/input_files/trace_case1.txt b/input_files/trace_case1.txt new file mode 100644 index 0000000..a4ba667 --- /dev/null +++ b/input_files/trace_case1.txt @@ -0,0 +1 @@ +EXEC program_large \ No newline at end of file diff --git a/input_files/trace_case2.txt b/input_files/trace_case2.txt new file mode 100644 index 0000000..b3e90f2 --- /dev/null +++ b/input_files/trace_case2.txt @@ -0,0 +1,7 @@ +FORK +IF_CHILD +EXEC program_child +ENDIF +IF_PARENT +EXEC program_parent +ENDIF \ No newline at end of file diff --git a/vector_table.txt b/input_files/vector_table.txt similarity index 100% rename from vector_table.txt rename to input_files/vector_table.txt diff --git a/interrupts.cpp b/interrupts.cpp index e2f2722..0129211 100644 --- a/interrupts.cpp +++ b/interrupts.cpp @@ -7,18 +7,18 @@ #include -std::tuple simulate_trace(std::vector trace_file, int time, std::vector vectors, std::vector delays, std::vector external_files, PCB current, std::vector wait_queue) { +std::tuple simulate_trace(std::vector trace_file, int time, const std::vector& vectors, std::vector delays, const std::vector& external_files, PCB current, const std::vector& wait_queue) { std::string trace; //!< string to store single line of trace file - std::string execution = ""; //!< string to accumulate the execution output - std::string system_status = ""; //!< string to accumulate the system status output + std::string execution; //!< string to accumulate the execution output + std::string system_status; //!< string to accumulate the system status output int current_time = time; - //parse each line of the input trace file. 'for' loop to keep track of indices. + // parse each line of the input trace file. 'for' loop to keep track of indices. for(size_t i = 0; i < trace_file.size(); i++) { - auto trace = trace_file[i]; + const auto& trace_line = trace_file[i]; - auto [activity, duration_intr, program_name] = parse_trace(trace); + auto [activity, duration_intr, program_name] = parse_trace(trace_line); if(activity == "CPU") { //As per Assignment 1 execution += std::to_string(current_time) + ", " + std::to_string(duration_intr) + ", CPU Burst\n"; @@ -49,14 +49,51 @@ std::tuple simulate_trace(std::vector(current.PID); + child.PID = current.PID + 1; // simple PID policy: next integer + + // Allocate memory for child program (same size and program name) + bool allocated = allocate_memory(&child); + if(!allocated) { + execution += std::to_string(current_time) + ", 1, fork failed: no memory for child\n"; + current_time += 1; + } else { + execution += std::to_string(current_time) + ", " + std::to_string(rand_1_10()) + ", create child PCB (PID=" + std::to_string(child.PID) + ")\n"; + current_time += rand_1_10(); + execution += std::to_string(current_time) + ", " + std::to_string(rand_1_10()) + ", assign partition " + std::to_string(child.partition_number) + " to child\n"; + current_time += rand_1_10(); + } + execution += std::to_string(current_time) + ", " + std::to_string(rand_1_10()) + ", scheduler()\n"; + current_time += rand_1_10(); + execution += std::to_string(current_time) + ", 1, IRET\n"; + current_time += 1; - /////////////////////////////////////////////////////////////////////////////////////////// + // Snapshot of system status after FORK: child runs first, parent waits + { + std::stringstream header; + header << "Time " << current_time << ", line: " << trace_line << "\n"; + system_status += header.str(); + if(allocated) { + std::vector queue; // copy existing processes in the wait queue + queue = wait_queue; + queue.push_back(current); // parent waits + system_status += print_PCB(child, queue); // child process gets priority + } else { + // If fork failed, parent continues running + system_status += print_PCB(current, wait_queue); + } + } //The following loop helps you do 2 things: - // * Collect the trace of the chile (and only the child, skip parent) + // * Collect the trace of the child (and only the child, skip parent) // * Get the index of where the parent is supposed to start executing from std::vector child_trace; bool skip = true; @@ -68,9 +105,10 @@ std::tuple simulate_trace(std::vector(j); if(exec_flag) { break; } @@ -90,11 +128,20 @@ std::tuple simulate_trace(std::vector child_wait_queue; // child has no waiters in this simple model + auto [child_exec, child_status, child_end_time] = simulate_trace(child_trace, current_time, vectors, delays, external_files, child, child_wait_queue); + execution += child_exec; + system_status += child_status; + current_time = child_end_time; + + // Child exits: free its memory + free_memory(&child); + execution += std::to_string(current_time) + ", 1, child exit (free partition)\n"; + current_time += 1; + } } else if(activity == "EXEC") { @@ -103,12 +150,59 @@ std::tuple simulate_trace(std::vector(get_size(program_name, external_files)); + if(static_cast(prog_size) == -1) { + execution += std::to_string(current_time) + ", 1, exec failed: program not found\n"; + current_time += 1; + } else { + execution += std::to_string(current_time) + ", " + std::to_string(rand_1_10()) + ", validate executable " + program_name + "\n"; + current_time += rand_1_10(); + + // Free current memory (a process will overlay its address space) + if(current.partition_number != -1) { + free_memory(¤t); + execution += std::to_string(current_time) + ", 1, free current partition\n"; + current_time += 1; + } + // Prepare a temp PCB with new program attributes to allocate memory + PCB temp = current; + temp.program_name = program_name; + temp.size = prog_size; + bool allocated = allocate_memory(&temp); + + if(!allocated) { + execution += std::to_string(current_time) + ", 1, exec failed: no suitable partition\n"; + current_time += 1; + } else { + // Simulate loading time: 15 ms per MB + int load_time = static_cast(15 * prog_size); + execution += std::to_string(current_time) + ", " + std::to_string(load_time) + ", load executable into memory (" + std::to_string(prog_size) + " MB)\n"; + current_time += load_time; + + // Commit the temp PCB to current + current.program_name = temp.program_name; + current.size = temp.size; + current.partition_number = temp.partition_number; + + execution += std::to_string(current_time) + ", " + std::to_string(rand_1_10()) + ", scheduler()\n"; + current_time += rand_1_10(); + } + } + execution += std::to_string(current_time) + ", 1, IRET\n"; + current_time += 1; /////////////////////////////////////////////////////////////////////////////////////////// - + // Snapshot system status after EXEC + { + std::stringstream header; + header << "Time " << current_time << ", line: " << trace_line << "\n"; + system_status += header.str(); + system_status += print_PCB(current, wait_queue); + } std::ifstream exec_trace_file(program_name + ".txt"); @@ -119,14 +213,16 @@ std::tuple simulate_trace(std::vector simulate_trace(std::vector wait_queue; - /******************ADD YOUR VARIABLES HERE*************************/ - - - /******************************************************************/ - //Converting the trace file into a vector of strings. std::vector trace_file; std::string trace; @@ -167,7 +258,7 @@ int main(int argc, char** argv) { trace_file.push_back(trace); } - auto [execution, system_status, _] = simulate_trace( trace_file, + auto [execution, system_status, _] = simulate_trace( trace_file, 0, vectors, delays, diff --git a/interrupts.hpp b/interrupts.hpp index 403e7fa..a0f98cf 100644 --- a/interrupts.hpp +++ b/interrupts.hpp @@ -4,13 +4,15 @@ #include #include #include +#include #include #include -#include #include #include #include -#include +#include +#include +#include #define ADDR_BASE 0 #define VECTOR_SIZE 2 @@ -21,7 +23,7 @@ struct memory_partition_t { std::string code; memory_partition_t(unsigned int _pn, unsigned int _s, std::string _c): - partition_number(_pn), size(_s), code(_c) {} + partition_number(_pn), size(_s), code(std::move(_c)) {} }; memory_partition_t memory[] = { @@ -38,22 +40,22 @@ struct PCB{ int PPID; std::string program_name; unsigned int size; - int partition_number; + unsigned int partition_number; PCB(unsigned int _pid, int _ppid, std::string _pn, unsigned int _size, int _part_num): - PID(_pid), PPID(_ppid), program_name(_pn), size(_size), partition_number(_part_num) {} + PID(_pid), PPID(_ppid), program_name(std::move(_pn)), size(_size), partition_number(_part_num) {} }; struct external_file{ std::string program_name; - unsigned int size; + unsigned int size{}; }; -//Allocates a program to memory (if there is space) -//returns true if the allocation was sucessful, false if not. -bool allocate_memory(PCB* current) { - for(int i = 5; i >= 0; i--) { //Start from smallest partition - //check is the code will fit and if the partition is empty +// Allocates a program to memory (if there is space) +// returns true if the allocation was successful, false if not. +inline bool allocate_memory(PCB* current) { + for(int i = 5; i >= 0; i--) { //Start from the smallest partition + //check is the code will fit, and if the partition is empty if(memory[i].size >= current->size && memory[i].code == "empty") { current->partition_number = memory[i].partition_number; memory[i].code = current->program_name; @@ -63,19 +65,18 @@ bool allocate_memory(PCB* current) { return false; } -//frees the memory given PCB. -void free_memory(PCB* process) { +// Frees the memory given PCB. +inline void free_memory(PCB* process) { memory[process->partition_number - 1].code = "empty"; process->partition_number = -1; } -// Following function was taken from stackoverflow; helper function for splitting strings -std::vector split_delim(std::string input, std::string delim) { +// The following function was taken from stackoverflow; helper function for splitting strings +inline std::vector split_delim(std::string input, const std::string &delim) { std::vector tokens; std::size_t pos = 0; - std::string token; while ((pos = input.find(delim)) != std::string::npos) { - token = input.substr(0, pos); + std::string token = input.substr(0, pos); tokens.push_back(token); input.erase(0, pos + delim.length()); } @@ -94,10 +95,10 @@ std::vector split_delim(std::string input, std::string delim) { * @return a vector of strings (the parsed vector table), a vector of delays, a vector of external files * */ -std::tuple, std::vector, std::vector>parse_args(int argc, char** argv) { +inline std::tuple, std::vector, std::vector>parse_args(int argc, char** argv) { if(argc != 5) { std::cout << "ERROR!\nExpected 4 argument, received " << argc - 1 << std::endl; - std::cout << "To run the program, do: ./interrutps " << std::endl; + std::cout << "To run the program, do: ./interrupts " << std::endl; exit(1); } @@ -159,8 +160,8 @@ std::tuple, std::vector, std::vector parse_trace(std::string trace) { +// Parses each trace and returns a tuple: {Tace activity, duration or interrupt number, program name (if applicable)} +inline std::tuple parse_trace(const std::string &trace) { //split line by ',' auto parts = split_delim(trace, ","); if (parts.size() < 2) { @@ -181,10 +182,10 @@ std::tuple parse_trace(std::string trace) { return {activity, duration_intr, extern_file}; } -//Default interrupt boilerplate -std::pair intr_boilerplate(int current_time, int intr_num, int context_save_time, std::vector vectors) { +// Default interrupt boilerplate +inline std::pair intr_boilerplate(int current_time, int intr_num, int context_save_time, const std::vector &vectors) { - std::string execution = ""; + std::string execution; execution += std::to_string(current_time) + ", " + std::to_string(1) + ", switch to kernel mode\n"; current_time++; @@ -206,8 +207,8 @@ std::pair intr_boilerplate(int current_time, int intr_num, int return std::make_pair(execution, current_time); } -//Writes a string to a file -void write_output(std::string execution, const char* filename) { +// Writes a string to a file +inline void write_output(const std::string &execution, const char* filename) { std::ofstream output_file(filename); if (output_file.is_open()) { @@ -221,9 +222,9 @@ void write_output(std::string execution, const char* filename) { std::cout << "Output generated in execution.txt" << std::endl; } -//Helper function for a sanity check. Prints the external files table -void print_external_files(std::vector files) { - const int tableWidth = 24; +// Helper function for a sanity check. Prints the external files table +inline void print_external_files(const std::vector &files) { + constexpr int tableWidth = 24; std::cout << "List of external files (" << files.size() << " entry(s)): " << std::endl; @@ -253,10 +254,10 @@ void print_external_files(std::vector files) { std::cout << "+" << std::setfill('-') << std::setw(tableWidth) << "+" << std::endl; } -//This function takes as input: the current PCB and the waitqueue (which is a -//std::vector of the PCB struct); the function returns the information as a table -std::string print_PCB(PCB current, std::vector _PCB) { - const int tableWidth = 55; +// This function takes as input: the current PCB and the wait queue (which is a +// std::vector of the PCB struct); the function returns the information as a table +inline std::string print_PCB(const PCB ¤t, const std::vector &PCB) { + constexpr int tableWidth = 55; std::stringstream buffer; @@ -292,7 +293,7 @@ std::string print_PCB(PCB current, std::vector _PCB) { << std::setw(2) << "|" << std::endl; // Print each PCB entry - for (const auto& program : _PCB) { + for (const auto& program : PCB) { buffer << "|" << std::setfill(' ') << std::setw(4) << program.PID << std::setw(2) << "|" @@ -314,12 +315,12 @@ std::string print_PCB(PCB current, std::vector _PCB) { // Searches the external_files table and returns the size of the program -unsigned int get_size(std::string name, std::vector external_files) { +inline int get_size(const std::string &name, const std::vector &external_files) { int size = -1; - for (auto file : external_files) { + for (const auto& file : external_files) { if(file.program_name == name){ - size = file.size; + size = static_cast(file.size); break; } } @@ -327,4 +328,12 @@ unsigned int get_size(std::string name, std::vector external_file return size; } +// Helper function that generates a random number between 1-10 ms +inline int rand_1_10() { + static std::mt19937 rng(static_cast( + std::chrono::high_resolution_clock::now().time_since_epoch().count())); + static std::uniform_int_distribution dist(1, 10); + return dist(rng); +} + #endif diff --git a/output_files/execution.txt b/output_files/execution.txt new file mode 100644 index 0000000..91d2f05 --- /dev/null +++ b/output_files/execution.txt @@ -0,0 +1,28 @@ +0, 1, switch to kernel mode +1, 10, context saved +11, 1, find vector 2 in memory position 0x0004 +12, 1, load address 0X0695 into the PC +13, 8, save parent PCB +23, 9, create child PCB (PID=1) +25, 2, assign partition 5 to child +30, 3, scheduler() +37, 1, IRET +38, 1, switch to kernel mode +39, 10, context saved +49, 1, find vector 3 in memory position 0x0006 +50, 1, load address 0X042B into the PC +51, 8, validate executable program1 +59, 1, free current partition +60, 150, load executable into memory (10 MB) +210, 2, scheduler() +213, 1, IRET +214, 1, child exit (free partition) +215, 1, switch to kernel mode +216, 10, context saved +226, 1, find vector 3 in memory position 0x0006 +227, 1, load address 0X042B into the PC +228, 7, validate executable program2 +234, 1, free current partition +235, 225, load executable into memory (15 MB) +460, 5, scheduler() +468, 1, IRET diff --git a/output_files/execution_case1.txt b/output_files/execution_case1.txt new file mode 100644 index 0000000..dfb6ac1 --- /dev/null +++ b/output_files/execution_case1.txt @@ -0,0 +1,6 @@ +0, 1, switch to kernel mode +1, 10, context saved +11, 1, find vector 3 in memory position 0x0006 +12, 1, load address 0X042B into the PC +13, 8, validate executable program_large +21, 1, memory allocation failed (program size exceeds all partitions) \ No newline at end of file diff --git a/output_files/execution_case3.txt b/output_files/execution_case3.txt new file mode 100644 index 0000000..a8a3971 --- /dev/null +++ b/output_files/execution_case3.txt @@ -0,0 +1,28 @@ +0, 1, switch to kernel mode +1, 10, context saved +11, 1, find vector 2 in memory position 0x0004 +12, 1, load address 0X0695 into the PC +13, 8, save parent PCB +21, 9, create child PCB (PID=1) +30, 2, assign partition 5 to child +35, 3, scheduler() +38, 1, IRET +39, 1, switch to kernel mode +40, 10, context saved +50, 1, find vector 3 in memory position 0x0006 +51, 1, load address 0X042B into the PC +52, 8, validate executable program_child +60, 1, free current partition +61, 150, load executable into memory (10 MB) +211, 2, scheduler() +214, 1, IRET +215, 1, child exit (free partition) +216, 1, switch to kernel mode +217, 10, context saved +227, 1, find vector 3 in memory position 0x0006 +228, 1, load address 0X042B into the PC +229, 7, validate executable program_parent +236, 1, free current partition +237, 375, load executable into memory (25 MB) +612, 5, scheduler() +620, 1, IRET \ No newline at end of file diff --git a/output_files/program_child.txt b/output_files/program_child.txt new file mode 100644 index 0000000..4859608 --- /dev/null +++ b/output_files/program_child.txt @@ -0,0 +1,3 @@ +RUN 5 +WAIT 2 +RUN 3 \ No newline at end of file diff --git a/output_files/program_large.txt b/output_files/program_large.txt new file mode 100644 index 0000000..3cd208e --- /dev/null +++ b/output_files/program_large.txt @@ -0,0 +1,3 @@ +RUN 10 +WAIT 5 +RUN 15 \ No newline at end of file diff --git a/output_files/program_parent.txt b/output_files/program_parent.txt new file mode 100644 index 0000000..0045a55 --- /dev/null +++ b/output_files/program_parent.txt @@ -0,0 +1,3 @@ +RUN 10 +WAIT 5 +RUN 10 \ No newline at end of file diff --git a/output_files/sysc4001_a2_p3_report_flavji543.pdf b/output_files/sysc4001_a2_p3_report_flavji543.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0d791ea1054a1084d435a65654c1424335ab1a0e GIT binary patch literal 35234 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 Qj7`kVEV)!wUH#p-0F5B9@&Et; literal 0 HcmV?d00001 diff --git a/output_files/system_status.txt b/output_files/system_status.txt new file mode 100644 index 0000000..d40cee6 --- /dev/null +++ b/output_files/system_status.txt @@ -0,0 +1,19 @@ +Time 38, line: FORK, 10 ++------------------------------------------------------+ +| PID |program name |partition number | size | state | ++------------------------------------------------------+ +| 1 | init | 5 | 1 | running | +| 0 | init | 6 | 1 | waiting | ++------------------------------------------------------+ +Time 214, line: EXEC program1, 50 ++------------------------------------------------------+ +| PID |program name |partition number | size | state | ++------------------------------------------------------+ +| 1 | program1 | 4 | 10 | running | ++------------------------------------------------------+ +Time 469, line: EXEC program2, 25 ++------------------------------------------------------+ +| PID |program name |partition number | size | state | ++------------------------------------------------------+ +| 0 | program2 | 3 | 15 | running | ++------------------------------------------------------+ diff --git a/output_files/system_status_case1.txt b/output_files/system_status_case1.txt new file mode 100644 index 0000000..e33a857 --- /dev/null +++ b/output_files/system_status_case1.txt @@ -0,0 +1,6 @@ +Time 21, line: EXEC program_large, 120 ++------------------------------------------------------+ +| PID |program name |partition number | size | state | ++------------------------------------------------------+ +| | | | | | ++------------------------------------------------------+ \ No newline at end of file diff --git a/output_files/system_status_case2.txt b/output_files/system_status_case2.txt new file mode 100644 index 0000000..5943275 --- /dev/null +++ b/output_files/system_status_case2.txt @@ -0,0 +1,19 @@ +Time 38, line: FORK, 10 ++------------------------------------------------------+ +| PID |program name |partition number | size | state | ++------------------------------------------------------+ +| 1 | init | 5 | 1 | running | +| 0 | init | 6 | 1 | waiting | ++------------------------------------------------------+ +Time 215, line: EXEC program_child, 10 ++------------------------------------------------------+ +| PID |program name |partition number | size | state | ++------------------------------------------------------+ +| 1 | program_child | 4 | 10 | running | ++------------------------------------------------------+ +Time 620, line: EXEC program_parent, 25 ++------------------------------------------------------+ +| PID |program name |partition number | size | state | ++------------------------------------------------------+ +| 0 | program_parent | 3 | 25 | running | ++------------------------------------------------------+ \ No newline at end of file