diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..39abe13 Binary files /dev/null and b/.DS_Store differ diff --git a/ossim_source_code/.DS_Store b/ossim_source_code/.DS_Store new file mode 100644 index 0000000..6b57edf Binary files /dev/null and b/ossim_source_code/.DS_Store differ diff --git a/ossim_source_code/.vscode/c_cpp_properties.json b/ossim_source_code/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..f6526a0 --- /dev/null +++ b/ossim_source_code/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "macos-clang-arm64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "/usr/bin/clang", + "cStandard": "${default}", + "cppStandard": "c++20", + "intelliSenseMode": "macos-clang-arm64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/ossim_source_code/.vscode/launch.json b/ossim_source_code/.vscode/launch.json new file mode 100644 index 0000000..5de968d --- /dev/null +++ b/ossim_source_code/.vscode/launch.json @@ -0,0 +1,13 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "/Users/admin/Downloads/ossim_source_code/src", + "program": "/Users/admin/Downloads/ossim_source_code/src/build/Debug/outDebug" + } + ] +} \ No newline at end of file diff --git a/ossim_source_code/.vscode/settings.json b/ossim_source_code/.vscode/settings.json new file mode 100644 index 0000000..7a3b5b2 --- /dev/null +++ b/ossim_source_code/.vscode/settings.json @@ -0,0 +1,66 @@ +{ + "C_Cpp_Runner.cCompilerPath": "clang", + "C_Cpp_Runner.cppCompilerPath": "clang++", + "C_Cpp_Runner.debuggerPath": "lldb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "c++20", + "C_Cpp_Runner.msvcBatchPath": "", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false, + "git.ignoreLimitWarning": true, + "files.associations": { + "cstdlib": "cpp", + "locale": "cpp", + "ostream": "cpp", + "new": "cpp" + } +} \ No newline at end of file diff --git a/ossim_source_code/Makefile b/ossim_source_code/Makefile new file mode 100644 index 0000000..f7ed868 --- /dev/null +++ b/ossim_source_code/Makefile @@ -0,0 +1,50 @@ + +INC = -Iinclude +LIB = -lpthread + +SRC = src +OBJ = obj +INCLUDE = include + +CC = gcc +DEBUG = -g +CFLAGS = -Wall -c $(DEBUG) +LFLAGS = -Wall $(DEBUG) + +vpath %.c $(SRC) +vpath %.h $(INCLUDE) + +MAKE = $(CC) $(INC) + +# Object files needed by modules +MEM_OBJ = $(addprefix $(OBJ)/, paging.o mem.o cpu.o loader.o) +OS_OBJ = $(addprefix $(OBJ)/, cpu.o mem.o loader.o queue.o os.o sched.o timer.o mm-vm.o mm.o mm-memphy.o) +SCHED_OBJ = $(addprefix $(OBJ)/, cpu.o loader.o) +HEADER = $(wildcard $(INCLUDE)/*.h) + +all: os +#mem sched os + +# Just compile memory management modules +mem: $(MEM_OBJ) + $(MAKE) $(LFLAGS) $(MEM_OBJ) -o mem $(LIB) + +# Just compile scheduler +sched: $(SCHED_OBJ) $(MEM_OBJ) + $(MAKE) $(LFLAGS) $(SCHED_OBJ) $(MEM_OBJ) -o sched $(LIB) + +# Compile the whole OS simulation +os: $(OS_OBJ) + $(MAKE) $(LFLAGS) $(OS_OBJ) -o os $(LIB) + +$(OBJ)/%.o: %.c ${HEADER} $(OBJ) + $(MAKE) $(CFLAGS) $< -o $@ + +# Prepare objectives container +$(OBJ): + mkdir -p $(OBJ) + +clean: + rm -f $(OBJ)/*.o os sched mem + rm -r $(OBJ) + diff --git a/ossim_source_code/include/bitops.h b/ossim_source_code/include/bitops.h new file mode 100644 index 0000000..0cc9413 --- /dev/null +++ b/ossim_source_code/include/bitops.h @@ -0,0 +1,37 @@ +#ifdef CONFIG_64BIT +#define BITS_PER_LONG 64 +#else +#define BITS_PER_LONG 32 +#endif /* CONFIG_64BIT */ + +#define BITS_PER_BYTE 8 +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) + +#define BIT(nr) (1U << (nr)) +#define BIT_ULL(nr) (1ULL << (nr)) +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) + +#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) + +#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) + +/* + * Create a contiguous bitmask starting at bit position @l and ending at + * position @h. For example + * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. + */ +#define GENMASK(h, l) \ + (((~0U) << (l)) & (~0U >> (BITS_PER_LONG - (h) - 1))) + +#define NBITS2(n) ((n&2)?1:0) +#define NBITS4(n) ((n&(0xC))?(2+NBITS2(n>>2)):(NBITS2(n))) +#define NBITS8(n) ((n&0xF0)?(4+NBITS4(n>>4)):(NBITS4(n))) +#define NBITS16(n) ((n&0xFF00)?(8+NBITS8(n>>8)):(NBITS8(n))) +#define NBITS32(n) ((n&0xFFFF0000)?(16+NBITS16(n>>16)):(NBITS16(n))) +#define NBITS(n) (n==0?0:NBITS32(n)) + +#define EXTRACT_NBITS(nr, h, l) ((nr&GENMASK(h,l)) >> l) diff --git a/ossim_source_code/include/common.h b/ossim_source_code/include/common.h new file mode 100644 index 0000000..c1d5a17 --- /dev/null +++ b/ossim_source_code/include/common.h @@ -0,0 +1,96 @@ +#ifndef COMMON_H +#define COMMON_H + +/* Define structs and routine could be used by every source files */ + +#include + +#ifndef OSCFG_H +#include "os-cfg.h" +#endif + +#ifndef OSMM_H +#include "os-mm.h" +#endif + +#define ADDRESS_SIZE 20 +#define OFFSET_LEN 10 +#define FIRST_LV_LEN 5 +#define SECOND_LV_LEN 5 +#define SEGMENT_LEN FIRST_LV_LEN +#define PAGE_LEN SECOND_LV_LEN + +#define NUM_PAGES (1 << (ADDRESS_SIZE - OFFSET_LEN)) +#define PAGE_SIZE (1 << OFFSET_LEN) + +enum ins_opcode_t { + CALC, // Just perform calculation, only use CPU + ALLOC, // Allocate memory +#ifdef MM_PAGING + MALLOC, // Allocate dynamic memory +#endif + FREE, // Deallocated a memory block + READ, // Write data to a byte on memory + WRITE // Read data from a byte on memory +}; + +/* instructions executed by the CPU */ +struct inst_t { + enum ins_opcode_t opcode; + uint32_t arg_0; // Argument lists for instructions + uint32_t arg_1; + uint32_t arg_2; +}; + +struct code_seg_t { + struct inst_t * text; + uint32_t size; +}; + +struct trans_table_t { + /* A row in the page table of the second layer */ + struct { + addr_t v_index; // The index of virtual address + addr_t p_index; // The index of physical address + } table[1 << SECOND_LV_LEN]; + int size; +}; + +/* Mapping virtual addresses and physical ones */ +struct page_table_t { + /* Translation table for the first layer */ + struct { + addr_t v_index; // Virtual index + struct trans_table_t * next_lv; + } table[1 << FIRST_LV_LEN]; + int size; // Number of row in the first layer +}; + +/* PCB, describe information about a process */ +struct pcb_t { + uint32_t pid; // PID + uint32_t priority; // Default priority, this legacy (FIXED) value depend on process itself + struct code_seg_t * code; // Code segment + addr_t regs[10]; // Registers, store address of allocated regions + uint32_t pc; // Program pointer, point to the next instruction +#ifdef MLQ_SCHED + // Priority on execution (if supported), on-fly aka. changeable + // and this vale overwrites the default priority when it existed + uint32_t prio; +#endif +#ifdef MM_PAGING + struct mm_struct *mm; + struct memphy_struct *mram; + struct memphy_struct **mswp; + struct memphy_struct *active_mswp; +#ifdef MM_PAGING_HEAP_GODOWN + uint32_t vmemsz; +#endif +#endif + struct page_table_t * page_table; // Page table + uint32_t bp; // Break pointer + +}; + +#endif + diff --git a/ossim_source_code/include/cpu.h b/ossim_source_code/include/cpu.h new file mode 100644 index 0000000..0b95b07 --- /dev/null +++ b/ossim_source_code/include/cpu.h @@ -0,0 +1,13 @@ + +#ifndef CPU_H +#define CPU_H + +#include "common.h" + +/* Execute an instruction of a process. Return 0 + * if the instruction is executed successfully. + * Otherwise, return 1. */ +int run(struct pcb_t * proc); + +#endif + diff --git a/ossim_source_code/include/loader.h b/ossim_source_code/include/loader.h new file mode 100644 index 0000000..8fedc07 --- /dev/null +++ b/ossim_source_code/include/loader.h @@ -0,0 +1,9 @@ +#ifndef LOADER_H +#define LOADER_H + +#include "common.h" + +struct pcb_t * load(const char * path); + +#endif + diff --git a/ossim_source_code/include/mem.h b/ossim_source_code/include/mem.h new file mode 100644 index 0000000..3c2f5a3 --- /dev/null +++ b/ossim_source_code/include/mem.h @@ -0,0 +1,32 @@ +#ifndef MEM_H +#define MEM_H + +#include "common.h" + +#define RAM_SIZE (1 << ADDRESS_SIZE) + +/* Init related parameters, must be called before being used */ +void init_mem(void); + +/* Allocate [size] bytes for process [proc] and return its virtual address. + * If we cannot allocate new memory region for this process, return 0 */ +addr_t alloc_mem(uint32_t size, struct pcb_t * proc); + +/* Free a memory block having the first byte at [address] used by + * process [proc]. Return 0 if [address] is valid. Otherwise, return 1 */ +int free_mem(addr_t address, struct pcb_t * proc); + +/* Read 1 byte memory pointed by [address] used by process [proc] and + * save it to [data]. + * If the given [address] is valid, return 0. Otherwise, return 1 */ +int read_mem(addr_t address, struct pcb_t * proc, BYTE * data); + +/* Write [data] to 1 byte on the memory pointed by [address] of process + * [proc]. If given [address] is valid, return 0. Otherwise, return 1 */ +int write_mem(addr_t address, struct pcb_t * proc, BYTE data); + +void dump(void); + +#endif + + diff --git a/ossim_source_code/include/mm.h b/ossim_source_code/include/mm.h new file mode 100644 index 0000000..e7d9094 --- /dev/null +++ b/ossim_source_code/include/mm.h @@ -0,0 +1,163 @@ +#ifndef MM_H + +#include "bitops.h" +#include "common.h" + +/* CPU Bus definition */ +#define PAGING_CPU_BUS_WIDTH 22 /* 22bit bus - MAX SPACE 4MB */ +#define PAGING_PAGESZ 256 /* 256B or 8-bits PAGE NUMBER */ +#define PAGING_MEMRAMSZ BIT(10) /* 1MB */ +#define PAGING_PAGE_ALIGNSZ(sz) (DIV_ROUND_UP(sz,PAGING_PAGESZ) *PAGING_PAGESZ) + +#define PAGING_MEMSWPSZ BIT(14) /* 16MB */ +#define PAGING_SWPFPN_OFFSET 5 +#define PAGING_MAX_PGN (DIV_ROUND_UP(BIT(PAGING_CPU_BUS_WIDTH),PAGING_PAGESZ)) + +#define PAGING_SBRK_INIT_SZ PAGING_PAGESZ +/* PTE BIT */ +#define PAGING_PTE_PRESENT_MASK BIT(31) +#define PAGING_PTE_SWAPPED_MASK BIT(30) +#define PAGING_PTE_RESERVE_MASK BIT(29) +#define PAGING_PTE_DIRTY_MASK BIT(28) +#define PAGING_PTE_EMPTY01_MASK BIT(14) +#define PAGING_PTE_EMPTY02_MASK BIT(13) + +/* PTE BIT PRESENT */ +#define PAGING_PTE_SET_PRESENT(pte) (pte=pte|PAGING_PTE_PRESENT_MASK) +#define PAGING_PTE_PAGE_PRESENT(pte) (pte&PAGING_PTE_PRESENT_MASK) + +/* USRNUM */ +#define PAGING_PTE_USRNUM_LOBIT 15 +#define PAGING_PTE_USRNUM_HIBIT 27 +/* FPN */ +#define PAGING_PTE_FPN_LOBIT 0 +#define PAGING_PTE_FPN_HIBIT 12 +/* SWPTYP */ +#define PAGING_PTE_SWPTYP_LOBIT 0 +#define PAGING_PTE_SWPTYP_HIBIT 4 +/* SWPOFF */ +#define PAGING_PTE_SWPOFF_LOBIT 5 +#define PAGING_PTE_SWPOFF_HIBIT 25 + +/* PTE masks */ +#define PAGING_PTE_USRNUM_MASK GENMASK(PAGING_PTE_USRNUM_HIBIT,PAGING_PTE_USRNUM_LOBIT) +#define PAGING_PTE_FPN_MASK GENMASK(PAGING_PTE_FPN_HIBIT,PAGING_PTE_FPN_LOBIT) +#define PAGING_PTE_SWPTYP_MASK GENMASK(PAGING_PTE_SWPTYP_HIBIT,PAGING_PTE_SWPTYP_LOBIT) +#define PAGING_PTE_SWPOFF_MASK GENMASK(PAGING_PTE_SWPOFF_HIBIT,PAGING_PTE_SWPOFF_LOBIT) + +/* Extract PTE */ +#define PAGING_PTE_OFFST(pte) GETVAL(pte,PAGING_OFFST_MASK,PAGING_ADDR_OFFST_LOBIT) +#define PAGING_PTE_PGN(pte) GETVAL(pte,PAGING_PGN_MASK,PAGING_ADDR_PGN_LOBIT) +#define PAGING_PTE_FPN(pte) GETVAL(pte,PAGING_PTE_FPN_MASK,PAGING_PTE_FPN_LOBIT) +#define PAGING_PTE_SWP(pte) GETVAL(pte,PAGING_PTE_SWPOFF_MASK,PAGING_SWPFPN_OFFSET) + +/* OFFSET */ +#define PAGING_ADDR_OFFST_LOBIT 0 +#define PAGING_ADDR_OFFST_HIBIT (NBITS(PAGING_PAGESZ) - 1) + +/* PAGE Num */ +#define PAGING_ADDR_PGN_LOBIT NBITS(PAGING_PAGESZ) +#define PAGING_ADDR_PGN_HIBIT (PAGING_CPU_BUS_WIDTH - 1) + +/* Frame PHY Num */ +#define PAGING_ADDR_FPN_LOBIT NBITS(PAGING_PAGESZ) +#define PAGING_ADDR_FPN_HIBIT (NBITS(PAGING_MEMRAMSZ) - 1) + +/* SWAPFPN */ +#define PAGING_SWP_LOBIT NBITS(PAGING_PAGESZ) +#define PAGING_SWP_HIBIT (NBITS(PAGING_MEMSWPSZ) - 1) + +/* Value operators */ +#define SETBIT(v,mask) (v=v|mask) +#define CLRBIT(v,mask) (v=v&~mask) + +#define SETVAL(v,value,mask,offst) (v=(v&~mask)|((value<>offst) + +/* Other masks */ +#define PAGING_OFFST_MASK GENMASK(PAGING_ADDR_OFFST_HIBIT,PAGING_ADDR_OFFST_LOBIT) +#define PAGING_PGN_MASK GENMASK(PAGING_ADDR_PGN_HIBIT,PAGING_ADDR_PGN_LOBIT) +#define PAGING_FPN_MASK GENMASK(PAGING_ADDR_FPN_HIBIT,PAGING_ADDR_FPN_LOBIT) +#define PAGING_SWP_MASK GENMASK(PAGING_SWP_HIBIT,PAGING_SWP_LOBIT) + +/* Extract OFFSET */ +//#define PAGING_OFFST(x) ((x&PAGING_OFFST_MASK) >> PAGING_ADDR_OFFST_LOBIT) +#define PAGING_OFFST(x) GETVAL(x,PAGING_OFFST_MASK,PAGING_ADDR_OFFST_LOBIT) +/* Extract Page Number*/ +#define PAGING_PGN(x) GETVAL(x,PAGING_PGN_MASK,PAGING_ADDR_PGN_LOBIT) +/* Extract FramePHY Number*/ +#define PAGING_FPN(x) GETVAL(x,PAGING_FPN_MASK,PAGING_ADDR_FPN_LOBIT) +/* Extract SWAPFPN */ +#define PAGING_PGN(x) GETVAL(x,PAGING_PGN_MASK,PAGING_ADDR_PGN_LOBIT) +/* Extract SWAPTYPE */ +#define PAGING_FPN(x) GETVAL(x,PAGING_FPN_MASK,PAGING_ADDR_FPN_LOBIT) + +/* Memory range operator */ +/* TODO implement the INCLUDE checking mechanism - currently dummy op only */ +#define INCLUDE(x1,x2,y1,y2) (0) +/* TODO implement the OVERLAP checking mechanism - currently dummy op only */ +#define OVERLAP(x1,x2,y1,y2) (1) + +/* VM region prototypes */ +struct vm_rg_struct * init_vm_rg(int rg_start, int rg_endi, int vmaid); +int enlist_vm_rg_node(struct vm_rg_struct **rglist, struct vm_rg_struct* rgnode); +int enlist_pgn_node(struct pgn_t **pgnlist, int pgn); +int vmap_page_range(struct pcb_t *caller, int addr, int pgnum, + struct framephy_struct *frames, struct vm_rg_struct *ret_rg); +int vm_map_ram(struct pcb_t *caller, int astart, int send, int mapstart, int incpgnum, struct vm_rg_struct *ret_rg); +int alloc_pages_range(struct pcb_t *caller, int incpgnum, struct framephy_struct **frm_lst); +int __swap_cp_page(struct memphy_struct *mpsrc, int srcfpn, + struct memphy_struct *mpdst, int dstfpn) ; +int pte_set_fpn(uint32_t *pte, int fpn); +int pte_set_swap(uint32_t *pte, int swptyp, int swpoff); +int init_pte(uint32_t *pte, + int pre, // present + int fpn, // FPN + int drt, // dirty + int swp, // swap + int swptyp, // swap type + int swpoff); //swap offset +int __alloc(struct pcb_t *caller, int vmaid, int rgid, int size, int *alloc_addr); +int __free(struct pcb_t *caller, int rgid); +int __read(struct pcb_t *caller, int rgid, int offset, BYTE *data); +int __write(struct pcb_t *caller, int rgid, int offset, BYTE value); +int init_mm(struct mm_struct *mm, struct pcb_t *caller); + +/* VM prototypes */ +int pgalloc(struct pcb_t *proc, uint32_t size, uint32_t reg_index); +int pgmalloc(struct pcb_t *proc, uint32_t size, uint32_t reg_index); +int pgfree_data(struct pcb_t *proc, uint32_t reg_index); +int pgread( + struct pcb_t * proc, // Process executing the instruction + uint32_t source, // Index of source register + uint32_t offset, // Source address = [source] + [offset] + uint32_t destination); +int pgwrite( + struct pcb_t * proc, // Process executing the instruction + BYTE data, // Data to be wrttien into memory + uint32_t destination, // Index of destination register + uint32_t offset); +/* Local VM prototypes */ +struct vm_rg_struct * get_symrg_byid(struct mm_struct* mm, int rgid); +int validate_overlap_vm_area(struct pcb_t *caller, int vmaid, int vmastart, int vmaend); +int get_free_vmrg_area(struct pcb_t *caller, int vmaid, int size, struct vm_rg_struct *newrg); +int inc_vma_limit(struct pcb_t *caller, int vmaid, int inc_sz, int* inc_limit_ret); +int find_victim_page(struct mm_struct* mm, int *pgn); +struct vm_area_struct *get_vma_by_num(struct mm_struct *mm, int vmaid); + +/* MEM/PHY protypes */ +int MEMPHY_get_freefp(struct memphy_struct *mp, int *fpn); +int MEMPHY_put_freefp(struct memphy_struct *mp, int fpn); +int MEMPHY_read(struct memphy_struct * mp, int addr, BYTE *value); +int MEMPHY_write(struct memphy_struct * mp, int addr, BYTE data); +int MEMPHY_dump(struct memphy_struct * mp); +int init_memphy(struct memphy_struct *mp, int max_size, int randomflg); +/* DEBUG */ +int print_list_fp(struct framephy_struct *fp); +int print_list_rg(struct vm_rg_struct *rg); +int print_list_vma(struct vm_area_struct *rg); + + +int print_list_pgn(struct pgn_t *ip); +int print_pgtbl(struct pcb_t *ip, uint32_t start, uint32_t end); +#endif diff --git a/ossim_source_code/include/os-cfg.h b/ossim_source_code/include/os-cfg.h new file mode 100644 index 0000000..d5034e0 --- /dev/null +++ b/ossim_source_code/include/os-cfg.h @@ -0,0 +1,15 @@ +#ifndef OSCFG_H +#define OSCFG_H + +#define MLQ_SCHED 1 +#define MAX_PRIO 140 + +#define MM_PAGING +#define MM_PAGING_HEAP_GODOWN +// #define MM_FIXED_MEMSZ +#define VMDBG 1 +#define MMDBG 1 +#define IODUMP 1 +#define PAGETBL_DUMP 1 + +#endif diff --git a/ossim_source_code/include/os-mm.h b/ossim_source_code/include/os-mm.h new file mode 100644 index 0000000..beef90e --- /dev/null +++ b/ossim_source_code/include/os-mm.h @@ -0,0 +1,88 @@ +#ifndef OSMM_H +#define OSMM_H + +#define MM_PAGING +#define PAGING_MAX_MMSWP 4 /* max number of supported swapped space */ +#define PAGING_MAX_SYMTBL_SZ 30 + +typedef char BYTE; +typedef uint32_t addr_t; +//typedef unsigned int uint32_t; + +struct pgn_t{ + int pgn; + struct pgn_t *pg_next; +}; + +/* + * Memory region struct + */ +struct vm_rg_struct { + int vmaid; + + unsigned long rg_start; + unsigned long rg_end; + + struct vm_rg_struct *rg_next; +}; + +/* + * Memory area struct + */ +struct vm_area_struct { + unsigned long vm_id; + unsigned long vm_start; + unsigned long vm_end; + + unsigned long sbrk; +/* + * Derived field + * unsigned long vm_limit = vm_end - vm_start + */ + struct mm_struct *vm_mm; + + struct vm_rg_struct *vm_freerg_list; + struct vm_area_struct *vm_next; +}; + +/* + * Memory management struct + */ +struct mm_struct { + uint32_t *pgd; + + struct vm_area_struct *mmap; + + /* Currently we support a fixed number of symbol */ + struct vm_rg_struct symrgtbl[PAGING_MAX_SYMTBL_SZ]; + + /* list of free page */ + struct pgn_t *fifo_pgn; +}; + +/* + * FRAME/MEM PHY struct + */ +struct framephy_struct { + int fpn; + struct framephy_struct *fp_next; + + /* Resereed for tracking allocated framed */ + struct mm_struct* owner; +}; + +struct memphy_struct { + /* Basic field of data and size */ + BYTE *storage; + int maxsz; + + /* Sequential device fields */ + int rdmflg; + int cursor; + + /* Management structure */ + struct framephy_struct *free_fp_list; + struct framephy_struct *used_fp_list; +}; + +#endif diff --git a/ossim_source_code/include/queue.h b/ossim_source_code/include/queue.h new file mode 100644 index 0000000..d26881c --- /dev/null +++ b/ossim_source_code/include/queue.h @@ -0,0 +1,22 @@ + +#ifndef QUEUE_H +#define QUEUE_H + +#include "common.h" + +#define MAX_QUEUE_SIZE 10 + +struct queue_t { + int count_slot; + struct pcb_t * proc[MAX_QUEUE_SIZE]; + int size; +}; + +void enqueue(struct queue_t * q, struct pcb_t * proc); + +struct pcb_t * dequeue(struct queue_t * q); + +int empty(struct queue_t * q); + +#endif + diff --git a/ossim_source_code/include/sched.h b/ossim_source_code/include/sched.h new file mode 100644 index 0000000..d252c72 --- /dev/null +++ b/ossim_source_code/include/sched.h @@ -0,0 +1,28 @@ +#ifndef QUEUE_H +#define QUEUE_H + +#include "common.h" + +#ifndef MLQ_SCHED +#define MLQ_SCHED +#endif + +//#define MAX_PRIO 139 + +int queue_empty(void); + +void init_scheduler(void); +void finish_scheduler(void); + +/* Get the next process from ready queue */ +struct pcb_t * get_proc(void); + +/* Put a process back to run queue */ +void put_proc(struct pcb_t * proc); + +/* Add a new process to ready queue */ +void add_proc(struct pcb_t * proc); + +#endif + + diff --git a/ossim_source_code/include/timer.h b/ossim_source_code/include/timer.h new file mode 100644 index 0000000..e480b66 --- /dev/null +++ b/ossim_source_code/include/timer.h @@ -0,0 +1,28 @@ +#ifndef TIMER_H +#define TIMER_H + +#include +#include + +struct timer_id_t { + int done; + int fsh; + pthread_cond_t event_cond; + pthread_mutex_t event_lock; + pthread_cond_t timer_cond; + pthread_mutex_t timer_lock; +}; + +void start_timer(); + +void stop_timer(); + +struct timer_id_t * attach_event(); + +void detach_event(struct timer_id_t * event); + +void next_slot(struct timer_id_t* timer_id); + +uint64_t current_time(); + +#endif diff --git a/ossim_source_code/input/os_0_mlq_paging b/ossim_source_code/input/os_0_mlq_paging new file mode 100644 index 0000000..6872297 --- /dev/null +++ b/ossim_source_code/input/os_0_mlq_paging @@ -0,0 +1,4 @@ +6 2 4 +1048576 16777216 0 0 0 3145728 +0 p0s 0 +2 p1s 15 diff --git a/ossim_source_code/input/os_1_mlq_paging b/ossim_source_code/input/os_1_mlq_paging new file mode 100644 index 0000000..0068caf --- /dev/null +++ b/ossim_source_code/input/os_1_mlq_paging @@ -0,0 +1,10 @@ +2 4 8 +1048576 16777216 0 0 0 3145728 +1 p0s 130 +2 s3 39 +4 m1s 15 +6 s2 120 +7 m0s 120 +9 p1s 15 +11 s0 38 +16 s1 0 diff --git a/ossim_source_code/input/os_1_mlq_paging_small_1K b/ossim_source_code/input/os_1_mlq_paging_small_1K new file mode 100644 index 0000000..a5788e4 --- /dev/null +++ b/ossim_source_code/input/os_1_mlq_paging_small_1K @@ -0,0 +1,10 @@ +2 4 8 +2048 16777216 0 0 0 3145728 +1 p0s 130 +2 s3 39 +4 m1s 15 +6 s2 120 +7 m0s 120 +9 p1s 15 +11 s0 38 +16 s1 0 diff --git a/ossim_source_code/input/os_1_mlq_paging_small_4K b/ossim_source_code/input/os_1_mlq_paging_small_4K new file mode 100644 index 0000000..bd6af03 --- /dev/null +++ b/ossim_source_code/input/os_1_mlq_paging_small_4K @@ -0,0 +1,10 @@ +2 4 8 +4096 16777216 0 0 0 3145728 +1 p0s 130 +2 s3 39 +4 m1s 15 +6 s2 120 +7 m0s 120 +9 p1s 15 +11 s0 38 +16 s1 0 diff --git a/ossim_source_code/input/os_1_singleCPU_mlq b/ossim_source_code/input/os_1_singleCPU_mlq new file mode 100644 index 0000000..98efc7e --- /dev/null +++ b/ossim_source_code/input/os_1_singleCPU_mlq @@ -0,0 +1,9 @@ +2 1 8 +1 s4 4 +2 s3 3 +4 m1s 2 +6 s2 3 +7 m0s 3 +9 p1s 2 +11 s0 1 +16 s1 0 diff --git a/ossim_source_code/input/os_1_singleCPU_mlq_paging b/ossim_source_code/input/os_1_singleCPU_mlq_paging new file mode 100644 index 0000000..99e0a04 --- /dev/null +++ b/ossim_source_code/input/os_1_singleCPU_mlq_paging @@ -0,0 +1,10 @@ +2 1 8 +1048576 16777216 0 0 0 3145728 +1 s4 4 +2 s3 3 +4 m1s 2 +6 s2 3 +7 m0s 3 +9 p1s 2 +11 s0 1 +16 s1 0 diff --git a/ossim_source_code/input/proc/m0s b/ossim_source_code/input/proc/m0s new file mode 100644 index 0000000..3466b3a --- /dev/null +++ b/ossim_source_code/input/proc/m0s @@ -0,0 +1,8 @@ +1 7 +alloc 300 0 +alloc 100 1 +free 0 +alloc 100 2 +malloc 100 3 +write 102 1 20 +write 1 2 1000 diff --git a/ossim_source_code/input/proc/m1s b/ossim_source_code/input/proc/m1s new file mode 100644 index 0000000..b3b24a6 --- /dev/null +++ b/ossim_source_code/input/proc/m1s @@ -0,0 +1,8 @@ +1 7 +alloc 300 0 +alloc 100 1 +free 0 +alloc 100 2 +malloc 100 2 +free 2 +free 1 diff --git a/ossim_source_code/input/proc/p0s b/ossim_source_code/input/proc/p0s new file mode 100644 index 0000000..7c443f9 --- /dev/null +++ b/ossim_source_code/input/proc/p0s @@ -0,0 +1,15 @@ +1 14 +calc +alloc 300 0 +malloc 300 4 +free 0 +alloc 100 1 +write 100 1 20 +read 1 20 20 +write 102 2 20 +read 2 20 20 +write 103 3 20 +read 3 20 20 +calc +free 4 +calc diff --git a/ossim_source_code/input/proc/p1s b/ossim_source_code/input/proc/p1s new file mode 100644 index 0000000..79c5fba --- /dev/null +++ b/ossim_source_code/input/proc/p1s @@ -0,0 +1,12 @@ +1 10 +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc diff --git a/ossim_source_code/input/proc/p2s b/ossim_source_code/input/proc/p2s new file mode 100644 index 0000000..2d9336d --- /dev/null +++ b/ossim_source_code/input/proc/p2s @@ -0,0 +1,14 @@ +20 13 +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc diff --git a/ossim_source_code/input/proc/p3s b/ossim_source_code/input/proc/p3s new file mode 100644 index 0000000..08a2128 --- /dev/null +++ b/ossim_source_code/input/proc/p3s @@ -0,0 +1,18 @@ +7 17 +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc diff --git a/ossim_source_code/input/proc/s0 b/ossim_source_code/input/proc/s0 new file mode 100644 index 0000000..6186100 --- /dev/null +++ b/ossim_source_code/input/proc/s0 @@ -0,0 +1,16 @@ +12 15 +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc diff --git a/ossim_source_code/input/proc/s1 b/ossim_source_code/input/proc/s1 new file mode 100644 index 0000000..8614b76 --- /dev/null +++ b/ossim_source_code/input/proc/s1 @@ -0,0 +1,8 @@ +20 7 +calc +calc +calc +calc +calc +calc +calc diff --git a/ossim_source_code/input/proc/s2 b/ossim_source_code/input/proc/s2 new file mode 100644 index 0000000..2d9336d --- /dev/null +++ b/ossim_source_code/input/proc/s2 @@ -0,0 +1,14 @@ +20 13 +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc diff --git a/ossim_source_code/input/proc/s3 b/ossim_source_code/input/proc/s3 new file mode 100644 index 0000000..08a2128 --- /dev/null +++ b/ossim_source_code/input/proc/s3 @@ -0,0 +1,18 @@ +7 17 +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc diff --git a/ossim_source_code/input/proc/s4 b/ossim_source_code/input/proc/s4 new file mode 100644 index 0000000..79dfde8 --- /dev/null +++ b/ossim_source_code/input/proc/s4 @@ -0,0 +1,31 @@ +20 30 +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc +calc diff --git a/ossim_source_code/input/sched b/ossim_source_code/input/sched new file mode 100644 index 0000000..33c50ef --- /dev/null +++ b/ossim_source_code/input/sched @@ -0,0 +1,4 @@ +4 2 3 +0 p1s +1 p2s +2 p3s diff --git a/ossim_source_code/input/sched_0 b/ossim_source_code/input/sched_0 new file mode 100644 index 0000000..ae979fd --- /dev/null +++ b/ossim_source_code/input/sched_0 @@ -0,0 +1,3 @@ +2 1 2 +0 s0 137 +4 s1 138 diff --git a/ossim_source_code/input/sched_1 b/ossim_source_code/input/sched_1 new file mode 100644 index 0000000..c7fac37 --- /dev/null +++ b/ossim_source_code/input/sched_1 @@ -0,0 +1,5 @@ +2 1 4 +0 s0 +4 s1 +6 s2 +7 s3 diff --git a/ossim_source_code/obj/cpu.o b/ossim_source_code/obj/cpu.o new file mode 100644 index 0000000..4a5586b Binary files /dev/null and b/ossim_source_code/obj/cpu.o differ diff --git a/ossim_source_code/obj/loader.o b/ossim_source_code/obj/loader.o new file mode 100644 index 0000000..6c7bebb Binary files /dev/null and b/ossim_source_code/obj/loader.o differ diff --git a/ossim_source_code/obj/mem.o b/ossim_source_code/obj/mem.o new file mode 100644 index 0000000..f258d18 Binary files /dev/null and b/ossim_source_code/obj/mem.o differ diff --git a/ossim_source_code/obj/mm-memphy.o b/ossim_source_code/obj/mm-memphy.o new file mode 100644 index 0000000..f63706c Binary files /dev/null and b/ossim_source_code/obj/mm-memphy.o differ diff --git a/ossim_source_code/obj/mm-vm.o b/ossim_source_code/obj/mm-vm.o new file mode 100644 index 0000000..f5dd1f1 Binary files /dev/null and b/ossim_source_code/obj/mm-vm.o differ diff --git a/ossim_source_code/obj/mm.o b/ossim_source_code/obj/mm.o new file mode 100644 index 0000000..75aaf47 Binary files /dev/null and b/ossim_source_code/obj/mm.o differ diff --git a/ossim_source_code/obj/os.o b/ossim_source_code/obj/os.o new file mode 100644 index 0000000..0f729d1 Binary files /dev/null and b/ossim_source_code/obj/os.o differ diff --git a/ossim_source_code/obj/queue.o b/ossim_source_code/obj/queue.o new file mode 100644 index 0000000..47a4309 Binary files /dev/null and b/ossim_source_code/obj/queue.o differ diff --git a/ossim_source_code/obj/sched.o b/ossim_source_code/obj/sched.o new file mode 100644 index 0000000..471d174 Binary files /dev/null and b/ossim_source_code/obj/sched.o differ diff --git a/ossim_source_code/obj/timer.o b/ossim_source_code/obj/timer.o new file mode 100644 index 0000000..a8cc5c9 Binary files /dev/null and b/ossim_source_code/obj/timer.o differ diff --git a/ossim_source_code/os b/ossim_source_code/os new file mode 100755 index 0000000..d436028 Binary files /dev/null and b/ossim_source_code/os differ diff --git a/ossim_source_code/output/os_0_mlq_paging.output b/ossim_source_code/output/os_0_mlq_paging.output new file mode 100644 index 0000000..87d78bc --- /dev/null +++ b/ossim_source_code/output/os_0_mlq_paging.output @@ -0,0 +1,78 @@ +Time slot 0 +ld_routine + Loaded a process at input/proc/p0s, PID: 1 PRIO: 0 + CPU 0: Dispatched process 1 +Time slot 1 +Time slot 2 + Loaded a process at input/proc/p1s, PID: 2 PRIO: 15 +Time slot 3 + Loaded a process at input/proc/p1s, PID: 3 PRIO: 0 +Time slot 4 + CPU 1: Dispatched process 2 + Loaded a process at input/proc/p1s, PID: 4 PRIO: 0 +Time slot 5 +write region=1 offset=20 value=100 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 6 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 1 +read region=1 offset=20 value=100 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 7 +write region=2 offset=20 value=102 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 8 +read region=2 offset=20 value=102 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 9 +write region=3 offset=20 value=103 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 10 + CPU 1: Put process 2 to run queue + CPU 1: Dispatched process 4 + CPU 0: Processed 1 has finished + CPU 0: Dispatched process 3 +Time slot 11 +Time slot 12 +Time slot 13 +Time slot 14 +Time slot 15 +Time slot 16 + CPU 1: Put process 4 to run queue + CPU 1: Dispatched process 2 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 17 +Time slot 18 +Time slot 19 +Time slot 20 + CPU 0: Processed 3 has finished + CPU 0: Dispatched process 4 + CPU 1: Processed 2 has finished + CPU 1 stopped +Time slot 21 +Time slot 22 +Time slot 23 +Time slot 24 + CPU 0: Processed 4 has finished + CPU 0 stopped diff --git a/ossim_source_code/output/os_1_mlq_paging.output b/ossim_source_code/output/os_1_mlq_paging.output new file mode 100644 index 0000000..2f675f0 --- /dev/null +++ b/ossim_source_code/output/os_1_mlq_paging.output @@ -0,0 +1,173 @@ +Time slot 0 +ld_routine +Time slot 1 + Loaded a process at input/proc/p0s, PID: 1 PRIO: 130 +Time slot 2 + CPU 1: Dispatched process 1 + Loaded a process at input/proc/s3, PID: 2 PRIO: 39 +Time slot 3 + CPU 0: Dispatched process 2 +Time slot 4 + CPU 1: Put process 1 to run queue + Loaded a process at input/proc/m1s, PID: 3 PRIO: 15 + CPU 3: Dispatched process 1 +Time slot 5 + CPU 2: Dispatched process 3 + CPU 0: Put process 2 to run queue +Time slot 6 + CPU 0: Dispatched process 2 + Loaded a process at input/proc/s2, PID: 4 PRIO: 120 + CPU 3: Put process 1 to run queue +Time slot 7 + CPU 1: Dispatched process 4 + CPU 2: Put process 3 to run queue + CPU 2: Dispatched process 1 + Loaded a process at input/proc/m0s, PID: 5 PRIO: 120 + CPU 3: Dispatched process 3 +Time slot 8 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 5 +write region=1 offset=20 value=100 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 9 + CPU 1: Put process 4 to run queue + CPU 1: Dispatched process 2 + CPU 2: Put process 1 to run queue + CPU 2: Dispatched process 4 + Loaded a process at input/proc/p1s, PID: 6 PRIO: 15 + CPU 3: Put process 3 to run queue + CPU 3: Dispatched process 1 +read region=1 offset=20 value=100 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 10 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 3 +write region=2 offset=20 value=102 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 11 + CPU 1: Put process 2 to run queue + CPU 1: Dispatched process 6 + CPU 2: Put process 4 to run queue + CPU 2: Dispatched process 2 + Loaded a process at input/proc/s0, PID: 7 PRIO: 38 + CPU 3: Put process 1 to run queue + CPU 3: Dispatched process 4 +Time slot 12 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 5 +Time slot 13 + CPU 2: Put process 2 to run queue + CPU 2: Dispatched process 1 +read region=2 offset=20 value=102 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 + CPU 1: Put process 6 to run queue + CPU 1: Dispatched process 6 + CPU 3: Put process 4 to run queue + CPU 3: Dispatched process 3 +Time slot 14 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 7 +write region=3 offset=20 value=103 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 15 + CPU 1: Put process 6 to run queue + CPU 1: Dispatched process 2 + CPU 2: Processed 1 has finished + CPU 2: Dispatched process 4 + CPU 3: Processed 3 has finished + CPU 3: Dispatched process 5 +write region=1 offset=20 value=102 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: 80000006 +Time slot 16 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 + Loaded a process at input/proc/s1, PID: 8 PRIO: 0 +write region=2 offset=1000 value=1 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: 80000006 +Time slot 17 + CPU 2: Put process 4 to run queue + CPU 2: Dispatched process 7 + CPU 1: Put process 2 to run queue + CPU 1: Dispatched process 4 + CPU 3: Put process 5 to run queue + CPU 3: Dispatched process 8 +Time slot 18 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 2 +Time slot 19 + CPU 2: Put process 7 to run queue + CPU 2: Dispatched process 5 +write region=0 offset=0 value=0 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: c0000000 + CPU 1: Put process 4 to run queue + CPU 1: Dispatched process 6 + CPU 0: Processed 2 has finished + CPU 0: Dispatched process 7 + CPU 3: Put process 8 to run queue + CPU 3: Dispatched process 4 +Time slot 20 + CPU 2: Processed 5 has finished + CPU 2: Dispatched process 8 +Time slot 21 + CPU 1: Put process 6 to run queue + CPU 1 stopped + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 + CPU 3: Processed 4 has finished + CPU 3: Dispatched process 7 +Time slot 22 + CPU 2: Put process 8 to run queue + CPU 2 stopped +Time slot 23 + CPU 0: Processed 6 has finished + CPU 0: Dispatched process 8 + CPU 3: Put process 7 to run queue + CPU 3 stopped +Time slot 24 +Time slot 25 + CPU 0: Put process 8 to run queue + CPU 0: Dispatched process 7 +Time slot 26 +Time slot 27 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 8 +Time slot 28 + CPU 0: Processed 8 has finished + CPU 0: Dispatched process 7 +Time slot 29 +Time slot 30 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 7 +Time slot 31 +Time slot 32 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 7 +Time slot 33 + CPU 0: Processed 7 has finished + CPU 0 stopped diff --git a/ossim_source_code/output/os_1_mlq_paging_small_1K.output b/ossim_source_code/output/os_1_mlq_paging_small_1K.output new file mode 100644 index 0000000..cb2fb07 --- /dev/null +++ b/ossim_source_code/output/os_1_mlq_paging_small_1K.output @@ -0,0 +1,171 @@ +Time slot 0 +ld_routine +Time slot 1 + Loaded a process at input/proc/p0s, PID: 1 PRIO: 130 + CPU 1: Dispatched process 1 +Time slot 2 + Loaded a process at input/proc/s3, PID: 2 PRIO: 39 +Time slot 3 + CPU 2: Dispatched process 2 + CPU 1: Put process 1 to run queue + CPU 3: Dispatched process 1 +Time slot 4 + Loaded a process at input/proc/m1s, PID: 3 PRIO: 15 +Time slot 5 + CPU 2: Put process 2 to run queue + CPU 0: Dispatched process 3 + CPU 1: Dispatched process 2 + CPU 3: Put process 1 to run queue +Time slot 6 + CPU 2: Dispatched process 1 + Loaded a process at input/proc/s2, PID: 4 PRIO: 120 +Time slot 7 +write region=1 offset=20 value=100 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 + CPU 1: Put process 2 to run queue + CPU 1: Dispatched process 4 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 2 + Loaded a process at input/proc/m0s, PID: 5 PRIO: 120 + CPU 3: Dispatched process 3 +Time slot 8 + CPU 2: Put process 1 to run queue + CPU 2: Dispatched process 5 +Time slot 9 + CPU 1: Put process 4 to run queue + CPU 1: Dispatched process 1 +read region=1 offset=20 value=100 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 4 + Loaded a process at input/proc/p1s, PID: 6 PRIO: 15 + CPU 3: Put process 3 to run queue + CPU 3: Dispatched process 2 +Time slot 10 + CPU 2: Put process 5 to run queue + CPU 2: Dispatched process 3 +write region=2 offset=20 value=102 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 11 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 6 + CPU 1: Put process 1 to run queue + CPU 1: Dispatched process 4 + Loaded a process at input/proc/s0, PID: 7 PRIO: 38 + CPU 3: Put process 2 to run queue + CPU 3: Dispatched process 5 +Time slot 12 + CPU 2: Put process 3 to run queue + CPU 2: Dispatched process 1 +read region=2 offset=20 value=102 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 13 + CPU 1: Put process 4 to run queue + CPU 1: Dispatched process 3 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 7 +write region=3 offset=20 value=103 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 + CPU 3: Put process 5 to run queue + CPU 3: Dispatched process 2 +Time slot 14 + CPU 2: Processed 1 has finished + CPU 2: Dispatched process 4 +Time slot 15 + CPU 1: Processed 3 has finished + CPU 1: Dispatched process 5 +write region=1 offset=20 value=102 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: 80000006 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 + CPU 3: Put process 2 to run queue + CPU 3: Dispatched process 7 +Time slot 16 +write region=2 offset=1000 value=1 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: 80000006 + CPU 2: Put process 4 to run queue + CPU 2: Dispatched process 2 + Loaded a process at input/proc/s1, PID: 8 PRIO: 0 +Time slot 17 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 4 + CPU 1: Put process 5 to run queue + CPU 1: Dispatched process 8 + CPU 2: Processed 2 has finished + CPU 2: Dispatched process 6 + CPU 3: Put process 7 to run queue + CPU 3: Dispatched process 5 +write region=0 offset=0 value=0 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: c0000000 +Time slot 18 + CPU 3: Processed 5 has finished + CPU 3: Dispatched process 7 +Time slot 19 + CPU 2: Put process 6 to run queue + CPU 2 stopped + CPU 1: Put process 8 to run queue + CPU 1: Dispatched process 6 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 8 +Time slot 20 + CPU 3: Put process 7 to run queue + CPU 3: Dispatched process 4 +Time slot 21 + CPU 1: Put process 6 to run queue + CPU 1: Dispatched process 7 + CPU 0: Put process 8 to run queue + CPU 0: Dispatched process 6 +Time slot 22 + CPU 3: Processed 4 has finished + CPU 3: Dispatched process 8 +Time slot 23 + CPU 1: Put process 7 to run queue + CPU 1 stopped + CPU 0: Processed 6 has finished + CPU 0: Dispatched process 7 +Time slot 24 + CPU 3: Put process 8 to run queue + CPU 3 stopped +Time slot 25 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 8 +Time slot 26 + CPU 0: Processed 8 has finished + CPU 0: Dispatched process 7 +Time slot 27 +Time slot 28 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 7 +Time slot 29 +Time slot 30 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 7 +Time slot 31 + CPU 0: Processed 7 has finished + CPU 0 stopped diff --git a/ossim_source_code/output/os_1_mlq_paging_small_4K.output b/ossim_source_code/output/os_1_mlq_paging_small_4K.output new file mode 100644 index 0000000..25afa10 --- /dev/null +++ b/ossim_source_code/output/os_1_mlq_paging_small_4K.output @@ -0,0 +1,172 @@ +Time slot 0 +ld_routine +Time slot 1 + Loaded a process at input/proc/p0s, PID: 1 PRIO: 130 + CPU 1: Dispatched process 1 +Time slot 2 + Loaded a process at input/proc/s3, PID: 2 PRIO: 39 +Time slot 3 + CPU 2: Dispatched process 2 + CPU 1: Put process 1 to run queue + CPU 3: Dispatched process 1 +Time slot 4 + Loaded a process at input/proc/m1s, PID: 3 PRIO: 15 +Time slot 5 + CPU 2: Put process 2 to run queue + CPU 0: Dispatched process 3 + CPU 1: Dispatched process 2 + CPU 3: Put process 1 to run queue +Time slot 6 + CPU 2: Dispatched process 1 + Loaded a process at input/proc/s2, PID: 4 PRIO: 120 +Time slot 7 +write region=1 offset=20 value=100 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 + CPU 1: Put process 2 to run queue + CPU 1: Dispatched process 4 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 2 + Loaded a process at input/proc/m0s, PID: 5 PRIO: 120 + CPU 3: Dispatched process 3 +Time slot 8 + CPU 2: Put process 1 to run queue + CPU 2: Dispatched process 5 +Time slot 9 + CPU 1: Put process 4 to run queue + CPU 1: Dispatched process 1 +read region=1 offset=20 value=100 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 4 + Loaded a process at input/proc/p1s, PID: 6 PRIO: 15 + CPU 3: Put process 3 to run queue + CPU 3: Dispatched process 2 +Time slot 10 + CPU 2: Put process 5 to run queue + CPU 2: Dispatched process 3 +write region=2 offset=20 value=102 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 11 + CPU 1: Put process 1 to run queue + CPU 1: Dispatched process 6 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 + Loaded a process at input/proc/s0, PID: 7 PRIO: 38 + CPU 3: Put process 2 to run queue + CPU 3: Dispatched process 5 +Time slot 12 + CPU 2: Put process 3 to run queue + CPU 2: Dispatched process 1 +read region=2 offset=20 value=102 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 +Time slot 13 + CPU 1: Put process 6 to run queue + CPU 1: Dispatched process 6 +write region=3 offset=20 value=103 +print_pgtbl: 0 - 1024 +00000000: 80000001 +00000004: 80000000 +00000008: 80000003 +00000012: 80000002 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 3 + CPU 3: Put process 5 to run queue + CPU 3: Dispatched process 7 +Time slot 14 + CPU 2: Processed 1 has finished + CPU 2: Dispatched process 2 +Time slot 15 + CPU 1: Put process 6 to run queue + CPU 1: Dispatched process 4 + CPU 0: Processed 3 has finished + CPU 0: Dispatched process 5 +write region=1 offset=20 value=102 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: 80000006 + CPU 3: Put process 7 to run queue + CPU 3: Dispatched process 6 +Time slot 16 + CPU 2: Put process 2 to run queue + CPU 2: Dispatched process 7 +write region=2 offset=1000 value=1 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: 80000006 + Loaded a process at input/proc/s1, PID: 8 PRIO: 0 +Time slot 17 + CPU 1: Put process 4 to run queue + CPU 1: Dispatched process 2 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 4 + CPU 3: Put process 6 to run queue + CPU 3: Dispatched process 5 +write region=0 offset=0 value=0 +print_pgtbl: 0 - 512 +00000000: 80000007 +00000004: c0000000 +Time slot 18 + CPU 2: Put process 7 to run queue + CPU 2: Dispatched process 8 + CPU 1: Processed 2 has finished + CPU 1: Dispatched process 6 + CPU 3: Processed 5 has finished + CPU 3: Dispatched process 7 +Time slot 19 + CPU 0: Put process 4 to run queue + CPU 0 stopped +Time slot 20 + CPU 2: Put process 8 to run queue + CPU 2: Dispatched process 4 + CPU 1: Put process 6 to run queue + CPU 1: Dispatched process 8 + CPU 3: Put process 7 to run queue + CPU 3: Dispatched process 6 +Time slot 21 +Time slot 22 + CPU 2: Processed 4 has finished + CPU 2: Dispatched process 7 + CPU 1: Put process 8 to run queue + CPU 1 stopped + CPU 3: Processed 6 has finished + CPU 3: Dispatched process 8 +Time slot 23 +Time slot 24 + CPU 2: Put process 7 to run queue + CPU 2 stopped + CPU 3: Put process 8 to run queue + CPU 3: Dispatched process 7 +Time slot 25 +Time slot 26 + CPU 3: Put process 7 to run queue + CPU 3: Dispatched process 8 +Time slot 27 + CPU 3: Processed 8 has finished + CPU 3: Dispatched process 7 +Time slot 28 +Time slot 29 + CPU 3: Put process 7 to run queue + CPU 3: Dispatched process 7 +Time slot 30 +Time slot 31 + CPU 3: Put process 7 to run queue + CPU 3: Dispatched process 7 +Time slot 32 + CPU 3: Processed 7 has finished + CPU 3 stopped diff --git a/ossim_source_code/output/os_1_singleCPU_mlq.output b/ossim_source_code/output/os_1_singleCPU_mlq.output new file mode 100644 index 0000000..65a13db --- /dev/null +++ b/ossim_source_code/output/os_1_singleCPU_mlq.output @@ -0,0 +1,185 @@ +Time slot 0 +ld_routine +Time slot 1 + Loaded a process at input/proc/s4, PID: 1 PRIO: 4 +Time slot 2 + Loaded a process at input/proc/s3, PID: 2 PRIO: 3 +Time slot 3 + CPU 0: Dispatched process 1 +Time slot 4 + Loaded a process at input/proc/m1s, PID: 3 PRIO: 2 +Time slot 5 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 6 + Loaded a process at input/proc/s2, PID: 4 PRIO: 3 +Time slot 7 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 + Loaded a process at input/proc/m0s, PID: 5 PRIO: 3 +Time slot 8 +Time slot 9 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 3 + Loaded a process at input/proc/p1s, PID: 6 PRIO: 2 +Time slot 10 +Time slot 11 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 4 + Loaded a process at input/proc/s0, PID: 7 PRIO: 1 +Time slot 12 +Time slot 13 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 14 +Time slot 15 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 16 + Loaded a process at input/proc/s1, PID: 8 PRIO: 0 +Time slot 17 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 18 +Time slot 19 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 20 +Time slot 21 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 22 +Time slot 23 + CPU 0: Processed 4 has finished + CPU 0: Dispatched process 2 +Time slot 24 +Time slot 25 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 26 +Time slot 27 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 28 +Time slot 29 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 30 +Time slot 31 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 32 + CPU 0: Processed 2 has finished + CPU 0: Dispatched process 5 +Time slot 33 +Time slot 34 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 1 +Time slot 35 +Time slot 36 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 8 +Time slot 37 +Time slot 38 + CPU 0: Put process 8 to run queue + CPU 0: Dispatched process 7 +Time slot 39 +Time slot 40 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 3 +Time slot 41 +Time slot 42 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 43 +Time slot 44 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 45 +Time slot 46 + CPU 0: Processed 3 has finished + CPU 0: Dispatched process 6 +Time slot 47 +Time slot 48 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 5 +Time slot 49 +Time slot 50 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 1 +Time slot 51 + CPU 0: Processed 1 has finished + CPU 0: Dispatched process 8 +Time slot 52 +Time slot 53 + CPU 0: Put process 8 to run queue + CPU 0: Dispatched process 7 +Time slot 54 +Time slot 55 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 +Time slot 56 +Time slot 57 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 5 +write region=1 offset=20 value=102 +print_pgtbl: 0 - 512 +00000000: 80000003 +00000004: 80000002 +Time slot 58 +write region=2 offset=1000 value=1 +print_pgtbl: 0 - 512 +00000000: 80000003 +00000004: 80000002 +Time slot 59 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 8 +Time slot 60 +Time slot 61 + CPU 0: Put process 8 to run queue + CPU 0: Dispatched process 7 +Time slot 62 +Time slot 63 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 +Time slot 64 +Time slot 65 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 5 +write region=0 offset=0 value=0 +print_pgtbl: 0 - 512 +00000000: 80000003 +00000004: c0000000 +Time slot 66 + CPU 0: Processed 5 has finished + CPU 0: Dispatched process 8 +Time slot 67 + CPU 0: Processed 8 has finished + CPU 0: Dispatched process 7 +Time slot 68 +Time slot 69 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 +Time slot 70 +Time slot 71 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 7 +Time slot 72 +Time slot 73 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 +Time slot 74 +Time slot 75 + CPU 0: Processed 6 has finished + CPU 0: Dispatched process 7 +Time slot 76 +Time slot 77 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 7 +Time slot 78 +Time slot 79 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 7 +Time slot 80 + CPU 0: Processed 7 has finished + CPU 0 stopped diff --git a/ossim_source_code/output/os_1_singleCPU_mlq_paging.output b/ossim_source_code/output/os_1_singleCPU_mlq_paging.output new file mode 100644 index 0000000..65a13db --- /dev/null +++ b/ossim_source_code/output/os_1_singleCPU_mlq_paging.output @@ -0,0 +1,185 @@ +Time slot 0 +ld_routine +Time slot 1 + Loaded a process at input/proc/s4, PID: 1 PRIO: 4 +Time slot 2 + Loaded a process at input/proc/s3, PID: 2 PRIO: 3 +Time slot 3 + CPU 0: Dispatched process 1 +Time slot 4 + Loaded a process at input/proc/m1s, PID: 3 PRIO: 2 +Time slot 5 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 6 + Loaded a process at input/proc/s2, PID: 4 PRIO: 3 +Time slot 7 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 + Loaded a process at input/proc/m0s, PID: 5 PRIO: 3 +Time slot 8 +Time slot 9 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 3 + Loaded a process at input/proc/p1s, PID: 6 PRIO: 2 +Time slot 10 +Time slot 11 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 4 + Loaded a process at input/proc/s0, PID: 7 PRIO: 1 +Time slot 12 +Time slot 13 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 14 +Time slot 15 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 16 + Loaded a process at input/proc/s1, PID: 8 PRIO: 0 +Time slot 17 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 18 +Time slot 19 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 20 +Time slot 21 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 22 +Time slot 23 + CPU 0: Processed 4 has finished + CPU 0: Dispatched process 2 +Time slot 24 +Time slot 25 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 26 +Time slot 27 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 28 +Time slot 29 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 30 +Time slot 31 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 32 + CPU 0: Processed 2 has finished + CPU 0: Dispatched process 5 +Time slot 33 +Time slot 34 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 1 +Time slot 35 +Time slot 36 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 8 +Time slot 37 +Time slot 38 + CPU 0: Put process 8 to run queue + CPU 0: Dispatched process 7 +Time slot 39 +Time slot 40 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 3 +Time slot 41 +Time slot 42 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 43 +Time slot 44 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 45 +Time slot 46 + CPU 0: Processed 3 has finished + CPU 0: Dispatched process 6 +Time slot 47 +Time slot 48 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 5 +Time slot 49 +Time slot 50 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 1 +Time slot 51 + CPU 0: Processed 1 has finished + CPU 0: Dispatched process 8 +Time slot 52 +Time slot 53 + CPU 0: Put process 8 to run queue + CPU 0: Dispatched process 7 +Time slot 54 +Time slot 55 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 +Time slot 56 +Time slot 57 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 5 +write region=1 offset=20 value=102 +print_pgtbl: 0 - 512 +00000000: 80000003 +00000004: 80000002 +Time slot 58 +write region=2 offset=1000 value=1 +print_pgtbl: 0 - 512 +00000000: 80000003 +00000004: 80000002 +Time slot 59 + CPU 0: Put process 5 to run queue + CPU 0: Dispatched process 8 +Time slot 60 +Time slot 61 + CPU 0: Put process 8 to run queue + CPU 0: Dispatched process 7 +Time slot 62 +Time slot 63 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 +Time slot 64 +Time slot 65 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 5 +write region=0 offset=0 value=0 +print_pgtbl: 0 - 512 +00000000: 80000003 +00000004: c0000000 +Time slot 66 + CPU 0: Processed 5 has finished + CPU 0: Dispatched process 8 +Time slot 67 + CPU 0: Processed 8 has finished + CPU 0: Dispatched process 7 +Time slot 68 +Time slot 69 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 +Time slot 70 +Time slot 71 + CPU 0: Put process 6 to run queue + CPU 0: Dispatched process 7 +Time slot 72 +Time slot 73 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 6 +Time slot 74 +Time slot 75 + CPU 0: Processed 6 has finished + CPU 0: Dispatched process 7 +Time slot 76 +Time slot 77 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 7 +Time slot 78 +Time slot 79 + CPU 0: Put process 7 to run queue + CPU 0: Dispatched process 7 +Time slot 80 + CPU 0: Processed 7 has finished + CPU 0 stopped diff --git a/ossim_source_code/output/sched.output b/ossim_source_code/output/sched.output new file mode 100644 index 0000000..edfe4cf --- /dev/null +++ b/ossim_source_code/output/sched.output @@ -0,0 +1,42 @@ +Time slot 0 +ld_routine + Loaded a process at input/proc/p1s, PID: 1 PRIO: 1 + CPU 1: Dispatched process 1 +Time slot 1 + Loaded a process at input/proc/p1s, PID: 2 PRIO: 0 +Time slot 2 + Loaded a process at input/proc/p1s, PID: 3 PRIO: 0 +Time slot 3 + CPU 0: Dispatched process 3 +Time slot 4 + CPU 1: Put process 1 to run queue + CPU 1: Dispatched process 2 +Time slot 5 +Time slot 6 +Time slot 7 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 1 +Time slot 8 + CPU 1: Put process 2 to run queue + CPU 1: Dispatched process 2 +Time slot 9 +Time slot 10 +Time slot 11 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 3 +Time slot 12 + CPU 1: Put process 2 to run queue + CPU 1: Dispatched process 1 +Time slot 13 +Time slot 14 + CPU 1: Processed 1 has finished + CPU 1: Dispatched process 2 +Time slot 15 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 16 + CPU 1: Processed 2 has finished + CPU 1 stopped +Time slot 17 + CPU 0: Processed 3 has finished + CPU 0 stopped diff --git a/ossim_source_code/output/sched_0.output b/ossim_source_code/output/sched_0.output new file mode 100644 index 0000000..0676714 --- /dev/null +++ b/ossim_source_code/output/sched_0.output @@ -0,0 +1,68 @@ +Time slot 0 +ld_routine + Loaded a process at input/proc/s0, PID: 1 PRIO: 4 +Time slot 1 + CPU 0: Dispatched process 1 + Loaded a process at input/proc/s0, PID: 2 PRIO: 0 +Time slot 2 +Time slot 3 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 1 +Time slot 4 +Time slot 5 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 6 +Time slot 7 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 8 +Time slot 9 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 10 +Time slot 11 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 12 +Time slot 13 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 14 +Time slot 15 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 16 +Time slot 17 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 18 +Time slot 19 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 20 +Time slot 21 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 22 +Time slot 23 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 24 +Time slot 25 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 26 +Time slot 27 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 28 + CPU 0: Processed 1 has finished + CPU 0: Dispatched process 2 +Time slot 29 +Time slot 30 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 31 + CPU 0: Processed 2 has finished + CPU 0 stopped diff --git a/ossim_source_code/output/sched_1.output b/ossim_source_code/output/sched_1.output new file mode 100644 index 0000000..9c338f7 --- /dev/null +++ b/ossim_source_code/output/sched_1.output @@ -0,0 +1,132 @@ +Time slot 0 +ld_routine + Loaded a process at input/proc/s0, PID: 1 PRIO: 4 +Time slot 1 + CPU 0: Dispatched process 1 + Loaded a process at input/proc/s0, PID: 2 PRIO: 0 +Time slot 2 + Loaded a process at input/proc/s0, PID: 3 PRIO: 0 +Time slot 3 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 1 + Loaded a process at input/proc/s0, PID: 4 PRIO: 0 +Time slot 4 +Time slot 5 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 4 +Time slot 6 +Time slot 7 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 8 +Time slot 9 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 10 +Time slot 11 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 12 +Time slot 13 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 14 +Time slot 15 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 16 +Time slot 17 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 18 +Time slot 19 + CPU 0: Put process 4 to run queue + CPU 0: Dispatched process 4 +Time slot 20 + CPU 0: Processed 4 has finished + CPU 0: Dispatched process 3 +Time slot 21 +Time slot 22 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 23 +Time slot 24 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 25 +Time slot 26 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 27 +Time slot 28 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 29 +Time slot 30 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 31 +Time slot 32 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 33 +Time slot 34 + CPU 0: Put process 3 to run queue + CPU 0: Dispatched process 3 +Time slot 35 + CPU 0: Processed 3 has finished + CPU 0: Dispatched process 2 +Time slot 36 +Time slot 37 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 38 +Time slot 39 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 40 +Time slot 41 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 42 +Time slot 43 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 44 +Time slot 45 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 46 +Time slot 47 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 48 +Time slot 49 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 50 +Time slot 51 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 52 +Time slot 53 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 54 +Time slot 55 + CPU 0: Put process 1 to run queue + CPU 0: Dispatched process 2 +Time slot 56 +Time slot 57 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 1 +Time slot 58 + CPU 0: Processed 1 has finished + CPU 0: Dispatched process 2 +Time slot 59 +Time slot 60 + CPU 0: Put process 2 to run queue + CPU 0: Dispatched process 2 +Time slot 61 + CPU 0: Processed 2 has finished + CPU 0 stopped diff --git a/ossim_source_code/src/cpu.c b/ossim_source_code/src/cpu.c new file mode 100644 index 0000000..b8deb25 --- /dev/null +++ b/ossim_source_code/src/cpu.c @@ -0,0 +1,102 @@ + +#include "cpu.h" +#include "mem.h" +#include "mm.h" + +int calc(struct pcb_t * proc) { + return ((unsigned long)proc & 0UL); +} + +int alloc(struct pcb_t * proc, uint32_t size, uint32_t reg_index) { + addr_t addr = alloc_mem(size, proc); + if (addr == 0) { + return 1; + }else{ + proc->regs[reg_index] = addr; + return 0; + } +} + +int free_data(struct pcb_t * proc, uint32_t reg_index) { + return free_mem(proc->regs[reg_index], proc); +} + +int read( + struct pcb_t * proc, // Process executing the instruction + uint32_t source, // Index of source register + uint32_t offset, // Source address = [source] + [offset] + uint32_t destination) { // Index of destination register + + BYTE data; + if (read_mem(proc->regs[source] + offset, proc, &data)) { + proc->regs[destination] = data; + return 0; + }else{ + return 1; + } +} + +int write( + struct pcb_t * proc, // Process executing the instruction + BYTE data, // Data to be wrttien into memory + uint32_t destination, // Index of destination register + uint32_t offset) { // Destination address = + // [destination] + [offset] + return write_mem(proc->regs[destination] + offset, proc, data); +} + +int run(struct pcb_t * proc) { + /* Check if Program Counter point to the proper instruction */ + if (proc->pc >= proc->code->size) { + return 1; + } + + struct inst_t ins = proc->code->text[proc->pc]; + proc->pc++; + int stat = 1; + switch (ins.opcode) { + case CALC: + stat = calc(proc); + break; + case ALLOC: +#ifdef MM_PAGING + stat = pgalloc(proc, ins.arg_0, ins.arg_1); + +#else + stat = alloc(proc, ins.arg_0, ins.arg_1); +#endif + break; +#ifdef MM_PAGING + case MALLOC: + stat = pgmalloc(proc, ins.arg_0, ins.arg_1); + break; +#endif + case FREE: +#ifdef MM_PAGING + stat = pgfree_data(proc, ins.arg_0); +#else + stat = free_data(proc, ins.arg_0); +#endif + break; + case READ: +#ifdef MM_PAGING + stat = pgread(proc, ins.arg_0, ins.arg_1, ins.arg_2); +#else + stat = read(proc, ins.arg_0, ins.arg_1, ins.arg_2); +#endif + break; + case WRITE: +#ifdef MM_PAGING + stat = pgwrite(proc, ins.arg_0, ins.arg_1, ins.arg_2); +#else + stat = write(proc, ins.arg_0, ins.arg_1, ins.arg_2); +#endif + break; + default: + stat = 1; + } + return stat; + +} + + diff --git a/ossim_source_code/src/loader.c b/ossim_source_code/src/loader.c new file mode 100644 index 0000000..5f8e56a --- /dev/null +++ b/ossim_source_code/src/loader.c @@ -0,0 +1,108 @@ + +#include "loader.h" +#include +#include +#include + +static uint32_t avail_pid = 1; + +#define OPT_CALC "calc" +#define OPT_ALLOC "alloc" +#define OPT_FREE "free" +#define OPT_READ "read" +#define OPT_WRITE "write" +#ifdef MM_PAGING +#define OPT_MALLOC "malloc" +#endif + +static enum ins_opcode_t get_opcode(char * opt) { + if (!strcmp(opt, OPT_CALC)) { + return CALC; + }else if (!strcmp(opt, OPT_ALLOC)) { + return ALLOC; +#ifdef MM_PAGING + }else if (!strcmp(opt, OPT_MALLOC)) { + return MALLOC; +#endif + }else if (!strcmp(opt, OPT_FREE)) { + return FREE; + }else if (!strcmp(opt, OPT_READ)) { + return READ; + }else if (!strcmp(opt, OPT_WRITE)) { + return WRITE; + }else{ + printf("Opcode: %s\n", opt); + exit(1); + } +} + +struct pcb_t * load(const char * path) { + /* Create new PCB for the new process */ + struct pcb_t * proc = (struct pcb_t * )malloc(sizeof(struct pcb_t)); + proc->pid = avail_pid; + avail_pid++; + proc->page_table = + (struct page_table_t*)malloc(sizeof(struct page_table_t)); + proc->bp = PAGE_SIZE; + proc->pc = 0; + + /* Read process code from file */ + FILE * file; + // printf(path); + if ((file = fopen(path, "r")) == NULL) { + printf("Cannot find process description at '%s'\n", path); + exit(1); + } + char opcode[10]; + proc->code = (struct code_seg_t*)malloc(sizeof(struct code_seg_t)); + fscanf(file, "%u %u", &proc->priority, &proc->code->size); + proc->code->text = (struct inst_t*)malloc( + sizeof(struct inst_t) * proc->code->size + ); + uint32_t i = 0; + for (i = 0; i < proc->code->size; i++) { + fscanf(file, "%s", opcode); + proc->code->text[i].opcode = get_opcode(opcode); + switch(proc->code->text[i].opcode) { + case CALC: + break; + case ALLOC: + fscanf( + file, + "%u %u\n", + &proc->code->text[i].arg_0, + &proc->code->text[i].arg_1 + ); + break; +#ifdef MM_PAGING + case MALLOC: + fscanf( + file, + "%u %u\n", + &proc->code->text[i].arg_0, + &proc->code->text[i].arg_1 + ); +#endif + case FREE: + fscanf(file, "%u\n", &proc->code->text[i].arg_0); + break; + case READ: + case WRITE: + fscanf( + file, + "%u %u %u\n", + &proc->code->text[i].arg_0, + &proc->code->text[i].arg_1, + &proc->code->text[i].arg_2 + ); + break; + default: + printf("Opcode: %s\n", opcode); + exit(1); + } + } + return proc; +} + + + diff --git a/ossim_source_code/src/mem.c b/ossim_source_code/src/mem.c new file mode 100644 index 0000000..187108f --- /dev/null +++ b/ossim_source_code/src/mem.c @@ -0,0 +1,173 @@ + +#include "mem.h" +#include "stdlib.h" +#include "string.h" +#include +#include + +static BYTE _ram[RAM_SIZE]; + +static struct { + uint32_t proc; // ID of process currently uses this page + int index; // Index of the page in the list of pages allocated + // to the process. + int next; // The next page in the list. -1 if it is the last + // page. +} _mem_stat [NUM_PAGES]; + +static pthread_mutex_t mem_lock; + +void init_mem(void) { + memset(_mem_stat, 0, sizeof(*_mem_stat) * NUM_PAGES); + memset(_ram, 0, sizeof(BYTE) * RAM_SIZE); + pthread_mutex_init(&mem_lock, NULL); +} + +/* get offset of the virtual address */ +static addr_t get_offset(addr_t addr) { + return addr & ~((~0U) << OFFSET_LEN); +} + +/* get the first layer index */ +static addr_t get_first_lv(addr_t addr) { + return addr >> (OFFSET_LEN + PAGE_LEN); +} + +/* get the second layer index */ +static addr_t get_second_lv(addr_t addr) { + return (addr >> OFFSET_LEN) - (get_first_lv(addr) << PAGE_LEN); +} + +/* Search for page table table from the a segment table */ +static struct trans_table_t * get_trans_table( + addr_t index, // Segment level index + struct page_table_t * page_table) { // first level table + + /* DO NOTHING HERE. This mem is obsoleted */ + + int i; + for (i = 0; i < page_table->size; i++) { + // Enter your code here + } + return NULL; + +} + +/* Translate virtual address to physical address. If [virtual_addr] is valid, + * return 1 and write its physical counterpart to [physical_addr]. + * Otherwise, return 0 */ +static int translate( + addr_t virtual_addr, // Given virtual address + addr_t * physical_addr, // Physical address to be returned + struct pcb_t * proc) { // Process uses given virtual address + + /* Offset of the virtual address */ + addr_t offset = get_offset(virtual_addr); + offset++; offset--; + /* The first layer index */ + addr_t first_lv = get_first_lv(virtual_addr); + /* The second layer index */ + addr_t second_lv = get_second_lv(virtual_addr); + + /* Search in the first level */ + struct trans_table_t * trans_table = NULL; + trans_table = get_trans_table(first_lv, proc->page_table); + if (trans_table == NULL) { + return 0; + } + + int i; + for (i = 0; i < trans_table->size; i++) { + if (trans_table->table[i].v_index == second_lv) { + /* DO NOTHING HERE. This mem is obsoleted */ + return 1; + } + } + return 0; +} + +addr_t alloc_mem(uint32_t size, struct pcb_t * proc) { + pthread_mutex_lock(&mem_lock); + addr_t ret_mem = 0; + /* DO NOTHING HERE. This mem is obsoleted */ + + uint32_t num_pages = (size % PAGE_SIZE) ? size / PAGE_SIZE : + size / PAGE_SIZE + 1; // Number of pages we will use + int mem_avail = 0; // We could allocate new memory region or not? + + /* First we must check if the amount of free memory in + * virtual address space and physical address space is + * large enough to represent the amount of required + * memory. If so, set 1 to [mem_avail]. + * Hint: check [proc] bit in each page of _mem_stat + * to know whether this page has been used by a process. + * For virtual memory space, check bp (break pointer). + * */ + + if (mem_avail) { + /* We could allocate new memory region to the process */ + ret_mem = proc->bp; + proc->bp += num_pages * PAGE_SIZE; + /* Update status of physical pages which will be allocated + * to [proc] in _mem_stat. Tasks to do: + * - Update [proc], [index], and [next] field + * - Add entries to segment table page tables of [proc] + * to ensure accesses to allocated memory slot is + * valid. */ + } + pthread_mutex_unlock(&mem_lock); + return ret_mem; +} + +int free_mem(addr_t address, struct pcb_t * proc) { + /* DO NOTHING HERE. This mem is obsoleted */ + return 0; +} + +int read_mem(addr_t address, struct pcb_t * proc, BYTE * data) { + addr_t physical_addr; + if (translate(address, &physical_addr, proc)) { + *data = _ram[physical_addr]; + return 0; + }else{ + return 1; + } +} + +int write_mem(addr_t address, struct pcb_t * proc, BYTE data) { + addr_t physical_addr; + if (translate(address, &physical_addr, proc)) { + _ram[physical_addr] = data; + return 0; + }else{ + return 1; + } +} + +void dump(void) { + int i; + for (i = 0; i < NUM_PAGES; i++) { + if (_mem_stat[i].proc != 0) { + printf("%03d: ", i); + printf("%05x-%05x - PID: %02d (idx %03d, nxt: %03d)\n", + i << OFFSET_LEN, + ((i + 1) << OFFSET_LEN) - 1, + _mem_stat[i].proc, + _mem_stat[i].index, + _mem_stat[i].next + ); + int j; + for ( j = i << OFFSET_LEN; + j < ((i+1) << OFFSET_LEN) - 1; + j++) { + + if (_ram[j] != 0) { + printf("\t%05x: %02x\n", j, _ram[j]); + } + + } + } + } +} + + diff --git a/ossim_source_code/src/mm-memphy.c b/ossim_source_code/src/mm-memphy.c new file mode 100644 index 0000000..880a858 --- /dev/null +++ b/ossim_source_code/src/mm-memphy.c @@ -0,0 +1,199 @@ +//#ifdef MM_PAGING +/* + * PAGING based Memory Management + * Memory physical module mm/mm-memphy.c + */ + +#include "mm.h" +#include + +/* + * MEMPHY_mv_csr - move MEMPHY cursor + * @mp: memphy struct + * @offset: offset + */ +int MEMPHY_mv_csr(struct memphy_struct *mp, int offset) +{ + int numstep = 0; + + mp->cursor = 0; + while(numstep < offset && numstep < mp->maxsz){ + /* Traverse sequentially */ + mp->cursor = (mp->cursor + 1) % mp->maxsz; + numstep++; + } + + return 0; +} + +/* + * MEMPHY_seq_read - read MEMPHY device + * @mp: memphy struct + * @addr: address + * @value: obtained value + */ +int MEMPHY_seq_read(struct memphy_struct *mp, int addr, BYTE *value) +{ + if (mp == NULL) + return -1; + + if (!mp->rdmflg) + return -1; /* Not compatible mode for sequential read */ + + MEMPHY_mv_csr(mp, addr); + *value = (BYTE) mp->storage[addr]; + + return 0; +} + +/* + * MEMPHY_read read MEMPHY device + * @mp: memphy struct + * @addr: address + * @value: obtained value + */ +int MEMPHY_read(struct memphy_struct * mp, int addr, BYTE *value) +{ + if (mp == NULL) + return -1; + + if (mp->rdmflg) + *value = mp->storage[addr]; + else /* Sequential access device */ + return MEMPHY_seq_read(mp, addr, value); + + return 0; +} + +/* + * MEMPHY_seq_write - write MEMPHY device + * @mp: memphy struct + * @addr: address + * @data: written data + */ +int MEMPHY_seq_write(struct memphy_struct * mp, int addr, BYTE value) +{ + + if (mp == NULL) + return -1; + + if (!mp->rdmflg) + return -1; /* Not compatible mode for sequential read */ + + MEMPHY_mv_csr(mp, addr); + mp->storage[addr] = value; + + return 0; +} + +/* + * MEMPHY_write-write MEMPHY device + * @mp: memphy struct + * @addr: address + * @data: written data + */ +int MEMPHY_write(struct memphy_struct * mp, int addr, BYTE data) +{ + if (mp == NULL) + return -1; + + if (mp->rdmflg) + mp->storage[addr] = data; + else /* Sequential access device */ + return MEMPHY_seq_write(mp, addr, data); + + return 0; +} + +/* + * MEMPHY_format-format MEMPHY device + * @mp: memphy struct + */ +int MEMPHY_format(struct memphy_struct *mp, int pagesz) +{ + /* This setting come with fixed constant PAGESZ */ + int numfp = mp->maxsz / pagesz; + struct framephy_struct *newfst, *fst; + int iter = 0; + + if (numfp <= 0) + return -1; + + /* Init head of free framephy list */ + fst = malloc(sizeof(struct framephy_struct)); + fst->fpn = iter; + mp->free_fp_list = fst; + + /* We have list with first element, fill in the rest num-1 element member*/ + for (iter = 1; iter < numfp ; iter++) + { + newfst = malloc(sizeof(struct framephy_struct)); + newfst->fpn = iter; + newfst->fp_next = NULL; + fst->fp_next = newfst; + fst = newfst; + } + + return 0; +} + +int MEMPHY_get_freefp(struct memphy_struct *mp, int *retfpn) +{ + struct framephy_struct *fp = mp->free_fp_list; + + if (fp == NULL) + return -1; + + *retfpn = fp->fpn; + mp->free_fp_list = fp->fp_next; + + /* MEMPHY is iteratively used up until its exhausted + * No garbage collector acting then it not been released + */ + free(fp); + + return 0; +} + +int MEMPHY_dump(struct memphy_struct * mp) +{ + /*TODO dump memphy contnt mp->storage + * for tracing the memory content + */ + + return 0; +} + +int MEMPHY_put_freefp(struct memphy_struct *mp, int fpn) +{ + struct framephy_struct *fp = mp->free_fp_list; + struct framephy_struct *newnode = malloc(sizeof(struct framephy_struct)); + + /* Create new node with value fpn */ + newnode->fpn = fpn; + newnode->fp_next = fp; + mp->free_fp_list = newnode; + + return 0; +} + + +/* + * Init MEMPHY struct + */ +int init_memphy(struct memphy_struct *mp, int max_size, int randomflg) +{ + mp->storage = (BYTE *)malloc(max_size*sizeof(BYTE)); + mp->maxsz = max_size; + + MEMPHY_format(mp,PAGING_PAGESZ); + + mp->rdmflg = (randomflg != 0)?1:0; + + if (!mp->rdmflg ) /* Not Ramdom acess device, then it serial device*/ + mp->cursor = 0; + + return 0; +} + +//#endif diff --git a/ossim_source_code/src/mm-vm.c b/ossim_source_code/src/mm-vm.c new file mode 100644 index 0000000..c262322 --- /dev/null +++ b/ossim_source_code/src/mm-vm.c @@ -0,0 +1,649 @@ +//#ifdef MM_PAGING +/* + * PAGING based Memory Management + * Virtual memory module mm/mm-vm.c + */ + +#include "string.h" +#include "mm.h" +#include +#include + +/*enlist_vm_freerg_list - add new rg to freerg_list + *@mm: memory region + *@rg_elmt: new region + * + */ +int enlist_vm_freerg_list(struct mm_struct *mm, struct vm_rg_struct rg_elmt) +{ + struct vm_rg_struct *new_node; + struct vm_rg_struct *head = mm->mmap->vm_freerg_list; + + // Check for invalid region + if (rg_elmt.rg_start >= rg_elmt.rg_end) + return -1; + + // Dynamically allocate memory for the new region + new_node = (struct vm_rg_struct *)malloc(sizeof(struct vm_rg_struct)); + if (!new_node) + return -1; // Allocation failed + + // Copy the data into the new node + *new_node = rg_elmt; + new_node->rg_next = head; + + // Update the list head + mm->mmap->vm_freerg_list = new_node; + + return 0; +} + + +/*get_vma_by_num - get vm area by numID + *@mm: memory region + *@vmaid: ID vm area to alloc memory region + * + */ +//get địa chỉ ô vma +struct vm_area_struct *get_vma_by_num(struct mm_struct *mm, int vmaid) +{ + struct vm_area_struct *pvma= mm->mmap; + + if(mm->mmap == NULL) + return NULL; + + int vmait = 0; + + while (vmait < vmaid) + { + if(pvma == NULL) + return NULL; + + vmait++; + pvma = pvma->vm_next; + } + + return pvma; +} + +/*get_symrg_byid - get mem region by region ID + *@mm: memory region + *@rgid: region ID act as symbol index of variable + * + */ +struct vm_rg_struct *get_symrg_byid(struct mm_struct *mm, int rgid) +{ + if(rgid < 0 || rgid > PAGING_MAX_SYMTBL_SZ) + return NULL; + + return &mm->symrgtbl[rgid]; +} + +/*__alloc - allocate a region memory + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@rgid: memory region ID (used to identify variable in symbole table) + *@size: allocated size + *@alloc_addr: address of allocated memory region + * + */ +int __alloc(struct pcb_t *caller, int vmaid, int rgid, int size, int *alloc_addr) +{ + /*Allocate at the toproof */ + struct vm_rg_struct rgnode; + + /* TODO: commit the vmaid */ + rgnode.vmaid = vmaid; + + if (get_free_vmrg_area(caller, vmaid, size, &rgnode) == 0) + { + //symrgtbl là vm_rg_struct + caller->mm->symrgtbl[rgid].rg_start = rgnode.rg_start; + caller->mm->symrgtbl[rgid].rg_end = rgnode.rg_end; + + caller->mm->symrgtbl[rgid].vmaid = rgnode.vmaid; + + *alloc_addr = rgnode.rg_start; + + return 0; + } + + /* TODO: get_free_vmrg_area FAILED handle the region management (Fig.6)*/ + if (get_free_vmrg_area(caller, vmaid, size, &rgnode) == -1 ){return -1;} + /* TODO retrive current vma if needed, current comment out due to compiler redundant warning*/ + /*Attempt to increate limit to get space */ + + struct vm_area_struct *cur_vma = get_vma_by_num(caller->mm, vmaid); + int inc_sz = PAGING_PAGE_ALIGNSZ(size); + int inc_limit_ret; + + /* TODO retrive old_sbrk if needed, current comment out due to compiler redundant warning*/ + int old_sbrk = cur_vma->sbrk; + + /* TODO INCREASE THE LIMIT + * inc_vma_limit(caller, vmaid, inc_sz) + */ + if (inc_vma_limit(caller, vmaid, inc_sz, &inc_limit_ret) < 0) return -1; + + cur_vma->sbrk += inc_sz; + /* TODO: commit the limit increment */ + if ( old_sbrk + size > cur_vma -> vm_end ) + { + if ( inc_vma_limit ( caller , vmaid , inc_sz, &inc_limit_ret ) < 0) + { + struct framephy_struct * frm_lst = NULL ; + struct vm_rg_struct * ret_rg = malloc ( sizeof ( struct vm_rg_struct ) ); + int pages = ( inc_sz / PAGING_PAGESZ ); + ret_rg -> rg_start = ret_rg -> rg_end = old_sbrk ; + ret_rg -> rg_next = NULL ; + alloc_pages_range ( caller , pages , & frm_lst ); + vmap_page_range ( caller , old_sbrk , pages , frm_lst , ret_rg ); + caller ->mm -> symrgtbl [ rgid ]. rg_start = ret_rg -> rg_start ; + caller ->mm -> symrgtbl [ rgid ]. rg_end = ret_rg -> rg_end ; + cur_vma -> sbrk += ret_rg -> rg_end - ret_rg -> rg_start ; + return 0; + } + } + + /* Successful increase limit */ + caller ->mm -> symrgtbl [ rgid ]. rg_start = old_sbrk ; + caller ->mm -> symrgtbl [ rgid ]. rg_end = old_sbrk + size ; + /* TODO: commit the allocation address + // *alloc_addr = ... + */ + *alloc_addr = rgnode.rg_start; + + return 0; +} + +/*__free - remove a region memory + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@rgid: memory region ID (used to identify variable in symbole table) + *@size: allocated size + * + */ +int __free(struct pcb_t *caller, int rgid) +{ + struct vm_rg_struct rgnode; + + // Dummy initialization for avoding compiler dummay warning + // in incompleted TODO code rgnode will overwrite through implementing + // the manipulation of rgid later + rgnode.vmaid = 0; //dummy initialization + rgnode.vmaid = 1; //dummy initialization + + if(rgid < 0 || rgid > PAGING_MAX_SYMTBL_SZ) + return -1; + + /* TODO: Manage the collect freed region to freerg_list */ + struct vm_rg_struct *sym_rg = &caller->mm->symrgtbl[rgid]; + rgnode.rg_start = sym_rg->rg_start; + rgnode.rg_end = sym_rg->rg_end; + rgnode.vmaid = sym_rg->vmaid; + + /*enlist the obsoleted memory region */ + enlist_vm_freerg_list(caller->mm, rgnode); + + return 0; +} + +/*pgalloc - PAGING-based allocate a region memory + *@proc: Process executing the instruction + *@size: allocated size + *@reg_index: memory region ID (used to identify variable in symbole table) + */ +int pgalloc(struct pcb_t *proc, uint32_t size, uint32_t reg_index) +{ + int addr; + + /* By default using vmaid = 0 */ + return __alloc(proc, 0, reg_index, size, &addr); +} + +/*pgmalloc - PAGING-based allocate a region memory + *@proc: Process executing the instruction + *@size: allocated size + *@reg_index: memory region ID (used to identify vaiable in symbole table) + */ +int pgmalloc(struct pcb_t *proc, uint32_t size, uint32_t reg_index) +{ + int addr; + + /* By default using vmaid = 1 */ + return __alloc(proc, 1, reg_index, size, &addr); +} + +/*pgfree - PAGING-based free a region memory + *@proc: Process executing the instruction + *@size: allocated size + *@reg_index: memory region ID (used to identify variable in symbole table) + */ + +int pgfree_data(struct pcb_t *proc, uint32_t reg_index) +{ + return __free(proc, reg_index); +} + +/*pg_getpage - get the page in ram + *@mm: memory region + *@pagenum: PGN + *@framenum: return FPN + *@caller: caller + * + */ +int pg_getpage(struct mm_struct *mm, int pgn, int *fpn, struct pcb_t *caller) +{ + uint32_t pte = mm->pgd[pgn]; + + if (!PAGING_PTE_PAGE_PRESENT(pte)) + { + // Page không tồn tại, cần đưa vào bộ nhớ + int vicpgn, swpfpn, vicfpn; + uint32_t vicpte; + + int tgtfpn = PAGING_PTE_SWP(pte); // Frame mục tiêu trong swap + + // Tìm victim page + if (find_victim_page(caller->mm, &vicpgn) < 0) + return -1; + + vicpte = caller->mm->pgd[vicpgn]; + vicfpn = PAGING_OFFST(vicpte); + + // Lấy free frame từ MEMSWP + if (MEMPHY_get_freefp(caller->active_mswp, &swpfpn) < 0) + { + struct memphy_struct **mswpit = caller->mswp; + for (int i = 0; i < PAGING_MAX_MMSWP; i++) + { + struct memphy_struct *tmp_swp = mswpit[i]; + if (MEMPHY_get_freefp(tmp_swp, &swpfpn) == 0) + { + __swap_cp_page(caller->mram, vicfpn, tmp_swp, swpfpn); + caller->active_mswp = tmp_swp; + break; + } + } + } + else + { + __swap_cp_page(caller->mram, vicfpn, caller->active_mswp, swpfpn); + } + + // Swap frame từ MEMRAM sang MEMSWP và ngược lại + __swap_cp_page(caller->active_mswp, tgtfpn, caller->mram, vicfpn); + + // Cập nhật page table + MEMPHY_put_freefp(caller->active_mswp, tgtfpn); + // swptype = 1 + pte_set_swap(&caller->mm->pgd[vicpgn], 1, swpfpn); + + // Đánh dấu trạng thái online của page mục tiêu + pte_set_fpn(&caller->mm->pgd[pgn], vicfpn); + pte = caller->mm->pgd[pgn]; + + + + *fpn = PAGING_OFFST(pte); + return 0; +} +} + + /* Do swap frame from MEMRAM to MEMSWP and vice versa*/ + /* Copy victim frame to swap */ + //__swap_cp_page(); + /* Copy target frame from swap to mem */ + //__swap_cp_page(); + + /* Update page table */ + //pte_set_swap() &mm->pgd; + + /* Update its online status of the target page */ + //pte_set_fpn() & mm->pgd[pgn]; + // pte_set_fpn(&pte, tgtfpn); + + // enlist_pgn_node(&caller->mm->fifo_pgn,pgn); + // } + + // *fpn = PAGING_PTE_FPN(pte); + + // return 0; + + +/*pg_getval - read value at given offset + *@mm: memory region + *@addr: virtual address to acess + *@value: value + * + */ +int pg_getval(struct mm_struct *mm, int addr, BYTE *data, struct pcb_t *caller) +{ + int pgn = PAGING_PGN(addr); + int off = PAGING_OFFST(addr); + int fpn; + + /* Get the page to MEMRAM, swap from MEMSWAP if needed */ + if(pg_getpage(mm, pgn, &fpn, caller) != 0) + return -1; /* invalid page access */ + + int phyaddr = (fpn << PAGING_ADDR_FPN_LOBIT) + off; + + MEMPHY_read(caller->mram,phyaddr, data); + + return 0; +} + +/*pg_setval - write value to given offset + *@mm: memory region + *@addr: virtual address to acess + *@value: value + * + */ +int pg_setval(struct mm_struct *mm, int addr, BYTE value, struct pcb_t *caller) +{ + int pgn = PAGING_PGN(addr); + int off = PAGING_OFFST(addr); + int fpn; + + /* Get the page to MEMRAM, swap from MEMSWAP if needed */ + if(pg_getpage(mm, pgn, &fpn, caller) != 0) + return -1; /* invalid page access */ + + int phyaddr = (fpn << PAGING_ADDR_FPN_LOBIT) + off; + + MEMPHY_write(caller->mram,phyaddr, value); + + return 0; +} + +/*__read - read value in region memory + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@offset: offset to acess in memory region + *@rgid: memory region ID (used to identify variable in symbole table) + *@size: allocated size + * + */ +int __read(struct pcb_t *caller, int rgid, int offset, BYTE *data) +{ + struct vm_rg_struct *currg = get_symrg_byid(caller->mm, rgid); + int vmaid = currg->vmaid; + + struct vm_area_struct *cur_vma = get_vma_by_num(caller->mm, vmaid); + + if(currg == NULL || cur_vma == NULL) /* Invalid memory identify */ + return -1; + + pg_getval(caller->mm, currg->rg_start + offset, data, caller); + + return 0; +} + + +/*pgwrite - PAGING-based read a region memory */ +int pgread( + struct pcb_t * proc, // Process executing the instruction + uint32_t source, // Index of source register + uint32_t offset, // Source address = [source] + [offset] + uint32_t destination) +{ + BYTE data; + int val = __read(proc, source, offset, &data); + + destination = (uint32_t) data; +#ifdef IODUMP + printf("read region=%d offset=%d value=%d\n", source, offset, data); +#ifdef PAGETBL_DUMP + print_pgtbl(proc, 0, -1); //print max TBL +#endif + MEMPHY_dump(proc->mram); +#endif + + return val; +} + +/*__write - write a region memory + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@offset: offset to acess in memory region + *@rgid: memory region ID (used to identify variable in symbole table) + *@size: allocated size + * + */ +int __write(struct pcb_t *caller, int rgid, int offset, BYTE value) +{ + struct vm_rg_struct *currg = get_symrg_byid(caller->mm, rgid); + int vmaid = currg->vmaid; + + struct vm_area_struct *cur_vma = get_vma_by_num(caller->mm, vmaid); + + if(currg == NULL || cur_vma == NULL) /* Invalid memory identify */ + return -1; + + pg_setval(caller->mm, currg->rg_start + offset, value, caller); + + return 0; +} + +/*pgwrite - PAGING-based write a region memory */ +int pgwrite( + struct pcb_t * proc, // Process executing the instruction + BYTE data, // Data to be wrttien into memory + uint32_t destination, // Index of destination register + uint32_t offset) +{ +#ifdef IODUMP + printf("write region=%d offset=%d value=%d\n", destination, offset, data); +#ifdef PAGETBL_DUMP + print_pgtbl(proc, 0, -1); //print max TBL +#endif + MEMPHY_dump(proc->mram); +#endif + + return __write(proc, destination, offset, data); +} + + +/*free_pcb_memphy - collect all memphy of pcb + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@incpgnum: number of page + */ +int free_pcb_memph(struct pcb_t *caller) +{ + int pagenum, fpn; + uint32_t pte; + + + for(pagenum = 0; pagenum < PAGING_MAX_PGN; pagenum++) + { + pte= caller->mm->pgd[pagenum]; + + if (!PAGING_PTE_PAGE_PRESENT(pte)) + { + fpn = PAGING_PTE_FPN(pte); + MEMPHY_put_freefp(caller->mram, fpn); + } else { + fpn = PAGING_PTE_SWP(pte); + MEMPHY_put_freefp(caller->active_mswp, fpn); + } + } + + return 0; +} + +/*get_vm_area_node - get vm area for a number of pages + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@incpgnum: number of page + *@vmastart: vma end + *@vmaend: vma end + * + */ +struct vm_rg_struct* get_vm_area_node_at_brk(struct pcb_t *caller, int vmaid, int size, int alignedsz) +{ + struct vm_rg_struct * newrg = malloc(sizeof(struct vm_rg_struct));; + /* TODO retrive current vma to obtain newrg, current comment out due to compiler redundant warning*/ + struct vm_area_struct *cur_vma = get_vma_by_num(caller->mm, vmaid); + + /* TODO: update the newrg boundary + // newrg->rg_start = ... + // newrg->rg_end = ... + */ + + newrg->rg_start = cur_vma -> sbrk; + + if ( (cur_vma ->sbrk + alignedsz) > cur_vma -> vm_end ) return newrg = cur_vma -> sbrk; +cur_vma ->sbrk = cur_vma->sbrk + alignedsz; + + newrg->rg_end = cur_vma -> sbrk; + +return newrg; +} + +/*validate_overlap_vm_area + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@vmastart: vma end + *@vmaend: vma end + * + */ +int validate_overlap_vm_area(struct pcb_t *caller, int vmaid, int vmastart, int vmaend) +{ + struct vm_area_struct *vma = caller->mm->mmap; + + /* TODO validate the planned memory area is not overlapped */ + while(vma != NULL) + { + + if ((vmastart >= vma->vm_start && vmastart < vma->vm_end) || (vmastart <= vma->vm_start && vmaend >= vma->vm_end)) + { + return -1; + } + vma = vma->vm_next; + } + return 0; +} + +/*inc_vma_limit - increase vm area limits to reserve space for new variable + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@inc_sz: increment size + *@inc_limit_ret: increment limit return + * + */ +int inc_vma_limit(struct pcb_t *caller, int vmaid, int inc_sz, int* inc_limit_ret) +{ + struct vm_rg_struct * newrg = malloc(sizeof(struct vm_rg_struct)); + int inc_amt = PAGING_PAGE_ALIGNSZ(inc_sz); + int incnumpage = inc_amt / PAGING_PAGESZ; + struct vm_rg_struct *area = get_vm_area_node_at_brk(caller, vmaid, inc_sz, inc_amt); + struct vm_area_struct *cur_vma = get_vma_by_num(caller->mm, vmaid); + + int old_end = cur_vma->vm_end; + + /*Validate overlap of obtained region */ + if (validate_overlap_vm_area(caller, vmaid, area->rg_start, area->rg_end) < 0) + return -1; /*Overlap and failed allocation */ + + /* TODO: Obtain the new vm area based on vmaid */ + cur_vma->sbrk = area -> rg_start; + + + if (vm_map_ram(caller, area->rg_start, area->rg_end, + old_end, incnumpage , newrg) < 0) + return -1; /* Map the memory to MEMRAM */ + inc_limit_ret = cur_vma->vm_end + inc_sz; + return 0; + +} + +/*find_victim_page - find victim page + *@caller: caller + *@pgn: return page number + * + */ +int find_victim_page(struct mm_struct *mm, int *retpgn) +{ + struct pgn_t *pg = mm->fifo_pgn; + + /* TODO: Implement the theorical mechanism to find the victim page */ + if (pg == NULL) return -1; + + *retpgn = pg->pgn; + + mm->fifo_pgn = pg->pg_next; + + free(pg); + + return 0; +} + +/*get_free_vmrg_area - get a free vm region + *@caller: caller + *@vmaid: ID vm area to alloc memory region + *@size: allocated size + * + */ +int get_free_vmrg_area(struct pcb_t *caller, int vmaid, int size, struct vm_rg_struct *newrg) +{ + struct vm_area_struct *cur_vma = get_vma_by_num(caller->mm, vmaid); + + struct vm_rg_struct *rgit = cur_vma->vm_freerg_list; + + if (rgit == NULL) + return -1; + + /* Probe unintialized newrg */ + newrg->rg_start = newrg->rg_end = -1; + + /* Traverse on list of free vm region to find a fit space */ + //check điều kiện bịp + while (rgit != NULL && rgit->vmaid == vmaid) + { + if (rgit->rg_start + size <= rgit->rg_end) + { /* Current region has enough space */ + newrg->rg_start = rgit->rg_start; + newrg->rg_end = rgit->rg_start + size; + + /* Update left space in chosen region */ + if (rgit->rg_start + size < rgit->rg_end) + { + rgit->rg_start = rgit->rg_start + size; + } + else + { /*Use up all space, remove current node */ + /*Clone next rg node */ + struct vm_rg_struct *nextrg = rgit->rg_next; + + /*Cloning */ + if (nextrg != NULL) + { + rgit->rg_start = nextrg->rg_start; + rgit->rg_end = nextrg->rg_end; + + rgit->rg_next = nextrg->rg_next; + + free(nextrg); + } + else + { /*End of free list */ + rgit->rg_start = rgit->rg_end; //dummy, size 0 region + rgit->rg_next = NULL; + } + } + } + else + { + rgit = rgit->rg_next; // Traverse next rg + } + } + + if(newrg->rg_start == -1) // new region not found + return -1; + + return 0; +} + +//#endif diff --git a/ossim_source_code/src/mm.c b/ossim_source_code/src/mm.c new file mode 100644 index 0000000..5071151 --- /dev/null +++ b/ossim_source_code/src/mm.c @@ -0,0 +1,458 @@ +//#ifdef MM_PAGING +/* + * PAGING based Memory Management + * Memory management unit mm/mm.c + */ + +#include "mm.h" +#include +#include + +/* + * init_pte - Initialize PTE entry + */ +int init_pte(uint32_t *pte, + int pre, // present + int fpn, // FPN + int drt, // dirty + int swp, // swap + int swptyp, // swap type + int swpoff) //swap offset +{ + if (pre != 0) { + if (swp == 0) { // Non swap ~ page online + if (fpn == 0) + return -1; // Invalid setting + + /* Valid setting with FPN */ + SETBIT(*pte, PAGING_PTE_PRESENT_MASK); + CLRBIT(*pte, PAGING_PTE_SWAPPED_MASK); + CLRBIT(*pte, PAGING_PTE_DIRTY_MASK); + + SETVAL(*pte, fpn, PAGING_PTE_FPN_MASK, PAGING_PTE_FPN_LOBIT); + } else { // page swapped + SETBIT(*pte, PAGING_PTE_PRESENT_MASK); + SETBIT(*pte, PAGING_PTE_SWAPPED_MASK); + CLRBIT(*pte, PAGING_PTE_DIRTY_MASK); + + SETVAL(*pte, swptyp, PAGING_PTE_SWPTYP_MASK, PAGING_PTE_SWPTYP_LOBIT); + SETVAL(*pte, swpoff, PAGING_PTE_SWPOFF_MASK, PAGING_PTE_SWPOFF_LOBIT); + } + } + + return 0; +} + +/* + * pte_set_swap - Set PTE entry for swapped page + * @pte : target page table entry (PTE) + * @swptyp : swap type + * @swpoff : swap offset + */ +int pte_set_swap(uint32_t *pte, int swptyp, int swpoff) +{ + SETBIT(*pte, PAGING_PTE_PRESENT_MASK); + SETBIT(*pte, PAGING_PTE_SWAPPED_MASK); + + SETVAL(*pte, swptyp, PAGING_PTE_SWPTYP_MASK, PAGING_PTE_SWPTYP_LOBIT); + SETVAL(*pte, swpoff, PAGING_PTE_SWPOFF_MASK, PAGING_PTE_SWPOFF_LOBIT); + + return 0; +} + +/* + * pte_set_swap - Set PTE entry for on-line page + * @pte : target page table entry (PTE) + * @fpn : frame page number (FPN) + */ +int pte_set_fpn(uint32_t *pte, int fpn) +{ + SETBIT(*pte, PAGING_PTE_PRESENT_MASK); + CLRBIT(*pte, PAGING_PTE_SWAPPED_MASK); + + SETVAL(*pte, fpn, PAGING_PTE_FPN_MASK, PAGING_PTE_FPN_LOBIT); + + return 0; +} + + +/* + * vmap_page_range - map a range of page at aligned address + */ +int vmap_page_range(struct pcb_t *caller, // process call + int addr, // start address which is aligned to pagesz + int pgnum, // num of mapping page + struct framephy_struct *frames,// list of the mapped frames + struct vm_rg_struct *ret_rg)// return mapped region, the real mapped fp +{ // no guarantee all given pages are mapped + //uint32_t * pte = malloc(sizeof(uint32_t)); + struct framephy_struct *fpit = malloc(sizeof(struct framephy_struct)); + //int fpn; + int pgit = 0; + int pgn = PAGING_PGN(addr); + + /* TODO: update the rg_end and rg_start of ret_rg + //ret_rg->rg_end = .... + //ret_rg->rg_start = ... + //ret_rg->vmaid = ... + */ + ret_rg -> rg_end = ret_rg -> rg_start = addr ; + + fpit->fp_next = frames; + + /* TODO map range of frame to address space + * in page table pgd in caller->mm + */ + + /* Tracking for later page replacement activities (if needed) + * Enqueue new usage page */ + while ( pgit < pgnum ) + { + if ( fpit == NULL ) + { + break ; + } + pgn = PAGING_PGN ( addr + pgnum * PAGING_PAGESZ ); + pte_set_fpn (&( caller ->mm -> pgd [ pgn ]) , fpit -> fpn ) ; + enlist_pgn_node (& caller -> mm -> fifo_pgn , pgn + pgit ) ; + fpit = fpit -> fp_next ; + } + ret_rg -> rg_end += pgit * PAGING_PAGESZ ; + return 0; + +} + +/* + * alloc_pages_range - allocate req_pgnum of frame in ram + * @caller : caller + * @req_pgnum : request page num + * @frm_lst : frame list + */ + +int alloc_pages_range(struct pcb_t *caller, int req_pgnum, struct framephy_struct** frm_lst) +{ + int pgit, fpn; + struct framephy_struct *newfp_str; + + for (pgit = 0; pgit < req_pgnum; pgit++) + { + if (MEMPHY_get_freefp(caller->mram, &fpn) == 0) + { + newfp_str = malloc(sizeof(struct framephy_struct)); + newfp_str->fpn = fpn; + newfp_str->owner = caller->mm; + newfp_str->fp_next = NULL; + + if (!*frm_lst) + { + *frm_lst = newfp_str; + } + else + { + newfp_str->fp_next = *frm_lst; + *frm_lst = newfp_str; + } + + struct framephy_struct *temp = malloc(sizeof(struct framephy_struct)); + *temp = *newfp_str; + temp->fp_next = caller->mram->used_fp_list; + caller->mram->used_fp_list = temp; + } + else + { + // ERROR CODE of obtaining some but not enough frames + int vicfpn, vicpgn, swpfpn; + uint32_t vicpte; + + if (find_victim_page(caller->mm, &vicpgn) < 0) + { + return -1; + } + + vicpte = caller->mm->pgd[vicpgn]; + vicfpn = PAGING_OFFST(vicpte); + + newfp_str = malloc(sizeof(struct framephy_struct)); + newfp_str->fpn = vicfpn; + newfp_str->owner = caller->mm; + newfp_str->fp_next = NULL; + + if (!*frm_lst) + { + *frm_lst = newfp_str; + } + else + { + newfp_str->fp_next = *frm_lst; + *frm_lst = newfp_str; + } + + int i; + if (MEMPHY_get_freefp(caller->active_mswp, &swpfpn) == 0) + { + __swap_cp_page(caller->mram, vicfpn, caller->active_mswp, swpfpn); + struct memphy_struct *mswp = *caller->mswp; + for (i = 0; i < PAGING_MAX_MMSWP; i++) + { + if (mswp + i == caller->active_mswp) break; + } + } + else + { + struct memphy_struct *mswp = *caller->mswp; + swpfpn = -1; + for (i = 0; i < PAGING_MAX_MMSWP; i++) + { + if (MEMPHY_get_freefp(mswp + i, &swpfpn) == 0) + { + __swap_cp_page(caller->mram, vicfpn, mswp + i, swpfpn); + break; + } + } + } + + if (swpfpn == -1) + return -3000; + + pte_set_swap(&caller->mm->pgd[vicpgn], i, swpfpn); + } + } + + return 0; +} + + + +/* + * vm_map_ram - do the mapping all vm are to ram storage device + * @caller : caller + * @astart : vm area start + * @aend : vm area end + * @mapstart : start mapping point + * @incpgnum : number of mapped page + * @ret_rg : returned region + */ +int vm_map_ram(struct pcb_t *caller, int astart, int aend, int mapstart, int incpgnum, struct vm_rg_struct *ret_rg) +{ + struct framephy_struct *frm_lst = NULL; + int ret_alloc; + + /*@bksysnet: author provides a feasible solution of getting frames + *FATAL logic in here, wrong behaviour if we have not enough page + *i.e. we request 1000 frames meanwhile our RAM has size of 3 frames + *Don't try to perform that case in this simple work, it will result + *in endless procedure of swap-off to get frame and we have not provide + *duplicate control mechanism, keep it simple + */ + ret_alloc = alloc_pages_range(caller, incpgnum, &frm_lst); + + if (ret_alloc < 0 && ret_alloc != -3000) + return -1; + + /* Out of memory */ + if (ret_alloc == -3000) + { +#ifdef MMDBG + printf("OOM: vm_map_ram out of memory \n"); +#endif + return -1; + } + + /* it leaves the case of memory is enough but half in ram, half in swap + * do the swaping all to swapper to get the all in ram */ + vmap_page_range(caller, mapstart, incpgnum, frm_lst, ret_rg); + + return 0; +} + +/* Swap copy content page from source frame to destination frame + * @mpsrc : source memphy + * @srcfpn : source physical page number (FPN) + * @mpdst : destination memphy + * @dstfpn : destination physical page number (FPN) + **/ +int __swap_cp_page(struct memphy_struct *mpsrc, int srcfpn, + struct memphy_struct *mpdst, int dstfpn) +{ + int cellidx; + int addrsrc,addrdst; + for(cellidx = 0; cellidx < PAGING_PAGESZ; cellidx++) + { + addrsrc = srcfpn * PAGING_PAGESZ + cellidx; + addrdst = dstfpn * PAGING_PAGESZ + cellidx; + + BYTE data; + MEMPHY_read(mpsrc, addrsrc, &data); + MEMPHY_write(mpdst, addrdst, data); + } + + return 0; +} + +/* + *Initialize a empty Memory Management instance + * @mm: self mm + * @caller: mm owner + */ +int init_mm(struct mm_struct *mm, struct pcb_t *caller) +{ + struct vm_area_struct *vma0 = malloc(sizeof(struct vm_area_struct)); + struct vm_area_struct *vma1 = malloc(sizeof(struct vm_area_struct)); + + mm->pgd = malloc(PAGING_MAX_PGN * sizeof(uint32_t)); + + /* By default the owner comes with at least one vma for DATA */ + vma0->vm_id = 0; + vma0->vm_start = 0; + vma0->vm_end = vma0->vm_start; + vma0->sbrk = vma0->vm_start; + + struct vm_rg_struct *first_rg = init_vm_rg(vma0->vm_start, vma0->vm_end, 0); + enlist_vm_rg_node(&vma0->vm_freerg_list, first_rg); + + /* Update vma0 next */ + vma0->vm_next = vma1; // Assuming vma1 is the next VM area + + /* Update one vma for HEAP */ + vma1->vm_id = 1; // Assuming ID for heap + // vma1->vm_start = HEAP_START; // Define an appropriate start address for the heap + //vma1->vm_end = HEAP_END; // Define the end address for the heap + vma1->sbrk = vma1->vm_start; + + struct vm_rg_struct *first_rg_heap = init_vm_rg(vma1->vm_start, vma1->vm_end, 0); + enlist_vm_rg_node(&vma1->vm_freerg_list, first_rg_heap); + + /* Set next for vma1 */ + vma1->vm_next = NULL; // Assuming it's the last one in the list for now + + /* Point vma owner backward */ + vma0->vm_mm = mm; + vma1->vm_mm = mm; + + /* Update mmap */ + mm->mmap = vma0; // Start the mmap list with vma0 + + return 0; +} + + +struct vm_rg_struct* init_vm_rg(int rg_start, int rg_end, int vmaid) +{ + struct vm_rg_struct *rgnode = malloc(sizeof(struct vm_rg_struct)); + + rgnode->rg_start = rg_start; + rgnode->rg_end = rg_end; + rgnode->vmaid = vmaid; + rgnode->rg_next = NULL; + + return rgnode; +} + +int enlist_vm_rg_node(struct vm_rg_struct **rglist, struct vm_rg_struct* rgnode) +{ + rgnode->rg_next = *rglist; + *rglist = rgnode; + + return 0; +} + +int enlist_pgn_node(struct pgn_t **plist, int pgn) +{ + struct pgn_t* pnode = malloc(sizeof(struct pgn_t)); + + pnode->pgn = pgn; + pnode->pg_next = *plist; + *plist = pnode; + + return 0; +} + +int print_list_fp(struct framephy_struct *ifp) +{ + struct framephy_struct *fp = ifp; + + printf("print_list_fp: "); + if (fp == NULL) {printf("NULL list\n"); return -1;} + printf("\n"); + while (fp != NULL ) + { + printf("fp[%d]\n",fp->fpn); + fp = fp->fp_next; + } + printf("\n"); + return 0; +} + +int print_list_rg(struct vm_rg_struct *irg) +{ + struct vm_rg_struct *rg = irg; + + printf("print_list_rg: "); + if (rg == NULL) {printf("NULL list\n"); return -1;} + printf("\n"); + while (rg != NULL) + { + printf("rg[%ld->%ldvma=%d]\n",rg->rg_start, rg->rg_end, rg->vmaid); + rg = rg->rg_next; + } + printf("\n"); + return 0; +} + +int print_list_vma(struct vm_area_struct *ivma) +{ + struct vm_area_struct *vma = ivma; + + printf("print_list_vma: "); + if (vma == NULL) {printf("NULL list\n"); return -1;} + printf("\n"); + while (vma != NULL ) + { + printf("va[%ld->%ld]\n",vma->vm_start, vma->vm_end); + vma = vma->vm_next; + } + printf("\n"); + return 0; +} + +int print_list_pgn(struct pgn_t *ip) +{ + printf("print_list_pgn: "); + if (ip == NULL) {printf("NULL list\n"); return -1;} + printf("\n"); + while (ip != NULL ) + { + printf("va[%d]-\n",ip->pgn); + ip = ip->pg_next; + } + printf("n"); + return 0; +} + +int print_pgtbl(struct pcb_t *caller, uint32_t start, uint32_t end) +{ + int pgn_start,pgn_end; + int pgit; + + if(end == -1){ + pgn_start = 0; + struct vm_area_struct *cur_vma = get_vma_by_num(caller->mm, 0); + end = cur_vma->vm_end; + } + pgn_start = PAGING_PGN(start); + pgn_end = PAGING_PGN(end); + + printf("print_pgtbl: %d - %d", start, end); + if (caller == NULL) {printf("NULL caller\n"); return -1;} + printf("\n"); + + + for(pgit = pgn_start; pgit < pgn_end; pgit++) + { + printf("%08ld: %08x\n", pgit * sizeof(uint32_t), caller->mm->pgd[pgit]); + } + + return 0; +} + +//#endif diff --git a/ossim_source_code/src/os.c b/ossim_source_code/src/os.c new file mode 100644 index 0000000..288a3c1 --- /dev/null +++ b/ossim_source_code/src/os.c @@ -0,0 +1,292 @@ + +#include "cpu.h" +#include "timer.h" +#include "sched.h" +#include "loader.h" +#include "mm.h" + +#include +#include +#include +#include + +static int time_slot; +static int num_cpus; +static int done = 0; + +#ifdef MM_PAGING +static int memramsz; +static int memswpsz[PAGING_MAX_MMSWP]; +#ifdef MM_PAGING_HEAP_GODOWN +static int vmemsz; +#endif + +struct mmpaging_ld_args { + /* A dispatched argument struct to compact many-fields passing to loader */ + int vmemsz; + struct memphy_struct *mram; + struct memphy_struct **mswp; + struct memphy_struct *active_mswp; + struct timer_id_t *timer_id; +}; +#endif + +static struct ld_args{ + char ** path; + unsigned long * start_time; +#ifdef MLQ_SCHED + unsigned long * prio; +#endif +} ld_processes; +int num_processes; + +struct cpu_args { + struct timer_id_t * timer_id; + int id; +}; + + +static void * cpu_routine(void * args) { + struct timer_id_t * timer_id = ((struct cpu_args*)args)->timer_id; + int id = ((struct cpu_args*)args)->id; + /* Check for new process in ready queue */ + int time_left = 0; + struct pcb_t * proc = NULL; + while (1) { + /* Check the status of current process */ + if (proc == NULL) { + /* No process is running, the we load new process from + * ready queue */ + proc = get_proc(); + if (proc == NULL) { + next_slot(timer_id); + continue; /* First load failed. skip dummy load */ + } + }else if (proc->pc == proc->code->size) { + /* The porcess has finish it job */ + printf("\tCPU %d: Processed %2d has finished\n", + id ,proc->pid); + free(proc); + proc = get_proc(); + time_left = 0; + }else if (time_left == 0) { + /* The process has done its job in current time slot */ + printf("\tCPU %d: Put process %2d to run queue\n", + id, proc->pid); + put_proc(proc); + proc = get_proc(); + } + + /* Recheck process status after loading new process */ + if (proc == NULL && done) { + /* No process to run, exit */ + printf("\tCPU %d stopped\n", id); + break; + }else if (proc == NULL) { + /* There may be new processes to run in + * next time slots, just skip current slot */ + next_slot(timer_id); + continue; + }else if (time_left == 0) { + printf("\tCPU %d: Dispatched process %2d\n", + id, proc->pid); + time_left = time_slot; + } + + /* Run current process */ + run(proc); + time_left--; + next_slot(timer_id); + } + detach_event(timer_id); + pthread_exit(NULL); +} + +static void * ld_routine(void * args) { +#ifdef MM_PAGING + struct memphy_struct* mram = ((struct mmpaging_ld_args *)args)->mram; + struct memphy_struct** mswp = ((struct mmpaging_ld_args *)args)->mswp; + struct memphy_struct* active_mswp = ((struct mmpaging_ld_args *)args)->active_mswp; + struct timer_id_t * timer_id = ((struct mmpaging_ld_args *)args)->timer_id; +#else + struct timer_id_t * timer_id = (struct timer_id_t*)args; +#endif + int i = 0; + printf("ld_routine\n"); + while (i < num_processes) { + struct pcb_t * proc = load(ld_processes.path[i]); +#ifdef MLQ_SCHED + proc->prio = ld_processes.prio[i]; +#endif + while (current_time() < ld_processes.start_time[i]) { + next_slot(timer_id); + } +#ifdef MM_PAGING + proc->mm = malloc(sizeof(struct mm_struct)); +#ifdef MM_PAGING_HEAP_GODOWN + proc->vmemsz = vmemsz; +#endif + init_mm(proc->mm, proc); + proc->mram = mram; + proc->mswp = mswp; + proc->active_mswp = active_mswp; +#endif + printf("\tLoaded a process at %s, PID: %d PRIO: %ld\n", + ld_processes.path[i], proc->pid, ld_processes.prio[i]); + add_proc(proc); + free(ld_processes.path[i]); + i++; + next_slot(timer_id); + } + free(ld_processes.path); + free(ld_processes.start_time); + done = 1; + detach_event(timer_id); + pthread_exit(NULL); +} + +static void read_config(const char * path) { + FILE * file; + if ((file = fopen(path, "r")) == NULL) { + printf("Cannot find configure file at %s\n", path); + exit(1); + } + fscanf(file, "%d %d %d\n", &time_slot, &num_cpus, &num_processes); + + ld_processes.path = (char**)malloc(sizeof(char*) * num_processes); + ld_processes.start_time = (unsigned long*) + malloc(sizeof(unsigned long) * num_processes); +#ifdef MM_PAGING + int sit; +#ifdef MM_FIXED_MEMSZ + /* We provide here a back compatible with legacy OS simulatiom config file + * In which, it have no addition config line for Mema, keep only one line + * for legacy info + * [time slice] [N = Number of CPU] [M = Number of Processes to be run] + */ + memramsz = 0x100000; + memswpsz[0] = 0x1000000; + for(sit = 1; sit < PAGING_MAX_MMSWP; sit++) + memswpsz[sit] = 0; + +#ifdef MM_PAGING_HEAP_GODOWN + vmemsz = 0x300000; +#endif +#else + /* Read input config of memory size: MEMRAM and upto 4 MEMSWP (mem swap) + * Format: (size=0 result non-used memswap, must have RAM and at least 1 SWAP) + * MEM_RAM_SZ MEM_SWP0_SZ MEM_SWP1_SZ MEM_SWP2_SZ MEM_SWP3_SZ + */ + fscanf(file, "%d\n", &memramsz); + for(sit = 0; sit < PAGING_MAX_MMSWP; sit++) + fscanf(file, "%d", &(memswpsz[sit])); +#ifdef MM_PAGING_HEAP_GODOWN + fscanf(file, "%d\n", &vmemsz); +#endif + fscanf(file, "\n"); /* Final character */ +#endif +#endif + +#ifdef MLQ_SCHED + ld_processes.prio = (unsigned long*) + malloc(sizeof(unsigned long) * num_processes); +#endif + int i; + for (i = 0; i < num_processes; i++) { + ld_processes.path[i] = (char*)malloc(sizeof(char) * 100); + ld_processes.path[i][0] = '\0'; + strcat(ld_processes.path[i], "input/proc/"); + char proc[100]; +#ifdef MLQ_SCHED + fscanf(file, "%lu %s %lu\n", &ld_processes.start_time[i], proc, &ld_processes.prio[i]); +#else + fscanf(file, "%lu %s\n", &ld_processes.start_time[i], proc); +#endif + strcat(ld_processes.path[i], proc); + } +} + +int main(int argc, char * argv[]) { + /* Read config */ + if (argc != 2) { + printf("Usage: os [path to configure file]\n"); + return 1; + } + char path[100]; + path[0] = '\0'; + strcat(path, "input/"); + strcat(path, argv[1]); + + read_config(path); + + pthread_t * cpu = (pthread_t*)malloc(num_cpus * sizeof(pthread_t)); + struct cpu_args * args = + (struct cpu_args*)malloc(sizeof(struct cpu_args) * num_cpus); + pthread_t ld; + + /* Init timer */ + int i; + for (i = 0; i < num_cpus; i++) { + args[i].timer_id = attach_event(); + args[i].id = i; + } + struct timer_id_t * ld_event = attach_event(); + start_timer(); + +#ifdef MM_PAGING + /* Init all MEMPHY include 1 MEMRAM and n of MEMSWP */ + int rdmflag = 1; /* By default memphy is RANDOM ACCESS MEMORY */ + + struct memphy_struct mram; + struct memphy_struct mswp[PAGING_MAX_MMSWP]; + + /* Create MEM RAM */ + init_memphy(&mram, memramsz, rdmflag); + + /* Create all MEM SWAP */ + int sit; + for(sit = 0; sit < PAGING_MAX_MMSWP; sit++) + init_memphy(&mswp[sit], memswpsz[sit], rdmflag); + + /* In Paging mode, it needs passing the system mem to each PCB through loader*/ + struct mmpaging_ld_args *mm_ld_args = malloc(sizeof(struct mmpaging_ld_args)); + + mm_ld_args->timer_id = ld_event; + mm_ld_args->mram = (struct memphy_struct *) &mram; + mm_ld_args->mswp = (struct memphy_struct**) &mswp; +#ifdef MM_PAGING_HEAP_GODOWN + mm_ld_args->vmemsz = vmemsz; +#endif + mm_ld_args->active_mswp = (struct memphy_struct *) &mswp[0]; +#endif + + + /* Init scheduler */ + init_scheduler(); + + /* Run CPU and loader */ +#ifdef MM_PAGING + pthread_create(&ld, NULL, ld_routine, (void*)mm_ld_args); +#else + pthread_create(&ld, NULL, ld_routine, (void*)ld_event); +#endif + for (i = 0; i < num_cpus; i++) { + pthread_create(&cpu[i], NULL, + cpu_routine, (void*)&args[i]); + } + + /* Wait for CPU and loader finishing */ + for (i = 0; i < num_cpus; i++) { + pthread_join(cpu[i], NULL); + } + pthread_join(ld, NULL); + + /* Stop timer */ + stop_timer(); + + return 0; + +} + + + diff --git a/ossim_source_code/src/paging.c b/ossim_source_code/src/paging.c new file mode 100644 index 0000000..b061019 --- /dev/null +++ b/ossim_source_code/src/paging.c @@ -0,0 +1,18 @@ + +#include "mem.h" +#include "cpu.h" +#include "loader.h" +#include + +int main() { + struct pcb_t * ld = load("input/p0"); + struct pcb_t * proc = load("input/p0"); + unsigned int i; + for (i = 0; i < proc->code->size; i++) { + run(proc); + run(ld); + } + dump(); + return 0; +} + diff --git a/ossim_source_code/src/queue.c b/ossim_source_code/src/queue.c new file mode 100644 index 0000000..6273086 --- /dev/null +++ b/ossim_source_code/src/queue.c @@ -0,0 +1,49 @@ +#include +#include +#include "queue.h" + +int empty(struct queue_t * q) { + if (q == NULL) return 1; + return (q->size == 0); +} + +void enqueue(struct queue_t * q, struct pcb_t * proc) { + /* TODO: put a new process to queue [q] */ + if (q->size > MAX_QUEUE_SIZE){ + return; + } + else if (!q->size){ + q->proc[0] = proc; + q->size++; + } + else { + int index = q->size; + while (index > 0 && q->proc[index - 1]->priority > proc->priority){ + q->proc[index] = q->proc[index - 1]; + index--; + } + + q->proc[index] = proc; + q->size++; + } + +} + +struct pcb_t * dequeue(struct queue_t * q) { + /* TODO: return a pcb whose prioprity is the highest + * in the queue [q] and remember to remove it from q + * */ + struct pcb_t * result = NULL; + if (q->proc[0] != NULL){ + result = q->proc[0]; + + for (int i = 0; i < q->size - 1; i++){ + q->proc[i] = q->proc[i + 1]; + } + q->proc[q->size - 1] = NULL; + q->size--; + + } + return result; +} + diff --git a/ossim_source_code/src/sched.c b/ossim_source_code/src/sched.c new file mode 100644 index 0000000..c4d5ce2 --- /dev/null +++ b/ossim_source_code/src/sched.c @@ -0,0 +1,140 @@ + +#include "queue.h" +#include "sched.h" +#include + +#include +#include +static struct queue_t ready_queue; +static struct queue_t run_queue; +static pthread_mutex_t queue_lock; + +#ifdef MLQ_SCHED +static struct queue_t mlq_ready_queue[MAX_PRIO]; +#endif + +int queue_empty(void) { +#ifdef MLQ_SCHED + unsigned long prio; + for (prio = 0; prio < MAX_PRIO; prio++) + if(!empty(&mlq_ready_queue[prio])) + return -1; +#endif + return (empty(&ready_queue) && empty(&run_queue)); +} + +void init_scheduler(void) { +#ifdef MLQ_SCHED + int i ; + + for (i = 0; i < MAX_PRIO; i ++) + mlq_ready_queue[i].size = 0; +#endif + ready_queue.size = 0; + run_queue.size = 0; + pthread_mutex_init(&queue_lock, NULL); +} + +#ifdef MLQ_SCHED +/* + * Stateful design for routine calling + * based on the priority and our MLQ policy + * We implement stateful here using transition technique + * State representation prio = 0 .. MAX_PRIO, curr_slot = 0..(MAX_PRIO - prio) + */ +struct pcb_t * get_mlq_proc(void) { + struct pcb_t * proc = NULL; + /*TODO: get a process from PRIORITY [ready_queue]. + * Remember to use lock to protect the queue. + * */ + //int curr_slot = 0; + pthread_mutex_lock(&queue_lock); + int prio; + + for (prio = 0; prio < MAX_PRIO; prio++){ + if (mlq_ready_queue[prio].size != 0 && mlq_ready_queue[prio].count_slot < MAX_PRIO - prio){ + proc = dequeue(&mlq_ready_queue[prio]); + mlq_ready_queue[prio].count_slot++; + break; + } + } + + if (prio == MAX_PRIO) { + for (int i = 0; i < MAX_PRIO; i++){ + mlq_ready_queue[i].count_slot = 0; + } + + for (int i = 0; i < MAX_PRIO; i++){ + if (mlq_ready_queue[i].size != 0 && mlq_ready_queue[i].count_slot < MAX_PRIO - i){ + proc = dequeue(&mlq_ready_queue[i]); + mlq_ready_queue[i].count_slot++; + break; + } + } + } + + // while (prio < MAX_PRIO){ + // curr_slot = MAX_PRIO - prio; + // if (!empty(&mlq_ready_queue[prio]) && mlq_ready_queue[prio].count_slot < curr_slot){ + // proc = dequeue(&mlq_ready_queue[prio]); + // curr_slot--; + // break; + // } + // else{ + // prio = (prio + 1) % MAX_PRIO; + // curr_slot = 0; + // } + // } + pthread_mutex_unlock(&queue_lock); + return proc; +} + +void put_mlq_proc(struct pcb_t * proc) { + pthread_mutex_lock(&queue_lock); + enqueue(&mlq_ready_queue[proc->prio], proc); + pthread_mutex_unlock(&queue_lock); +} + +void add_mlq_proc(struct pcb_t * proc) { + pthread_mutex_lock(&queue_lock); + enqueue(&mlq_ready_queue[proc->prio], proc); + pthread_mutex_unlock(&queue_lock); +} + +struct pcb_t * get_proc(void) { + return get_mlq_proc(); +} + +void put_proc(struct pcb_t * proc) { + return put_mlq_proc(proc); +} + +void add_proc(struct pcb_t * proc) { + return add_mlq_proc(proc); +} +#else +struct pcb_t * get_proc(void) { + struct pcb_t * proc = NULL; + /*TODO: get a process from [ready_queue]. + * Remember to use lock to protect the queue. + * */ + pthread_mutex_lock(&queue_lock); + dequeue(&ready_queue); + pthread_mutex_unlock(&queue_lock); + return proc; +} + +void put_proc(struct pcb_t * proc) { + pthread_mutex_lock(&queue_lock); + enqueue(&run_queue, proc); + pthread_mutex_unlock(&queue_lock); +} + +void add_proc(struct pcb_t * proc) { + pthread_mutex_lock(&queue_lock); + enqueue(&ready_queue, proc); + pthread_mutex_unlock(&queue_lock); +} +#endif + + diff --git a/ossim_source_code/src/timer.c b/ossim_source_code/src/timer.c new file mode 100644 index 0000000..02c4111 --- /dev/null +++ b/ossim_source_code/src/timer.c @@ -0,0 +1,136 @@ + +#include "timer.h" +#include +#include + +static pthread_t _timer; + +struct timer_id_container_t { + struct timer_id_t id; + struct timer_id_container_t * next; +}; + +static struct timer_id_container_t * dev_list = NULL; + +static uint64_t _time; + +static int timer_started = 0; +static int timer_stop = 0; + + +static void * timer_routine(void * args) { + while (!timer_stop) { + printf("Time slot %3lu\n", current_time()); + int fsh = 0; + int event = 0; + /* Wait for all devices have done the job in current + * time slot */ + struct timer_id_container_t * temp; + for (temp = dev_list; temp != NULL; temp = temp->next) { + pthread_mutex_lock(&temp->id.event_lock); + while (!temp->id.done && !temp->id.fsh) { + pthread_cond_wait( + &temp->id.event_cond, + &temp->id.event_lock + ); + } + if (temp->id.fsh) { + fsh++; + } + event++; + pthread_mutex_unlock(&temp->id.event_lock); + } + + /* Increase the time slot */ + _time++; + + /* Let devices continue their job */ + for (temp = dev_list; temp != NULL; temp = temp->next) { + pthread_mutex_lock(&temp->id.timer_lock); + temp->id.done = 0; + pthread_cond_signal(&temp->id.timer_cond); + pthread_mutex_unlock(&temp->id.timer_lock); + } + if (fsh == event) { + break; + } + } + pthread_exit(args); +} + +void next_slot(struct timer_id_t * timer_id) { + /* Tell to timer that we have done our job in current slot */ + pthread_mutex_lock(&timer_id->event_lock); + timer_id->done = 1; + pthread_cond_signal(&timer_id->event_cond); + pthread_mutex_unlock(&timer_id->event_lock); + + /* Wait for going to next slot */ + pthread_mutex_lock(&timer_id->timer_lock); + while (timer_id->done) { + pthread_cond_wait( + &timer_id->timer_cond, + &timer_id->timer_lock + ); + } + pthread_mutex_unlock(&timer_id->timer_lock); +} + +uint64_t current_time() { + return _time; +} + +void start_timer() { + timer_started = 1; + pthread_create(&_timer, NULL, timer_routine, NULL); +} + +void detach_event(struct timer_id_t * event) { + pthread_mutex_lock(&event->event_lock); + event->fsh = 1; + pthread_cond_signal(&event->event_cond); + pthread_mutex_unlock(&event->event_lock); +} + +struct timer_id_t * attach_event() { + if (timer_started) { + return NULL; + }else{ + struct timer_id_container_t * container = + (struct timer_id_container_t*)malloc( + sizeof(struct timer_id_container_t) + ); + container->id.done = 0; + container->id.fsh = 0; + pthread_cond_init(&container->id.event_cond, NULL); + pthread_mutex_init(&container->id.event_lock, NULL); + pthread_cond_init(&container->id.timer_cond, NULL); + pthread_mutex_init(&container->id.timer_lock, NULL); + if (dev_list == NULL) { + dev_list = container; + dev_list->next = NULL; + }else{ + container->next = dev_list; + dev_list = container; + } + return &(container->id); + } +} + +void stop_timer() { + timer_stop = 1; + pthread_join(_timer, NULL); + while (dev_list != NULL) { + struct timer_id_container_t * temp = dev_list; + dev_list = dev_list->next; + pthread_cond_destroy(&temp->id.event_cond); + pthread_mutex_destroy(&temp->id.event_lock); + pthread_cond_destroy(&temp->id.timer_cond); + pthread_mutex_destroy(&temp->id.timer_lock); + free(temp); + } +} + + + +