diff --git a/inc/environment_definitions.h b/inc/environment_definitions.h index 427b2f1..3228d46 100644 --- a/inc/environment_definitions.h +++ b/inc/environment_definitions.h @@ -108,7 +108,9 @@ struct Env { int priority; // Current priority char prog_name[PROGNAMELEN]; // Program name (to print it via USER.cprintf in multitasking) void* channel; // Address of the channel that it's blocked (sleep) on it - + // used in free env + uint32** startVAs; + int shared_object_no; //================ /*ADDRESS SPACE*/ //================ diff --git a/inc/x86.h b/inc/x86.h index d1d670e..e636303 100644 --- a/inc/x86.h +++ b/inc/x86.h @@ -48,6 +48,10 @@ static __inline void write_esp(uint32 esp) __attribute__((always_inline)); static __inline void write_ebp(uint32 ebp) __attribute__((always_inline)); static __inline void cpuid(uint32 info, uint32 *eaxp, uint32 *ebxp, uint32 *ecxp, uint32 *edxp); static __inline uint64 read_tsc(void) __attribute__((always_inline)); +static inline __attribute__((always_inline)) struct uint64 get_virtual_time_user(); + + +#define RANDU(s,e) ((get_virtual_time_user().low % (e-s) + s)) static __inline void breakpoint(void) @@ -366,4 +370,16 @@ static __inline void lidt(struct Gatedesc *p, int size) asm volatile("lidt (%0)" : : "r" (pd)); } + + +static inline __attribute__((always_inline)) struct uint64 get_virtual_time_user() +{ + struct uint64 result; + + __asm __volatile("rdtsc\n" + : "=a" (result.low), "=d" (result.hi) + ); + + return result; +} #endif /* !FOS_INC_X86_H */ diff --git a/kern/cmd/command_prompt.c b/kern/cmd/command_prompt.c index 67b7c58..b43806a 100644 --- a/kern/cmd/command_prompt.c +++ b/kern/cmd/command_prompt.c @@ -263,10 +263,11 @@ void run_command_prompt() { if (autograde) { - char cmd1_2[BUFLEN] = "tst bsd_nice 0"; - char cmd2_2[BUFLEN] = "tst bsd_nice 1"; - char cmd3_2[BUFLEN] = "tst bsd_nice 2"; - //execute_command(cmd3_2); + char cmdU1_2[BUFLEN] = "tst priorityRR 0"; // + char cmdU2_2[BUFLEN] = "tst priorityRR 1"; // + char cmdU3_2[BUFLEN] = "tst priorityRR 2"; // + +// execute_command(cmdU3_2); autograde = 0; } /*2024*/ @@ -453,47 +454,16 @@ int execute_command(char *command_string) } -int subsequence_matched(char *command_name, char *arg_name){ - int ptr_command_name=0,ptr_arg_name=0; - int len_command_name=strlen(command_name); - int len_arg_name=strlen(arg_name); - - while(ptr_command_name=len_arg_name) - return 1; - else return 0; - -} - int process_command(int number_of_arguments, char** arguments) { //TODO: [PROJECT'24.MS1 - #01] [1] PLAY WITH CODE! - process_command - LIST_INIT(&foundCommands); // initialize it for the Matched Commands for (int i = 0; i < NUM_OF_COMMANDS; i++) { if (strcmp(arguments[0], commands[i].name) == 0) { - LIST_INIT(&foundCommands); // empty the list - - if((commands[i].num_of_args==number_of_arguments-1) || (commands[i].num_of_args==-1 && number_of_arguments>1)){ - return i; - }else{ - LIST_INSERT_TAIL(&foundCommands, &commands[i]); // insert it with one found command - return CMD_INV_NUM_ARGS; - } - }else if(subsequence_matched(commands[i].name,arguments[0])){ - LIST_INSERT_TAIL(&foundCommands, &commands[i]); + return i; } } - int size = LIST_SIZE(&foundCommands); - if(size<=0) - return CMD_INVALID; - else return CMD_MATCHED; + return CMD_INVALID; } diff --git a/kern/init.c b/kern/init.c index c493d28..db5b503 100644 --- a/kern/init.c +++ b/kern/init.c @@ -81,7 +81,7 @@ void FOS_initialize() initialize_kheap_dynamic_allocator(KERNEL_HEAP_START, PAGE_SIZE, KERNEL_HEAP_START + DYN_ALLOC_MAX_SIZE); #endif // page_check(); - setPageReplacmentAlgorithmNchanceCLOCK(); + setPageReplacmentAlgorithmNchanceCLOCK(1); //setPageReplacmentAlgorithmLRU(PG_REP_LRU_TIME_APPROX); //setPageReplacmentAlgorithmFIFO(); //setPageReplacmentAlgorithmLRU(PG_REP_LRU_LISTS_APPROX); @@ -122,8 +122,8 @@ void FOS_initialize() irq_clear_mask(4); cprintf("* IRQ4 (COM1): is Enabled\n"); //Enable Primary ATA Hard Disk Interrupt -// irq_clear_mask(14); -// cprintf("* IRQ14 (Primary ATA Hard Disk): is Enabled\n"); + // irq_clear_mask(14); + // cprintf("* IRQ14 (Primary ATA Hard Disk): is Enabled\n"); } cprintf("* 5) SCHEDULER & MULTI-TASKING:\n"); { @@ -145,11 +145,105 @@ void FOS_initialize() cprintf("********************************************************************\n"); // start the kernel command prompt. - autograde = 0; + autograde = 1; while (1==1) { cprintf("\nWelcome to the FOS kernel command prompt!\n"); cprintf("Type 'help' for a list of commands.\n"); + if (autograde) + { + /*CHECK THE FOLLOWING: + * 1) time of each test + * 2) "unhandled trap in" message + */ + cprintf("\nMS3 Automatic testing is STARTED...\n") ; + + //TEST#1: FAULT HANDLER II [NTH CLOCK NORMAL] [10 sec] + { + char cmd0[BUFLEN] = "nclock 5 1"; + char cmd1[BUFLEN] = "run tpr1 11"; + char cmd2[BUFLEN] = "run tpr2 6"; + char cmd3[BUFLEN] = "run tnclock1 11"; + char cmdU[BUFLEN] = "run tnclock3 11"; + +// execute_command(cmd0); +// execute_command(cmdU); + } + //TEST#2: FAULT HANDLER II [NTH CLOCK MODIFIED] [10 sec] + { + char cmd0[BUFLEN] = "nclock 5 2"; + char cmd1[BUFLEN] = "run tpr1 11"; + char cmd2[BUFLEN] = "run tpr2 6"; + char cmd3[BUFLEN] = "run tnclock2 11"; + +// execute_command(cmd0); +// execute_command(cmd3); + } + + //TEST#3: SEMAPHORES [30 sec] + { + char cmd1[BUFLEN] = "run tsem1 500"; //5 sec + char cmd2[BUFLEN] = "run tsem2 500"; //20 sec + char cmdU[BUFLEN] = "run tair 500"; //10 sec +// execute_command(cmd1); + } + + //TEST#4: PRIORITY RR SCHEDULER + { + char cmd01[BUFLEN] = "schedPRIRR 10 40 1000"; + char cmd03[BUFLEN] = "schedPRIRR 10 40 20"; +// execute_command(cmd03); + + char cmdU1_1[BUFLEN] = "tst priorityRR 0"; //52 sec + char cmdU2_1[BUFLEN] = "tst priorityRR 1"; //58 sec + char cmdU3_1[BUFLEN] = "tst priorityRR 2"; //90 sec +// execute_command(cmdU3_1); + } + + //TEST#4: BONUSES + { + //[1] EXIT I + { +// char cmd0_1[BUFLEN] = "fifo"; +// char cmd1_1[BUFLEN] = "run tef1 5"; //4s +// char cmd2_1[BUFLEN] = "run tef2 15"; //20s +// // execute_command(cmd0_1); +// // execute_command(cmd2_1); +// +// char cmd0_2[BUFLEN] = "lru 2"; +// char cmd1_2[BUFLEN] = "run tef1 5 3"; //6s +// char cmd2_2[BUFLEN] = "run tef2 15 5"; //25s +// // execute_command(cmd0_2); +// // execute_command(cmd2_2); + } + //[2] FREE SHARED OBJECT + { + char cmd1[BUFLEN] = "run tshr4 3000"; + char cmd2[BUFLEN] = "run tshr5 3000"; + //execute_command(cmd1); + } + } + //TEST#5: OVERALL SCENARIOS [3min] + { +// char cmd0_1[BUFLEN] = "fifo"; +// char cmd0_2[BUFLEN] = "lru 2"; +// execute_command(cmd0_1); +// +// char cmd1[BUFLEN] = "run sc_MultipleApps 10000"; //45s +// char cmd2[BUFLEN] = "run sc_LEAK_NOLEAK 5000"; //55s +// char cmd3[BUFLEN] = "run sc_FIFO_LRUList 5000"; //35s +// execute_command(cmd1); +// +// char cmd4_1[BUFLEN] = "schedBSD 64 5"; +// char cmd4_2[BUFLEN] = "run sc_bsd_1 20 20"; //fifo //1m20s +// char cmd5_2[BUFLEN] = "run sc_bsd_1 20 5 20"; //lru //1m +// // execute_command(cmd4_1); +// // execute_command(cmd5_2); + + } + cprintf("MS3 Automatic testing is ENDED\n") ; + autograde = 0; + } get_into_prompt(); } } @@ -272,7 +366,7 @@ void _panic_into_prompt(const char *file, int line, const char *fmt,...) cprintf("\n"); va_end(ap); -// dead: + // dead: /* break into the fos scheduler */ //2013: Check if the panic occur when running an environment struct Env* cur_env = get_cpu_proc(); diff --git a/kern/mem/kheap.c b/kern/mem/kheap.c index d47745f..4169f25 100644 --- a/kern/mem/kheap.c +++ b/kern/mem/kheap.c @@ -113,7 +113,7 @@ void *sbrk(int numOfPages) va = va + PAGE_SIZE; } } - //cprintf("\n kernel sbrk called with number of pages = %d \n", numOfPages); +// cprintf("\n kernel sbrk called with number of pages = %d \n", numOfPages); return (void *)previous_segBreak; // MS2: COMMENT THIS LINE BEFORE START CODING========== // return (void*)-1 ; @@ -518,7 +518,7 @@ void *krealloc(void *virtual_address, uint32 new_size) { // cprintf("krealloc: reallocating a block to page section \n"); if (free_frames < new_pages) - return virtual_address; + return NULL; new_address = kmalloc(new_size); diff --git a/kern/mem/shared_memory_manager.c b/kern/mem/shared_memory_manager.c index 6e1139b..7a1f60b 100644 --- a/kern/mem/shared_memory_manager.c +++ b/kern/mem/shared_memory_manager.c @@ -221,6 +221,29 @@ int createSharedObject(int32 ownerID, char* shareName, uint32 size, index_of_framesStorage++; } shared_obj->ID=(uint32)virtual_address& 0x7FFFFFFF; + // ---------- for free env + myenv->shared_object_no+=1; //env created a shared obj + + if(myenv->shared_object_no == 1){ + myenv->startVAs = (uint32** )kmalloc(sizeof(int)); + myenv->startVAs[0] = (uint32 *)virtual_address; + }else{ + uint32 *prevVAs[myenv->shared_object_no-1]; + for(int i=0; ishared_object_no-1; i++) + prevVAs[i] = myenv->startVAs[i]; + + myenv->startVAs = (uint32 **)krealloc(myenv->startVAs, myenv->shared_object_no*sizeof(uint32)); + + for(int i=0; ishared_object_no-1; i++) + myenv->startVAs[i] = prevVAs[i]; + + myenv->startVAs[myenv->shared_object_no - 1] = (uint32*)virtual_address; + + } + + + shared_obj->referenced_ids = NULL; + shared_obj->refCounter = 0; return shared_obj->ID; } @@ -228,6 +251,32 @@ int createSharedObject(int32 ownerID, char* shareName, uint32 size, //====================== // [5] Get Share Object: //====================== +void adjustReferences(struct Share* sharedObj, struct Env * env, uint32 va){ + + // ignore the reference of the env that created shared object + int32 referencesNumber = sharedObj->references - 1; + int32 referenced_id = env->env_id; + + // there's previous references need to store their values + if(referencesNumber != 1){ + int32* prevIds[referencesNumber-1]; + + for(int i=0; ireferenced_ids[i]; + + sharedObj->referenced_ids = (int32 **)krealloc(sharedObj->referenced_ids, referencesNumber*sizeof(int32)); + + for(int i=0; ireferenced_ids[i] = prevIds[i]; + + sharedObj->referenced_ids[referencesNumber - 1] = (int32*)referenced_id; + + }else{ + sharedObj->referenced_ids = (int32 **)kmalloc(referencesNumber*sizeof(int32)); + sharedObj->referenced_ids[0] = (int32*)referenced_id; + } + +} int getSharedObject(int32 ownerID, char* shareName, void* virtual_address) { //TODO: [PROJECT'24.MS2 - #21] [4] SHARED MEMORY [KERNEL SIDE] - getSharedObject() @@ -237,15 +286,15 @@ int getSharedObject(int32 ownerID, char* shareName, void* virtual_address) struct Env* myenv = get_cpu_proc(); //The calling environment struct Share* my_shared_object = get_share(ownerID, shareName); - bool lock_already_held = holding_spinlock(&AllShares.shareslock); - if (!lock_already_held) { - acquire_spinlock(&AllShares.shareslock); - } +// bool lock_already_held = holding_spinlock(&AllShares.shareslock); +// if (!lock_already_held) { +// acquire_spinlock(&AllShares.shareslock); +// } if(my_shared_object==NULL){ - if (!lock_already_held) { - release_spinlock(&AllShares.shareslock); - } +// if (!lock_already_held) { +// release_spinlock(&AllShares.shareslock); +// } return E_SHARED_MEM_NOT_EXISTS; } @@ -268,9 +317,12 @@ int getSharedObject(int32 ownerID, char* shareName, void* virtual_address) } my_shared_object->references = my_shared_object->references + 1; - if (!lock_already_held) { - release_spinlock(&AllShares.shareslock); - } + my_shared_object->refCounter += 1; + + adjustReferences(my_shared_object, myenv, (uint32) virtual_address); +// if (!lock_already_held) { +// release_spinlock(&AllShares.shareslock); +// } return my_shared_object->ID; } diff --git a/kern/mem/shared_memory_manager.h b/kern/mem/shared_memory_manager.h index 226d4c4..802584f 100644 --- a/kern/mem/shared_memory_manager.h +++ b/kern/mem/shared_memory_manager.h @@ -34,6 +34,9 @@ struct Share // list link pointers LIST_ENTRY(Share) prev_next_info; + int32 **referenced_ids; + int refCounter; + }; //List of all shared objects diff --git a/kern/proc/user_environment.c b/kern/proc/user_environment.c index 3740dee..a62e7bd 100644 --- a/kern/proc/user_environment.c +++ b/kern/proc/user_environment.c @@ -457,6 +457,43 @@ void env_start(void) //=============================== // 3) FREE ENV FROM THE SYSTEM: //=============================== +void checkReferences(struct Share* obj) +{ + struct Share *sharedObj = NULL; + LIST_FOREACH(sharedObj, &AllShares.shares_list) + { + if (sharedObj->ID == obj->ID) + break; + } + if (sharedObj == NULL) + return; + if (obj->references == 0) + { + if (!holding_spinlock(&AllShares.shareslock)) + acquire_spinlock(&AllShares.shareslock); + LIST_REMOVE(&AllShares.shares_list, obj); + if (!holding_spinlock(&AllShares.shareslock)) + release_spinlock(&AllShares.shareslock); + kfree((void *)obj->framesStorage); + kfree((void*)obj); + } +} + +void freePages(struct Env *e, int pages, void *startVa) +{ + uint32 va = (uint32)startVa; + while (pages) + { + uint32 *ptr_page_table = NULL; + struct FrameInfo *ptr_frame = get_frame_info(e->env_page_directory, va, &ptr_page_table); + free_frame(ptr_frame); + unmap_frame(e->env_page_directory, va); + + va = va + PAGE_SIZE; + pages--; + } +} + // Frees environment "e" and all memory it uses. // void env_free(struct Env *e) @@ -500,7 +537,49 @@ void env_start(void) } // [3] free shared objects // [4] free semaphores - + // [3] free shared objects + // [4] free semaphores + int foundShared = 0; + struct Share *sharedObj = NULL; + if (!holding_spinlock(&AllShares.shareslock)) + acquire_spinlock(&AllShares.shareslock); + + LIST_FOREACH(sharedObj, &AllShares.shares_list) + { + if (e->shared_object_no > 0) + { + for (int i = 0; i < e->shared_object_no; i++) + { + if (sharedObj->ID == ((int32)e->startVAs[i] & 0x7FFFFFFF)) + { + foundShared = 1; + int pages = ROUNDUP(sharedObj->size, PAGE_SIZE) / PAGE_SIZE; + freePages(e, pages, e->startVAs[i]); + sharedObj->references -= 1; + checkReferences(sharedObj); + } + } + } + } + if (!holding_spinlock(&AllShares.shareslock)) + release_spinlock(&AllShares.shareslock); + + if (!foundShared) + { + struct Share *sharedObj = NULL; + LIST_FOREACH(sharedObj, &AllShares.shares_list) + { + for (int i = 0; i < sharedObj->refCounter; i++) + { + if ((int32)sharedObj->referenced_ids[i] == e->env_id) + { + sharedObj->references -= 1; + checkReferences(sharedObj); + break; + } + } + } + } // [5] free page tables for (int i=0; ienv_id; + prog_orders[0][env_count[0]++] = env->env_id; break; case -5: - prog_orders[1][nice_count[1]++] = env->env_id; + prog_orders[1][env_count[1]++] = env->env_id; break; case 0: - prog_orders[2][nice_count[2]++] = env->env_id; + prog_orders[2][env_count[2]++] = env->env_id; break; case 5: - prog_orders[3][nice_count[3]++] = env->env_id; + prog_orders[3][env_count[3]++] = env->env_id; break; case 10: - prog_orders[4][nice_count[4]++] = env->env_id; + prog_orders[4][env_count[4]++] = env->env_id; break; } sched_new_env(env); @@ -114,17 +114,17 @@ void test_bsd_nice_0() sched_print_all(); // print_order(prog_orders); int start_idx = 0; - for (int i = 0; i < TOTAL_NICE_VALUES; i++) + for (int i = 0; i < TOTAL_TEST_VALUES; i++) { for (int j = 0; prog_orders[i][j] != 0; j++) { - int exist = find_in_range(prog_orders[i][j], start_idx, nice_count[i]); + int exist = find_in_range(prog_orders[i][j], start_idx, env_count[i]); if (exist == -1) panic("The programs' order of finishing is not correct\n"); } - start_idx += nice_count[i]; + start_idx += env_count[i]; } - firstTimeTestBSD = 0; + firstTimeTest = 0; } cprintf("\nCongratulations!! test_bsd_nice_0 completed successfully.\n"); } @@ -132,9 +132,9 @@ void test_bsd_nice_0() void test_bsd_nice_1() { - if (firstTimeTestBSD) + if (firstTimeTest) { - firstTimeTestBSD = 0; + firstTimeTest = 0; struct Env *fibEnv = env_create("bsd_fib", 500, 0, 0); struct Env *fibposnEnv = env_create("bsd_fib_posn", 500, 0, 0); struct Env *fibnegnEnv = env_create("bsd_fib_negn", 500, 0, 0); @@ -179,15 +179,15 @@ void test_bsd_nice_1() void test_bsd_nice_2() { - if (firstTimeTestBSD) + if (firstTimeTest) { chksch(1); - firstTimeTestBSD = 0; + firstTimeTest = 0; int nice_values[] = {15, 5, 0, -5, -15}; for (int i = 0; i < INSTANCES_NUMBER; i++) { struct Env *env = env_create("bsd_matops", 10000, 0, 0); - int nice_index = i % TOTAL_NICE_VALUES; + int nice_index = i % TOTAL_TEST_VALUES; env_set_nice(env, nice_values[nice_index]); if (env == NULL) panic("Loading programs failed\n"); @@ -197,19 +197,19 @@ void test_bsd_nice_2() switch (nice_values[nice_index]) { case -15: - prog_orders[0][nice_count[0]++] = env->env_id; + prog_orders[0][env_count[0]++] = env->env_id; break; case -5: - prog_orders[1][nice_count[1]++] = env->env_id; + prog_orders[1][env_count[1]++] = env->env_id; break; case 0: - prog_orders[2][nice_count[2]++] = env->env_id; + prog_orders[2][env_count[2]++] = env->env_id; break; case 5: - prog_orders[3][nice_count[3]++] = env->env_id; + prog_orders[3][env_count[3]++] = env->env_id; break; case 15: - prog_orders[4][nice_count[4]++] = env->env_id; + prog_orders[4][env_count[4]++] = env->env_id; break; } sched_new_env(env); @@ -225,17 +225,236 @@ void test_bsd_nice_2() sched_print_all(); // print_order(prog_orders); int start_idx = 0; - for (int i = 0; i < TOTAL_NICE_VALUES; i++) + for (int i = 0; i < TOTAL_TEST_VALUES; i++) { for (int j = 0; prog_orders[i][j] != 0; j++) { - int exist = find_in_range(prog_orders[i][j], start_idx, nice_count[i]); + int exist = find_in_range(prog_orders[i][j], start_idx, env_count[i]); if (exist == -1) panic("The programs' order of finishing is not correct\n"); } - start_idx += nice_count[i]; + start_idx += env_count[i]; } - firstTimeTestBSD = 0; + firstTimeTest = 0; } cprintf("\nCongratulations!! test_bsd_nice_2 completed successfully.\n"); } + + +void test_priorityRR_0() +{ + if (firstTimeTest) + { + firstTimeTest = 0; + int priority_values[] = {0, 2, 4, 6, 8}; + for (int i = 0; i < INSTANCES_NUMBER/2; i++) + { + struct Env *env ; + if (i == 4) + { + env = env_create("priRR_fib_small", 500, 0, 0); + } + else + { + env = env_create("priRR_fib", 500, 0, 0); + } + int priority_index = i % TOTAL_TEST_VALUES; + env_set_priority(env->env_id, priority_values[priority_index]); + if (env == NULL) + panic("Loading programs failed\n"); + if (env->page_WS_max_size != 500) + panic("The program working set size is not correct\n"); + + switch (priority_values[priority_index]) + { + case 0: + prog_orders[0][env_count[0]++] = env->env_id; + break; + case 2: + prog_orders[1][env_count[1]++] = env->env_id; + break; + case 4: + prog_orders[2][env_count[2]++] = env->env_id; + break; + case 6: + prog_orders[3][env_count[3]++] = env->env_id; + break; + case 8: + prog_orders[4][env_count[4]++] = env->env_id; + break; + } + sched_new_env(env); + } + // print_order(prog_orders); + cprintf("> Running... (After all running programs finish, Run the same command again.)\n"); + execute_command("runall"); + } + else + { + cprintf("> Checking...\n"); + sched_print_all(); + // print_order(prog_orders); + int start_idx = 0; + for (int i = 0; i < TOTAL_TEST_VALUES; i++) + { + for (int j = 0; prog_orders[i][j] != 0; j++) + { + int exist = find_in_range(prog_orders[i][j], start_idx, env_count[i]); + if (exist == -1) + panic("The programs' order of finishing is not correct\n"); + } + start_idx += env_count[i]; + } + firstTimeTest = 0; + } + //cprintf("\nCongratulations!! test_priorityRR_0 completed successfully.\n"); + cprintf("\nCongratulations!!... test is completed.\n"); + +} + +void test_priorityRR_1() +{ + if (firstTimeTest) + { + rsttst(); + firstTimeTest = 0; + struct Env *fibPri0Env = env_create("priRR_fib", 500, 0, 0); + struct Env *fibPri4Env = env_create("priRR_fib_pri4", 500, 0, 0); + struct Env *fibPri8Env = env_create("priRR_fib_pri8", 500, 0, 0); + struct Env *fibPri2ParentEnv = env_create("priRR_fib_create", 500, 0, 0); + if (fibPri0Env == NULL || fibPri4Env == NULL || fibPri8Env == NULL || fibPri2ParentEnv == NULL) + panic("Loading programs failed\n"); + if (fibPri0Env->page_WS_max_size != 500 || fibPri4Env->page_WS_max_size != 500 || fibPri8Env->page_WS_max_size != 500 || fibPri2ParentEnv->page_WS_max_size != 500) + panic("The programs should be initially loaded with the given working set size.\n"); + sched_new_env(fibPri8Env); + sched_new_env(fibPri0Env); + sched_new_env(fibPri4Env); + sched_new_env(fibPri2ParentEnv); + env_set_priority(fibPri2ParentEnv->env_id, 6); + + prog_orders[0][0] = fibPri0Env->env_id; + prog_orders[1][0] = fibPri4Env->env_id; + prog_orders[2][0] = fibPri2ParentEnv->env_id ; //id of the parent + prog_orders[3][0] = fibPri2ParentEnv->env_id + 1; //id of the 1st created child fib + prog_orders[4][0] = fibPri8Env->env_id; + prog_orders[5][0] = fibPri2ParentEnv->env_id + 2; //id of the 2nd created child fib + + cprintf("> Running... (After all running programs finish, Run the same command again.)\n"); + execute_command("runall"); + } + else + { + cprintf("> Checking...\n"); + sched_print_all(); + // print_order(prog_orders); + int i = 0; + struct Env *env = NULL; + acquire_spinlock(&ProcessQueues.qlock); + { + //REVERSE LOOP ON EXIT LIST (to be the same as the queue order) + int numOfExitEnvs = LIST_SIZE(&ProcessQueues.env_exit_queue); + env = LIST_LAST(&ProcessQueues.env_exit_queue); + for (; i < numOfExitEnvs; env = LIST_PREV(env)) + //LIST_FOREACH_R(env, &env_exit_queue) + { + cprintf("%s - id=%d, priority=%d\n", env->prog_name, env->env_id, env->priority); + if (prog_orders[i][0] != env->env_id) + panic("The programs' order of finishing is not correct\n"); + i++; + } + } + release_spinlock(&ProcessQueues.qlock); + } + //cprintf("\nCongratulations!! test_priorityRR_1 completed successfully.\n"); + cprintf("\nCongratulations!!... test is completed.\n"); + +} + +void test_priorityRR_2() +{ + if (firstTimeTest) + { + firstTimeTest = 0; + int priority_values[] = {0, 2, 4, 6}; + for (int i = 0; i < INSTANCES_NUMBER - 2; i++) + { + struct Env *env = env_create("priRR_fib", 500, 0, 0); + int priority_index = i % (TOTAL_TEST_VALUES-1); + env_set_priority(env->env_id, priority_values[priority_index]); + if (env == NULL) + panic("Loading programs failed\n"); + if (env->page_WS_max_size != 500) + panic("The program working set size is not correct\n"); + + switch (priority_values[priority_index]) + { + case 0: + prog_orders[1][env_count[1]++] = env->env_id; + break; + case 2: + prog_orders[2][env_count[2]++] = env->env_id; + break; + case 4: + prog_orders[3][env_count[3]++] = env->env_id; + break; + case 6: + prog_orders[4][env_count[4]++] = env->env_id; + break; + } + sched_new_env(env); + } + + int priority_values2[] = {0, 1, 2, 3, 4, 5, 6, 7 }; + for (int i = 0; i < INSTANCES_NUMBER - 2; i++) + { + struct Env *env = env_create("priRR_fib_small", 500, 0, 0); + int priority_index = i ; + env_set_priority(env->env_id, priority_values2[priority_index]); + if (env == NULL) + panic("Loading programs failed\n"); + if (env->page_WS_max_size != 500) + panic("The program working set size is not correct\n"); + + prog_orders[0][env_count[0]++] = env->env_id; + + sched_new_env(env); + } + // print_order(prog_orders); + cprintf("> Running... (After all running programs finish, Run the same command again.)\n"); + execute_command("runall"); + } + else + { + cprintf("> Checking...\n"); + sched_print_all(); + // print_order(prog_orders); + int start_idx = 0; + for (int i = 0; i < TOTAL_TEST_VALUES; i++) + { + if (i == 0) //small programs should finish in their strict order + { + for (int j = 0; j < INSTANCES_NUMBER - 2; j++) + { + int exist = find_in_range(prog_orders[i][j], j, 1); + if (exist == -1) + panic("The programs' order of finishing is not correct\n"); + } + start_idx += env_count[i]; + } + else + { + for (int j = 0; prog_orders[i][j] != 0; j++) + { + int exist = find_in_range(prog_orders[i][j], start_idx, env_count[i]); + if (exist == -1) + panic("The programs' order of finishing is not correct\n"); + } + start_idx += env_count[i]; + } + } + firstTimeTest = 0; + } + //cprintf("\nCongratulations!! test_priorityRR_2 completed successfully.\n"); + cprintf("\nCongratulations!!... test is completed.\n"); + +} diff --git a/kern/tests/test_scheduler.h b/kern/tests/test_scheduler.h index 36aeff9..ee69092 100644 --- a/kern/tests/test_scheduler.h +++ b/kern/tests/test_scheduler.h @@ -16,4 +16,8 @@ void test_bsd_nice_0(); void test_bsd_nice_1(); void test_bsd_nice_2(); +void test_priorityRR_0(); +void test_priorityRR_1(); +void test_priorityRR_2(); + #endif diff --git a/kern/tests/tst_handler.c b/kern/tests/tst_handler.c index 79810cd..cd87d20 100644 --- a/kern/tests/tst_handler.c +++ b/kern/tests/tst_handler.c @@ -21,44 +21,46 @@ #include "../tests/test_scheduler.h" struct Test tests[] = { - {"3functions", "Env Load: test the creation of new dir, tables and pages WS", tst_three_creation_functions}, - {"kfreeall", "Kernel Heap: test kfreeall (freed frames, mem access...etc)", tst_kfreeall}, - {"kexpand", "Kernel Heap: test expanding last allocated var", tst_kexpand}, - {"kshrink", "Kernel Heap: test shrinking last allocated var", tst_kshrink}, - {"kfreelast", "Kernel Heap: test freeing last allocated var", tst_kfreelast}, - {"priority1", "Tests the priority of the program (Normal and Higher)", tst_priority1}, - {"priority2", "Tests the priority of the program (Normal and Lower)", tst_priority2}, - {"mlfq_sc4", "Scenario#4: MLFQ", tst_sc_MLFQ}, - {"bsd_nice", "BSD Scheduler: check order of running multiple instances of same program with different nice values", tst_bsd_nice}, + {"3functions", "Env Load: test the creation of new dir, tables and pages WS", tst_three_creation_functions}, + {"kfreeall", "Kernel Heap: test kfreeall (freed frames, mem access...etc)", tst_kfreeall}, + {"kexpand", "Kernel Heap: test expanding last allocated var", tst_kexpand}, + {"kshrink", "Kernel Heap: test shrinking last allocated var", tst_kshrink}, + {"kfreelast", "Kernel Heap: test freeing last allocated var", tst_kfreelast}, + {"priority1", "Tests the priority of the program (Normal and Higher)", tst_priority1}, + {"priority2", "Tests the priority of the program (Normal and Lower)", tst_priority2}, + {"mlfq_sc4","Scenario#4: MLFQ",tst_sc_MLFQ }, + {"bsd_nice", "BSD Scheduler: check order of running multiple instances of same program with different nice values", tst_bsd_nice}, + {"priorityRR", "Priority RR Scheduler: check order of running multiple instances of same program with different priority values", tst_priorityRR}, - // 2022 - {"str2lower", "Test str2lower function", tst_str2lower}, - {"autocomplete", "Test commands autcomplte", tst_autocomplete}, - {"dynalloc", "Test dynamic allocator", tst_dyn_alloc}, - {"pg", "Test paging manipulation for a specific page", tst_paging_manipulation}, - {"chunks", "Test chunk manipulations", tst_chunks}, - {"kheap", "Test KHEAP functions", tst_kheap}, + //2022 + {"str2lower", "Test str2lower function", tst_str2lower}, + {"autocomplete", "Test commands autcomplte", tst_autocomplete}, + {"dynalloc","Test dynamic allocator", tst_dyn_alloc }, + {"pg", "Test paging manipulation for a specific page", tst_paging_manipulation}, + {"chunks","Test chunk manipulations", tst_chunks }, + {"kheap", "Test KHEAP functions", tst_kheap}, }; -// Number of tests = size of the array / size of test structure -uint32 NUM_OF_TESTS = (sizeof(tests) / sizeof(struct Test)); +//Number of tests = size of the array / size of test structure +uint32 NUM_OF_TESTS = (sizeof(tests)/sizeof(struct Test)); + //=================// /*Test MAIN Handler*/ //=================// int tst_handler(int number_of_arguments, char **arguments) { - // Remove "tst" from arguments + //Remove "tst" from arguments for (int a = 0; a < number_of_arguments - 1; ++a) { - arguments[a] = arguments[a + 1]; + arguments[a] = arguments[a+1] ; } number_of_arguments--; - // Check name of the given test and execute its corresponding function + //Check name of the given test and execute its corresponding function int test_found = 0; - int i; + int i ; for (i = 0; i < NUM_OF_TESTS; i++) { if (strcmp(arguments[0], tests[i].name) == 0) @@ -68,7 +70,7 @@ int tst_handler(int number_of_arguments, char **arguments) } } - if (test_found) + if(test_found) { int return_value; return_value = tests[i].function_to_execute(number_of_arguments, arguments); @@ -129,23 +131,23 @@ int tst_kfreelast(int number_of_arguments, char **arguments) int tst_sc_MLFQ(int number_of_arguments, char **arguments) { int numOfSlave2 = strtol(arguments[1], NULL, 10); - int cnt = 0; + int cnt = 0 ; int firstTime = 1; - struct Env *e; + struct Env *e ; acquire_spinlock(&ProcessQueues.qlock); { LIST_FOREACH(e, &ProcessQueues.env_exit_queue) - { + { if (strcmp(e->prog_name, "tmlfq_2") == 0) { if (firstTime) firstTime = 0; - cnt++; + cnt++ ; } else if (!firstTime) break; - } - if (cnt == numOfSlave2) + } + if(cnt == numOfSlave2) { cprintf("Congratulations... MLFQScenario# completed successfully\n"); } @@ -158,6 +160,7 @@ int tst_sc_MLFQ(int number_of_arguments, char **arguments) return 0; } + /*2023*/ int tst_bsd_nice(int number_of_arguments, char **arguments) { @@ -182,6 +185,29 @@ int tst_bsd_nice(int number_of_arguments, char **arguments) return 0; } +/*2024*/ +int tst_priorityRR(int number_of_arguments, char **arguments) +{ + if (number_of_arguments != 2) + { + cprintf("Invalid number of arguments! USAGE: tst priorityRR \n"); + return 0; + } + int testNumber = strtol(arguments[1], NULL, 10); + switch (testNumber) + { + case 0: + test_priorityRR_0(); + break; + case 1: + test_priorityRR_1(); + break; + case 2: + test_priorityRR_2(); + break; + } + return 0; +} int tst_str2lower(int number_of_arguments, char **arguments) { if (number_of_arguments != 1) @@ -203,52 +229,50 @@ int tst_dyn_alloc(int number_of_arguments, char **arguments) { if (number_of_arguments != 2) { - cprintf("Invalid number of arguments! USAGE: tst dynalloc \n"); + cprintf("Invalid number of arguments! USAGE: tst dynalloc \n") ; return 0; } - // str2lower(arguments[1]); - // Test 1 Example for initialize_MemBlocksList: tstdynalloc init - if (strcmp(arguments[1], "init") == 0) + //str2lower(arguments[1]); + // Test 1 Example for initialize_MemBlocksList: tstdynalloc init + if(strcmp(arguments[1], "init") == 0) { test_initialize_dynamic_allocator(); } // Test 2 Example for alloc_block_FF: tstdynalloc allocFF - else if (strcmp(arguments[1], "allocff") == 0) + else if(strcmp(arguments[1], "allocff") == 0) { test_alloc_block_FF(); } // Test 3 Example for alloc_block_BF: tstdynalloc allocBF - else if (strcmp(arguments[1], "allocbf") == 0) + else if(strcmp(arguments[1], "allocbf") == 0) { test_alloc_block_BF(); } // Test 4 Example for alloc_block_NF: tstdynalloc allocNF - else if (strcmp(arguments[1], "allocnf") == 0) + else if(strcmp(arguments[1], "allocnf") == 0) { test_alloc_block_NF(); } // Test 5 Example for free_block: tstdynalloc freeFF - else if (strcmp(arguments[1], "freeff") == 0) + else if(strcmp(arguments[1], "freeff") == 0) { test_free_block_FF(); } // Test 6 Example for free_block: tstdynalloc freeBF - else if (strcmp(arguments[1], "freebf") == 0) + else if(strcmp(arguments[1], "freebf") == 0) { test_free_block_BF(); } // Test 7 Example for free_block: tstdynalloc freeNF - else if (strcmp(arguments[1], "freenf") == 0) + else if(strcmp(arguments[1], "freenf") == 0) { test_free_block_NF(); } // Test 8 Example for realloc_block_ff: tstdynalloc reallocFF - else if (strcmp(arguments[1], "reallocff") == 0) + else if(strcmp(arguments[1], "reallocff") == 0) { - // test_realloc_block_FF(); - test_realloc_block_FF_COMPLETE(); - // test_realloc_block_FF(); - test_realloc_block_FF_COMPLETE(); + test_realloc_block_FF(); + //test_realloc_block_FF_COMPLETE(); } return 0; } @@ -257,36 +281,36 @@ int tst_chunks(int number_of_arguments, char **arguments) { if (number_of_arguments != 2) { - cprintf("Invalid number of arguments! USAGE: tstchunk \n"); + cprintf("Invalid number of arguments! USAGE: tstchunk \n") ; return 0; } // CUT-PASTE Test - if (strcmp(arguments[1], "cutpaste") == 0) + if(strcmp(arguments[1], "cutpaste") == 0) { test_cut_paste_pages(); } // COPY-PASTE Test - else if (strcmp(arguments[1], "copypaste") == 0) + else if(strcmp(arguments[1], "copypaste") == 0) { test_copy_paste_chunk(); } // SHARE Test - else if (strcmp(arguments[1], "share") == 0) + else if(strcmp(arguments[1], "share") == 0) { test_share_chunk(); } // ALLOCATE Test - else if (strcmp(arguments[1], "allocate") == 0) + else if(strcmp(arguments[1], "allocate") == 0) { test_allocate_chunk(); } // REQUIRED SPACE Test - else if (strcmp(arguments[1], "required_space") == 0) + else if(strcmp(arguments[1], "required_space") == 0) { test_calculate_required_frames(); } // ALLOCATED SPACE Test - else if (strcmp(arguments[1], "allocated_space") == 0) + else if(strcmp(arguments[1], "allocated_space") == 0) { test_calculate_allocated_space(); } @@ -297,39 +321,39 @@ int tst_paging_manipulation(int number_of_arguments, char **arguments) { if (number_of_arguments != 2) { - cprintf("Invalid number of arguments! USAGE: tstpg \n"); + cprintf("Invalid number of arguments! USAGE: tstpg \n") ; return 0; } // Test 1.1-Set/Clear permissions: tstpg scperm1 - if (strcmp(arguments[1], "scperm1") == 0) + if(strcmp(arguments[1], "scperm1") == 0) { test_pt_set_page_permissions(); } // Test 1.2-Set/Clear permissions: tstpg scperm2 - else if (strcmp(arguments[1], "scperm2") == 0) + else if(strcmp(arguments[1], "scperm2") == 0) { test_pt_set_page_permissions_invalid_va(); } // Test 2-Get permissions: tstpg getperm - else if (strcmp(arguments[1], "getperm") == 0) + else if(strcmp(arguments[1], "getperm") == 0) { test_pt_get_page_permissions(); } // Test 3.1-Clear entry: tstpg clear1 - else if (strcmp(arguments[1], "clear1") == 0) + else if(strcmp(arguments[1], "clear1") == 0) { test_pt_clear_page_table_entry(); } // Test 3.2-Clear entry: tstpg clear2 - else if (strcmp(arguments[1], "clear2") == 0) + else if(strcmp(arguments[1], "clear2") == 0) { test_pt_clear_page_table_entry_invalid_va(); } // Test 4-Convert virtual to physical: tstpg v2p - // else if(strcmp(arguments[1], "v2p") == 0) - // { - // test_virtual_to_physical(); - // } +// else if(strcmp(arguments[1], "v2p") == 0) +// { +// test_virtual_to_physical(); +// } return 0; } @@ -338,47 +362,47 @@ int tst_kheap(int number_of_arguments, char **arguments) // Parameters Validation Checking if (strcmp(arguments[2], "kmalloc") == 0 && number_of_arguments != 4) { - cprintf("Invalid number of arguments! USAGE: tst kheap kmalloc <1 or 2 or 3>\n"); + cprintf("Invalid number of arguments! USAGE: tst kheap kmalloc <1 or 2 or 3>\n") ; return 0; } if (strcmp(arguments[2], "kmalloc") != 0 && number_of_arguments != 3) { if (strcmp(arguments[2], "krealloc") != 0 && number_of_arguments != 5) { - cprintf("Invalid number of arguments! USAGE: tst kheap \n"); + cprintf("Invalid number of arguments! USAGE: tst kheap \n") ; return 0; } } // Setting Strategy - if (strcmp(arguments[1], "FF") == 0 || strcmp(arguments[1], "ff") == 0) + if(strcmp(arguments[1], "FF") == 0 || strcmp(arguments[1], "ff") == 0) { setKHeapPlacementStrategyFIRSTFIT(); cprintf("Kernel Heap placement strategy is FIRST FIT\n"); } - else if (strcmp(arguments[1], "BF") == 0 || strcmp(arguments[1], "bf") == 0) + else if(strcmp(arguments[1], "BF") == 0 || strcmp(arguments[1], "bf") == 0) { setKHeapPlacementStrategyBESTFIT(); cprintf("Kernel Heap placement strategy is BEST FIT\n"); } - else if (strcmp(arguments[1], "NF") == 0 || strcmp(arguments[1], "nf") == 0) + else if(strcmp(arguments[1], "NF") == 0 || strcmp(arguments[1], "nf") == 0) { setKHeapPlacementStrategyNEXTFIT(); cprintf("Kernel Heap placement strategy is NEXT FIT\n"); } // Test 1-kmalloc: tst kheap FF kmalloc 1 - if (strcmp(arguments[2], "kmalloc") == 0) + if(strcmp(arguments[2], "kmalloc") == 0) { uint32 testNum = strtol(arguments[3], NULL, 10); - if (isKHeapPlacementStrategyFIRSTFIT()) + if(isKHeapPlacementStrategyFIRSTFIT()) { if (testNum == 0) { cprintf("Error: [Kernel.FirstFit] must specify the test number (1 or 2) as an argument\n"); return 0; } - // Test FIRST FIT allocation + //Test FIRST FIT allocation if (testNum == 1) test_kmalloc(); else if (testNum == 2) @@ -386,7 +410,7 @@ int tst_kheap(int number_of_arguments, char **arguments) else if (testNum == 3) test_kmalloc_firstfit2(); } - else if (isKHeapPlacementStrategyBESTFIT()) + else if(isKHeapPlacementStrategyBESTFIT()) { if (testNum == 0) { @@ -400,26 +424,26 @@ int tst_kheap(int number_of_arguments, char **arguments) else if (testNum == 3) test_kmalloc_bestfit2(); } - else if (isKHeapPlacementStrategyNEXTFIT()) + else if(isKHeapPlacementStrategyNEXTFIT()) { if (testNum == 0) { cprintf("Error: [Kernel.NextFit] must specify the test number (1 or 2) as an argument\n"); return 0; } - // Test cont. allocation + //Test cont. allocation if (testNum == 1) test_kmalloc(); - // Test nextfit strategy + //Test nextfit strategy else if (testNum == 2) test_kmalloc_nextfit(); } return 0; } // Test Fast Implementation of kmalloc/kfree FF - else if (strcmp(arguments[2], "fast") == 0) + else if(strcmp(arguments[2], "fast") == 0) { - if (isKHeapPlacementStrategyFIRSTFIT()) + if(isKHeapPlacementStrategyFIRSTFIT()) { test_fastfirstfit(); } @@ -430,46 +454,46 @@ int tst_kheap(int number_of_arguments, char **arguments) return 0; } // Test 2-kfree: tst kheap FF kfree - else if (strcmp(arguments[2], "kfree") == 0) + else if(strcmp(arguments[2], "kfree") == 0) { if (isKHeapPlacementStrategyBESTFIT() || isKHeapPlacementStrategyFIRSTFIT()) { test_kfree_bestfirstfit(); } - else // NEXT & CONT + else //NEXT & CONT { test_kfree(); } return 0; } // Test 3-kphysaddr: tst kheap FF kphysaddr - else if (strcmp(arguments[2], "kphysaddr") == 0) + else if(strcmp(arguments[2], "kphysaddr") == 0) { test_kheap_phys_addr(); return 0; } // Test 4-kvirtaddr: tst kheap FF kvirtaddr - else if (strcmp(arguments[2], "kvirtaddr") == 0) + else if(strcmp(arguments[2], "kvirtaddr") == 0) { test_kheap_virt_addr(); return 0; } // Test 5-krealloc: tst kheap BF krealloc - else if (strcmp(arguments[2], "krealloc") == 0) + else if(strcmp(arguments[2], "krealloc") == 0) { uint32 testNum = strtol(arguments[3], NULL, 10); - if (isKHeapPlacementStrategyFIRSTFIT()) + if(isKHeapPlacementStrategyFIRSTFIT()) { if (testNum == 0) { cprintf("Error: [Kernel.FirstFit] must specify the test number (1 or 2) as an argument\n"); return 0; } - if (testNum == 1) + if (testNum==1) test_krealloc_FF1(); - else if (testNum == 2) + else if (testNum==2) test_krealloc_FF2(); - else if (testNum == 3) + else if (testNum==3) test_krealloc_FF3(); } if (isKHeapPlacementStrategyNEXTFIT()) @@ -490,4 +514,6 @@ int tst_kheap(int number_of_arguments, char **arguments) return 0; } -// END====================================================== + +//END====================================================== + diff --git a/kern/tests/tst_handler.h b/kern/tests/tst_handler.h index 06c2ddc..a4ccbd3 100644 --- a/kern/tests/tst_handler.h +++ b/kern/tests/tst_handler.h @@ -51,6 +51,8 @@ int tst_paging_manipulation(int number_of_arguments, char **arguments); int tst_chunks(int number_of_arguments, char **arguments); int tst_kheap(int number_of_arguments, char **arguments); +/*2024*/ +int tst_priorityRR(int number_of_arguments, char **arguments); #endif /* KERN_TESTS_TST_HANDLER_H_ */ diff --git a/kern/tests/utilities.c b/kern/tests/utilities.c index 9d7d365..ae532ec 100644 --- a/kern/tests/utilities.c +++ b/kern/tests/utilities.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "../trap/syscall.h" @@ -164,6 +165,18 @@ void sys_utilities(char* utilityName, int value) assert(env->env_id == envID) ; env_set_nice(env, value); } + else if (strncmp(utilityName, "__PRIRRSetPriority@", strlen("__PRIRRSetPriority@")) == 0) + { + int number_of_tokens; + //allocate array of char * of size MAX_ARGUMENTS = 16 found in string.h + char *tokens[MAX_ARGUMENTS]; + strsplit(utilityName, "@", tokens, &number_of_tokens) ; + int envID = strtol(tokens[1], NULL, 10); + struct Env* env = NULL ; + envid2env(envID, &env, 0); + assert(env->env_id == envID) ; + env_set_priority(envID, value); + } else if (strncmp(utilityName, "__CheckExitOrder@", strlen("__CheckExitOrder@")) == 0) { int* numOfInstances = (int*) value ; @@ -218,19 +231,46 @@ void sys_utilities(char* utilityName, int value) release_spinlock(&ProcessQueues.qlock); if (*numOfInstances != 0 || success == 0) { - cprintf("###########################################\n"); - cprintf("%s: check exit order is FAILED\n", progName); - cprintf("###########################################\n"); + cons_lock(); + { + cprintf("###########################################\n"); + cprintf("%s: check exit order is FAILED\n", progName); + cprintf("###########################################\n"); + } + cons_unlock(); *numOfInstances = 0; //to indicate the failure of test } else { - cprintf("####################################################\n"); - cprintf("%s: check exit order is SUCCEEDED\n", progName); - cprintf("####################################################\n"); + cons_lock(); + { + cprintf("####################################################\n"); + cprintf("%s: check exit order is SUCCEEDED\n", progName); + cprintf("####################################################\n"); + } + cons_unlock(); *numOfInstances = 1; //to indicate the success of test } } + else if (strncmp(utilityName, "__NthClkRepl@", strlen("__NthClkRepl@")) == 0) + { + int number_of_tokens; + //allocate array of char * of size MAX_ARGUMENTS = 16 found in string.h + char *tokens[MAX_ARGUMENTS]; + strsplit(utilityName, "@", tokens, &number_of_tokens) ; + int type = strtol(tokens[1], NULL, 10); + int N = value; + if (type == 2) + N *= -1; + setPageReplacmentAlgorithmNchanceCLOCK(N); + cons_lock(); + { + cprintf("\n*********************************************************" + "\nPAGE REPLACEMENT IS SET TO Nth Clock type = %d (N = %d)." + "\n*********************************************************\n", type, N); + } + cons_unlock(); + } else if (strcmp(utilityName, "__Sleep__") == 0) { if (__firstTimeSleep) @@ -289,6 +329,52 @@ void sys_utilities(char* utilityName, int value) uint32* lockOwnerID = (uint32*) value ; *lockOwnerID =__tstslplk__.pid; } + else if (strcmp(utilityName, "__GetConsLockedCnt__") == 0) + { + uint32* consLockCnt = (uint32*) value ; + *consLockCnt = queue_size(&(conslock.chan.queue)); + } + else if (strcmp(utilityName, "__tmpReleaseConsLock__") == 0) + { + if (CONS_LCK_METHOD == LCK_SLEEP) + { + conslock.pid = get_cpu_proc()->env_id; + cons_unlock(); + } + } + else if (strcmp(utilityName, "__getKernelSBreak__") == 0) + { + uint32* ksbrk = (uint32*) value ; + *ksbrk = (uint32)sbrk(0); + } + else if (strcmp(utilityName, "__changeInterruptStatus__") == 0) + { + if (value == 0) + { + kclock_stop(); + cli(); + struct Env * p = get_cpu_proc(); + if (p == NULL) + { + panic("cons_lock: no running process to block"); + } + p->env_tf->tf_eflags &= ~FL_IF ; + //cprintf("\nINTERRUPT WILL BE DISABLED\n"); + } + else if (value == 1) + { + kclock_stop(); + cli(); + struct Env * p = get_cpu_proc(); + if (p == NULL) + { + panic("cons_unlock: no running process to block"); + } + p->env_tf->tf_eflags |= FL_IF ; + //cprintf("\nINTERRUPT WILL BE ENABLED\n"); + } + } + if ((int)value < 0) { if (strcmp(utilityName, "__ReplStrat__") == 0) @@ -303,6 +389,10 @@ void sys_utilities(char* utilityName, int value) cprintf("\n*************************************\nPAGE REPLACEMENT IS SET TO LRU LISTS.\n*************************************\n"); setPageReplacmentAlgorithmLRU(PG_REP_LRU_LISTS_APPROX); break; + case -PG_REP_NchanceCLOCK: + cprintf("\n*************************************\nPAGE REPLACEMENT IS SET TO Nth Clock Normal (N=1).\n*************************************\n"); + setPageReplacmentAlgorithmNchanceCLOCK(1); + break; default: break; } diff --git a/lib/concurrency.c b/lib/concurrency.c index d17837a..d45b4a7 100644 --- a/lib/concurrency.c +++ b/lib/concurrency.c @@ -8,10 +8,13 @@ env_sleep(uint32 approxMilliSeconds) uint32 time_in_cycles=approxMilliSeconds*CYCLES_PER_MILLISEC; uint32 cycles_counter =0; - struct uint64 baseTime = sys_get_virtual_time() ; + /*2024*/ //USE A USER-SIDE VERSION OF THIS FUNCTION TO AVOID SLOW-DOWN THE PERFORMANCE DUE SYS_CALL (el7 :)) + //struct uint64 baseTime = sys_get_virtual_time() ; + struct uint64 baseTime = get_virtual_time_user() ; while(cycles_counterenv_rLimit + PAGE_SIZE)) / PAGE_SIZE; } -int num_of_unmapped_pages(uint32 start_va) -{ - int num = 0; - uint32 page_index = get_page_index(start_va); - while(start_va < USER_HEAP_MAX && (virtual_addresses_pages_num[page_index]==0)) - { - num = num + 1; - start_va = start_va + PAGE_SIZE; - page_index = get_page_index(start_va); - } - return num; +void mark_pages_allocated(uint32 start_index, uint32 num_pages) { + for (uint32 i = 0; i < num_pages; i++) { + page_marked[start_index + i] = 1; + } + virtual_addresses_pages_num[start_index] = num_pages; +} +void mark_pages_free(uint32 start_index, uint32 num_pages) { + for (uint32 i = 0; i < num_pages; i++) { + page_marked[start_index + i] = 0; + } + virtual_addresses_pages_num[start_index] = 0; } -uint32 FirstFit(uint32 start_va,uint32 size) { - /* - * this function apply FirstFit strategy for user virtual memory - * Parameters: - * start_va -> start address of search - * size -> size in bytes not page or frame number - * return: - * if success ->start virtual address of allocation (uint32) - * if no pages-> return 0 - * */ - - //number of required pages - - uint32 num_of_pages=ROUNDUP(size,PAGE_SIZE)/PAGE_SIZE; - - uint32 final_va = 0; - while (start_va < USER_HEAP_MAX) { - uint32 page_index = get_page_index(start_va); - - // If the current page is allocated, skip it - if (virtual_addresses_pages_num[page_index]!=0) { - - start_va += virtual_addresses_pages_num[page_index] * PAGE_SIZE; - continue; - } - - int consecutive_free_pages = num_of_unmapped_pages(start_va); - if (consecutive_free_pages >= num_of_pages) { - final_va = start_va; - break; - } - // go to next block of free pages - start_va += (consecutive_free_pages * PAGE_SIZE); - } - return final_va; +uint32 FirstFit(uint32 num_pages){ + uint32 consecutive_free = 0; + uint32 start_page = 0; + for (uint32 page = 0; page < NUM_OF_UHEAP_PAGES; page++) { + if (page_marked[page] == 0) { + if (consecutive_free == 0) { + start_page = page; + } + consecutive_free++; + uint32 va = (myEnv->env_rLimit + PAGE_SIZE) + (start_page * PAGE_SIZE); + uint32 end_va = va + (num_pages * PAGE_SIZE); + if (consecutive_free >= num_pages && end_va <= USER_HEAP_MAX) { + return va; + } + } + else + consecutive_free = 0; + } + return 0; } void* malloc(uint32 size) { @@ -84,23 +69,22 @@ void* malloc(uint32 size) //Use sys_isUHeapPlacementStrategyFIRSTFIT() and sys_isUHeapPlacementStrategyBESTFIT() //to check the current strategy if(sys_isUHeapPlacementStrategyFIRSTFIT()) - { - if(size <= DYN_ALLOC_MAX_BLOCK_SIZE) - { - return alloc_block_FF(size); - } - else - { - uint32 start_va = myEnv->env_rLimit + PAGE_SIZE; - uint32 final_va = FirstFit(start_va, size); - if(final_va==0) - return NULL; - sys_allocate_user_mem(final_va, size); - virtual_addresses_pages_num[get_page_index(final_va)]=(size/PAGE_SIZE) + ((size%PAGE_SIZE!=0)?1:0); - return (void *) final_va; - } - } - return (void *) -1; + { + if(size <= DYN_ALLOC_MAX_BLOCK_SIZE) + { + return alloc_block_FF(size); + } + uint32 num_pages = ROUNDUP(size, PAGE_SIZE) / PAGE_SIZE; + uint32 va = FirstFit(num_pages); + + if (va == 0) return NULL; + + sys_allocate_user_mem(va, size); + mark_pages_allocated(get_page_index(va), num_pages); + return (void*)va; + } + return (void *) -1; + } //================================= // [3] FREE SPACE FROM USER HEAP: @@ -112,15 +96,17 @@ void free(void* virtual_address) //panic("free() is not implemented yet...!!"); uint32 va = (uint32)virtual_address; - if(va>=USER_HEAP_START && vaenv_segBreak){ - free_block(virtual_address); - }else if(va>=myEnv->env_rLimit+PAGE_SIZE && va=USER_HEAP_START && vaenv_segBreak){ + free_block(virtual_address); + } + else if(va>=myEnv->env_rLimit+PAGE_SIZE && vaenv_rLimit + PAGE_SIZE, size); + uint32 num_pages = ROUNDUP(size, PAGE_SIZE) / PAGE_SIZE; + uint32 va = FirstFit(num_pages); if(va == 0) return NULL; @@ -148,8 +135,7 @@ void* smalloc(char *sharedVarName, uint32 size, uint8 isWritable) if(check == E_SHARED_MEM_EXISTS || check == E_NO_SHARE) return NULL; - virtual_addresses_pages_num[get_page_index(va)]=(size/PAGE_SIZE) + ((size%PAGE_SIZE!=0)?1:0); - + mark_pages_allocated(get_page_index(va), num_pages); slave_to_master[get_page_index(va)]=va; return (void *) va; @@ -170,8 +156,8 @@ void* sget(int32 ownerEnvID, char *sharedVarName) { return NULL; } - - uint32 va = FirstFit(myEnv->env_rLimit + PAGE_SIZE, size); + uint32 num_pages = ROUNDUP(size, PAGE_SIZE) / PAGE_SIZE; + uint32 va = FirstFit(num_pages); if (va == 0) { return NULL; @@ -185,7 +171,7 @@ void* sget(int32 ownerEnvID, char *sharedVarName) { slave_to_master[get_page_index(va)]=ret; - virtual_addresses_pages_num[get_page_index(va)]=(size/PAGE_SIZE) + ((size%PAGE_SIZE!=0)?1:0); + mark_pages_allocated(get_page_index(va), num_pages); return (void*)va; @@ -215,7 +201,9 @@ void sfree(void* virtual_address) uint32 Id = slave_to_master[get_page_index((uint32)virtual_address)] & 0x7FFFFFFF; sys_freeSharedObject(Id, virtual_address); uint32 va = (uint32)virtual_address; - virtual_addresses_pages_num[get_page_index(va)]=0; + uint32 page_index = get_page_index(va); + uint32 num_pages = virtual_addresses_pages_num[get_page_index(va)]; + mark_pages_free(page_index, num_pages); } diff --git a/user/arrayOperations_Master.c b/user/arrayOperations_Master.c index c0e33b3..a44ba50 100644 --- a/user/arrayOperations_Master.c +++ b/user/arrayOperations_Master.c @@ -126,7 +126,7 @@ _main(void) // int middle = (NumOfElements-1)/2; // if (NumOfElements % 2 != 0) // middle--; - int middle = NumOfElements/2 - 1; /*-1 to make it ZERO-Based*/ + int middle = (NumOfElements+1)/2 - 1; /*-1 to make it ZERO-Based*/ int correctMax = quicksortedArr[last]; int correctMed = quicksortedArr[middle]; diff --git a/user/arrayOperations_mergesort_static.c b/user/arrayOperations_mergesort_static.c new file mode 100644 index 0000000..c6286e3 --- /dev/null +++ b/user/arrayOperations_mergesort_static.c @@ -0,0 +1,162 @@ +#include + +#define SIZE 100000 +int __Left[SIZE] ; +int __Right[SIZE] ; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void PrintElements(int *Elements, int NumOfElements); + +void MSort(int* A, int p, int r); +void Merge(int* A, int p, int q, int r); + +//int *Left; +//int *Right; + +void _main(void) +{ + int32 parentenvID = sys_getparentenvid(); + + int ret; + + /*[1] GET SEMAPHORES*/ + struct semaphore ready = get_semaphore(parentenvID, "Ready"); + struct semaphore finished = get_semaphore(parentenvID, "Finished"); + + /*[2] WAIT A READY SIGNAL FROM THE MASTER*/ + wait_semaphore(ready); + + /*[3] GET SHARED VARs*/ + //Get the cons_mutex ownerID + int* consMutexOwnerID = sget(parentenvID, "cons_mutex ownerID") ; + struct semaphore cons_mutex = get_semaphore(*consMutexOwnerID, "Console Mutex"); + + //Get the shared array & its size + int *numOfElements = NULL; + int *sharedArray = NULL; + sharedArray = sget(parentenvID, "arr") ; + numOfElements = sget(parentenvID, "arrSize") ; + //PrintElements(sharedArray, *numOfElements); + + /*[4] DO THE JOB*/ + //take a copy from the original array + int *sortedArray; + + sortedArray = smalloc("mergesortedArr", sizeof(int) * *numOfElements, 0) ; + int i ; + for (i = 0 ; i < *numOfElements ; i++) + { + sortedArray[i] = sharedArray[i]; + } +// //Create two temps array for "left" & "right" +// Left = smalloc("mergesortLeftArr", sizeof(int) * (*numOfElements), 1) ; +// Right = smalloc("mergesortRightArr", sizeof(int) * (*numOfElements), 1) ; + + MSort(sortedArray, 1, *numOfElements); + + wait_semaphore(cons_mutex); + { + cprintf("Merge sort is Finished!!!!\n") ; + cprintf("will notify the master now...\n"); + cprintf("Merge sort says GOOD BYE :)\n") ; + } + signal_semaphore(cons_mutex); + + /*[5] DECLARE FINISHING*/ + signal_semaphore(finished); +} + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} + + +void MSort(int* A, int p, int r) +{ + if (p >= r) + { + return; + } + + int q = (p + r) / 2; + + MSort(A, p, q); +// cprintf("LEFT is sorted: from %d to %d\n", p, q); + + MSort(A, q + 1, r); +// cprintf("RIGHT is sorted: from %d to %d\n", q+1, r); + + Merge(A, p, q, r); + //cprintf("[%d %d] + [%d %d] = [%d %d]\n", p, q, q+1, r, p, r); + +} + +void Merge(int* A, int p, int q, int r) +{ + int leftCapacity = q - p + 1; + + int rightCapacity = r - q; + + int leftIndex = 0; + + int rightIndex = 0; + + //int* Left = malloc(sizeof(int) * leftCapacity); + int* Left = __Left ; + int* Right = __Right; + //int* Right = malloc(sizeof(int) * rightCapacity); + + int i, j, k; + for (i = 0; i < leftCapacity; i++) + { + Left[i] = A[p + i - 1]; + } + for (j = 0; j < rightCapacity; j++) + { + Right[j] = A[q + j]; + } + + for ( k = p; k <= r; k++) + { + if (leftIndex < leftCapacity && rightIndex < rightCapacity) + { + if (Left[leftIndex] < Right[rightIndex] ) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + else if (leftIndex < leftCapacity) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + +} + diff --git a/user/arrayOperations_quicksort.c b/user/arrayOperations_quicksort.c index 6f81157..9027f97 100644 --- a/user/arrayOperations_quicksort.c +++ b/user/arrayOperations_quicksort.c @@ -64,7 +64,7 @@ void QuickSort(int *Elements, int NumOfElements) void QSort(int *Elements,int NumOfElements, int startIndex, int finalIndex) { if (startIndex >= finalIndex) return; - int pvtIndex = RAND(startIndex, finalIndex) ; + int pvtIndex = RANDU(startIndex, finalIndex) ; Swap(Elements, startIndex, pvtIndex); int i = startIndex+1, j = finalIndex; diff --git a/user/arrayOperations_stats.c b/user/arrayOperations_stats.c index 1ae121f..e2ebdf9 100644 --- a/user/arrayOperations_stats.c +++ b/user/arrayOperations_stats.c @@ -87,7 +87,7 @@ int QSort(int *Elements,int NumOfElements, int startIndex, int finalIndex, int k { if (startIndex >= finalIndex) return Elements[finalIndex]; - int pvtIndex = RAND(startIndex, finalIndex) ; + int pvtIndex = RANDU(startIndex, finalIndex) ; Swap(Elements, startIndex, pvtIndex); int i = startIndex+1, j = finalIndex; @@ -132,7 +132,7 @@ void ArrayStats(int *Elements, int NumOfElements, int64 *mean, int64 *var, int * } } - (*med) = KthElement(Elements, NumOfElements, NumOfElements/2); + (*med) = KthElement(Elements, NumOfElements, (NumOfElements+1)/2); (*mean) /= NumOfElements; (*var) = 0; diff --git a/user/priRR_fib.c b/user/priRR_fib.c new file mode 100644 index 0000000..4244c2d --- /dev/null +++ b/user/priRR_fib.c @@ -0,0 +1,34 @@ + +#include + + +int fibonacci(int n); + +void +_main(void) +{ + int i1=0; + char buff1[256]; + i1 = 38; + + int res = fibonacci(i1) ; + + atomic_cprintf("Fibonacci #%d = %d\n",i1, res); + + if (res != 63245986) + panic("[envID %d] wrong result!", myEnv->env_id); + + //To indicate that it's completed successfully + inctst(); + + return; +} + + +int fibonacci(int n) +{ + if (n <= 1) + return 1 ; + return fibonacci(n-1) + fibonacci(n-2) ; +} + diff --git a/user/priRR_fib_create.c b/user/priRR_fib_create.c new file mode 100644 index 0000000..3cce1bd --- /dev/null +++ b/user/priRR_fib_create.c @@ -0,0 +1,30 @@ + +#include + +//extern void sys_env_set_priority(int , int ); + +void +_main(void) +{ + int32 envIdFib1 = sys_create_env("priRR_fib", (myEnv->page_WS_max_size),(myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + if (envIdFib1 == E_ENV_CREATION_ERROR) + panic("Loading programs failed\n"); + + int32 envIdFib2 = sys_create_env("priRR_fib", (myEnv->page_WS_max_size),(myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + if (envIdFib2 == E_ENV_CREATION_ERROR) + panic("Loading programs failed\n"); + + sys_run_env(envIdFib1); + sys_run_env(envIdFib2); + + int priority = 2; + cprintf("process %d will be added to ready queue at priority %d\n", envIdFib1, priority); + //sys_env_set_priority(envIdFib1, priority); + + priority = 9; + cprintf("process %d will be added to ready queue at priority %d\n", envIdFib2, priority); + //sys_env_set_priority(envIdFib2, priority); +return; +} + + diff --git a/user/priRR_fib_pri4.c b/user/priRR_fib_pri4.c new file mode 100644 index 0000000..2e99bd3 --- /dev/null +++ b/user/priRR_fib_pri4.c @@ -0,0 +1,37 @@ + +#include + + +int fibonacci(int n); +//extern void sys_env_set_priority(int , int ); + +void +_main(void) +{ + //sys_env_set_priority(myEnv->env_id, 4); + + int i1=0; + char buff1[256]; + i1 = 38; + + int res = fibonacci(i1) ; + + atomic_cprintf("Fibonacci #%d = %d\n",i1, res); + + if (res != 63245986) + panic("[envID %d] wrong result!", myEnv->env_id); + + //To indicate that it's completed successfully + inctst(); + + return; +} + + +int fibonacci(int n) +{ + if (n <= 1) + return 1 ; + return fibonacci(n-1) + fibonacci(n-2) ; +} + diff --git a/user/priRR_fib_pri8.c b/user/priRR_fib_pri8.c new file mode 100644 index 0000000..ad98d70 --- /dev/null +++ b/user/priRR_fib_pri8.c @@ -0,0 +1,37 @@ + +#include + + +int fibonacci(int n); +//extern void sys_env_set_priority(int , int ); + +void +_main(void) +{ + //sys_env_set_priority(myEnv->env_id, 8); + + int i1=0; + char buff1[256]; + i1 = 38; + + int res = fibonacci(i1) ; + + atomic_cprintf("Fibonacci #%d = %d\n",i1, res); + + if (res != 63245986) + panic("[envID %d] wrong result!", myEnv->env_id); + + //To indicate that it's completed successfully + inctst(); + + return; +} + + +int fibonacci(int n) +{ + if (n <= 1) + return 1 ; + return fibonacci(n-1) + fibonacci(n-2) ; +} + diff --git a/user/priRR_fib_small.c b/user/priRR_fib_small.c new file mode 100644 index 0000000..22d593e --- /dev/null +++ b/user/priRR_fib_small.c @@ -0,0 +1,34 @@ + +#include + + +int fibonacci(int n); + +void +_main(void) +{ + int i1=0; + char buff1[256]; + i1 = 8; + + int res = fibonacci(i1) ; + + atomic_cprintf("Fibonacci #%d = %d\n",i1, res); + + if (res != 34) + panic("[envID %d] wrong result!", myEnv->env_id); + + //To indicate that it's completed successfully + inctst(); + + return; +} + + +int fibonacci(int n) +{ + if (n <= 1) + return 1 ; + return fibonacci(n-1) + fibonacci(n-2) ; +} + diff --git a/user/sc_MultipleApps.c b/user/sc_MultipleApps.c new file mode 100644 index 0000000..eeaeed8 --- /dev/null +++ b/user/sc_MultipleApps.c @@ -0,0 +1,101 @@ +#include + +inline unsigned int nearest_pow2_ceil(unsigned int x) +{ + if (x <= 1) return 1; + int power = 2; + x--; + while (x >>= 1) { + power <<= 1; + } + return power; +} + +void _main(void) +{ + int WS_Size = 10000 ; + int ID_MatOps, ID_Fact; + int* ID_Fibs = malloc(3*sizeof(int)); + + //setPageReplacmentAlgorithmNchanceCLOCK(1); + sys_utilities("__ReplStrat__", -0x6); + rsttst(); + + //Matrix Operations: 9 trials in same program + { + ID_MatOps = sys_create_env("sc_matops", WS_Size, 0, 0); + if (ID_MatOps == E_ENV_CREATION_ERROR) + panic("RUNNING OUT OF ENV!! terminating..."); + } + + //Factorial: 1 program + { + ID_Fact = sys_create_env("sc_fact_recursive", WS_Size, 0, 0); + if (ID_Fact == E_ENV_CREATION_ERROR) + panic("RUNNING OUT OF ENV!! terminating..."); + } + + //Fibonacci: 3 programs (recursive, loop & memomization) + { + ID_Fibs[0] = sys_create_env("sc_fib_recursive", WS_Size, 0, 0); + ID_Fibs[1] = sys_create_env("sc_fib_loop", WS_Size, 0, 0); + ID_Fibs[2] = sys_create_env("sc_fib_memomize", WS_Size, 0, 0); + + for (int i = 0; i < 3; ++i) + { + if (ID_Fibs[i] == E_ENV_CREATION_ERROR) + panic("RUNNING OUT OF ENV!! terminating..."); + } + } + + //RUN ALL + { + sys_run_env(ID_MatOps); + sys_run_env(ID_Fact); + for (int i = 0; i < 3; ++i) + { + sys_run_env(ID_Fibs[i]); + } + } + + while (gettst() != 5); + + //VALIDATE Results + { + volatile struct Env* env_MatOps = NULL ; + //envid2env(ID_FIFO, &env_LEAK, 0); + env_MatOps = &envs[ENVX(ID_MatOps)]; + assert(env_MatOps->env_id == ID_MatOps) ; + + volatile struct Env* env_Fact = NULL ; + //envid2env(ID_LRU, &env_LRU, 0); + env_Fact = &envs[ENVX(ID_Fact)]; + assert(env_Fact->env_id == ID_Fact) ; + + volatile struct Env** env_Fibs = malloc(3*sizeof(struct Env*)); + for (int i = 0; i < 3; ++i) + { + env_Fibs[i] = &envs[ENVX(ID_Fibs[i])]; + assert(env_Fibs[i]->env_id == ID_Fibs[i]) ; + } + free(ID_Fibs) ; + + bool FactCheck = (env_Fact->nPageIn == 0) && (env_Fact->nPageOut == 0) ? 1 : 0; + bool MatOpsCheck = (env_MatOps->nPageIn == 0) && (env_MatOps->nPageOut == 0) ? 1 : 0; + bool FibCheck = (env_Fibs[0]->pageFaultsCounter < env_Fibs[1]->pageFaultsCounter) && (env_Fibs[1]->pageFaultsCounter < env_Fibs[2]->pageFaultsCounter)? 1 : 0; + FibCheck = FibCheck && (env_Fibs[0]->nPageIn == 0) && (env_Fibs[1]->nPageIn == 0) && (env_Fibs[2]->nPageIn == 0); + FibCheck = FibCheck && (env_Fibs[0]->nPageOut== 0) && (env_Fibs[1]->nPageOut == 0) && (env_Fibs[2]->nPageOut == 0); + if (FactCheck && MatOpsCheck && FibCheck) + { + free(env_Fibs) ; + //cprintf("Congratulations... MULTIPLE APPS scenario finished\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); + } + else + { + free(env_Fibs) ; + panic("Unexpected result\n"); + } + } + +} diff --git a/user/sc_NthClk_Norm_vs_Mod.c b/user/sc_NthClk_Norm_vs_Mod.c new file mode 100644 index 0000000..7c6dd3c --- /dev/null +++ b/user/sc_NthClk_Norm_vs_Mod.c @@ -0,0 +1,90 @@ +#include + +inline unsigned int nearest_pow2_ceil(unsigned int x) +{ + if (x <= 1) return 1; + int power = 2; + x--; + while (x >>= 1) { + power <<= 1; + } + return power; +} + +void _main(void) +{ + int NthClk_WS_Size = 20 ; + int ID_NORMAL_1, ID_NORMAL_10, ID_MODIFIED_10; + + //Nth Clock NORMAL (N = 1) + char setNthClkCmd1[100] = "__NthClkRepl@1"; + sys_utilities(setNthClkCmd1, 1); + { + rsttst(); + ID_NORMAL_1 = sys_create_env("sc_qs_leak", NthClk_WS_Size, 0, 0); + if (ID_NORMAL_1 == E_ENV_CREATION_ERROR) + panic("RUNNING OUT OF ENV!! terminating..."); + sys_run_env(ID_NORMAL_1); + + //Wait until the first program end + while (gettst() != 1) ; + } + + //Nth Clock NORMAL (N = 10) + char setNthClkCmd2[100] = "__NthClkRepl@1"; + sys_utilities(setNthClkCmd2, 10); + { + rsttst(); + ID_NORMAL_10 = sys_create_env("sc_qs_leak", NthClk_WS_Size, 0, 0); + if (ID_NORMAL_10 == E_ENV_CREATION_ERROR) + panic("RUNNING OUT OF ENV!! terminating..."); + sys_run_env(ID_NORMAL_10); + + //Wait until the first program end + while (gettst() != 1) ; + } + + //Nth Clock MODIFIED (N = 10) + char setNthClkCmd3[100] = "__NthClkRepl@2"; + sys_utilities(setNthClkCmd3, 10); + { + rsttst(); + ID_MODIFIED_10 = sys_create_env("sc_qs_leak", NthClk_WS_Size, 0, 0); + if (ID_MODIFIED_10 == E_ENV_CREATION_ERROR) + panic("RUNNING OUT OF ENV!! terminating..."); + sys_run_env(ID_MODIFIED_10); + + //Wait until the first program end + while (gettst() != 1) ; + } + //VALIDATE Results + { + volatile struct Env* env_NORMAL_1 = NULL ; + //envid2env(ID_FIFO, &env_FIFO, 0); + env_NORMAL_1 = &envs[ENVX(ID_NORMAL_1)]; + assert(env_NORMAL_1->env_id == ID_NORMAL_1) ; + + volatile struct Env* env_NORMAL_10 = NULL ; + //envid2env(ID_LRU, &env_LRU, 0); + env_NORMAL_10 = &envs[ENVX(ID_NORMAL_10)]; + assert(env_NORMAL_10->env_id == ID_NORMAL_10) ; + + volatile struct Env* env_MODIFIED_10 = NULL ; + //envid2env(ID_LRU, &env_LRU, 0); + env_MODIFIED_10 = &envs[ENVX(ID_MODIFIED_10)]; + assert(env_MODIFIED_10->env_id == ID_MODIFIED_10) ; + + if ((env_NORMAL_1->nPageIn > env_NORMAL_10->nPageIn) && (env_NORMAL_1->nPageOut > env_NORMAL_10->nPageOut) && + (env_NORMAL_10->nPageIn > env_MODIFIED_10->nPageIn) && (env_NORMAL_10->nPageOut > env_MODIFIED_10->nPageOut) && + (env_NORMAL_1->nNewPageAdded == env_NORMAL_10->nNewPageAdded) && (env_NORMAL_10->nNewPageAdded == env_MODIFIED_10->nNewPageAdded)) + { + //cprintf("%~\n\nCongratulations... Nth Clock: Normal vs Modified scenario finished\n\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); + } + else + { + panic("%~Unexpected result: the number of PageIn/PageOut of Normal Version is expected to be greater than the Modified Version ones\nNumber of Newly Added Pages are expected to be equal\n"); + } + } + +} diff --git a/user/sc_air.c b/user/sc_air.c new file mode 100644 index 0000000..654195b --- /dev/null +++ b/user/sc_air.c @@ -0,0 +1,353 @@ +// Air reservation problem +// Master program +#include +#include +int find(int* arr, int size, int val); + +void +_main(void) +{ + int envID = sys_getenvid(); + + int numOfClerks = 3; + int agentCapacity = 20; + int numOfCustomers = 50; + int flight1NumOfCustomers = numOfCustomers/3; + int flight2NumOfCustomers = numOfCustomers/3; + int flight3NumOfCustomers = numOfCustomers - (flight1NumOfCustomers + flight2NumOfCustomers); + + int flight1NumOfTickets = 15; + int flight2NumOfTickets = 15; + + // ************************************************************************************************* + /// Reading Inputs ********************************************************************************* + // ************************************************************************************************* + char Line[255] ; + char Chose; + sys_lock_cons(); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!!! AIR PLANE RESERVATION !!!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + cprintf("%~Default #customers = %d (equally divided over the 3 flights).\n" + "Flight1 Tickets = %d, Flight2 Tickets = %d\n" + "Agent Capacity = %d\n", numOfCustomers, flight1NumOfTickets, flight2NumOfTickets, agentCapacity) ; + Chose = 0 ; + while (Chose != 'y' && Chose != 'n' && Chose != 'Y' && Chose != 'N') + { + cprintf("%~Do you want to change these values(y/n)? ") ; + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + if (Chose == 'y' || Chose == 'Y') + { + readline("Enter the capacity of the agent: ", Line); + agentCapacity = strtol(Line, NULL, 10) ; + readline("Enter the total number of customers: ", Line); + numOfCustomers = strtol(Line, NULL, 10) ; + flight1NumOfCustomers = flight2NumOfCustomers = numOfCustomers / 3; + flight3NumOfCustomers = numOfCustomers - (flight1NumOfCustomers + flight2NumOfCustomers); + readline("Enter # tickets of flight#1: ", Line); + flight1NumOfTickets = strtol(Line, NULL, 10) ; + readline("Enter # tickets of flight#2: ", Line); + flight2NumOfTickets = strtol(Line, NULL, 10) ; + } + } + sys_unlock_cons(); + + // ************************************************************************************************* + /// Shared Variables Region ************************************************************************ + // ************************************************************************************************* + char _isOpened[] = "isOpened"; + char _agentCapacity[] = "agentCapacity"; + char _customers[] = "customers"; + char _custCounter[] = "custCounter"; + char _flight1Customers[] = "flight1Customers"; + char _flight2Customers[] = "flight2Customers"; + char _flight3Customers[] = "flight3Customers"; + char _flight1Counter[] = "flight1Counter"; + char _flight2Counter[] = "flight2Counter"; + char _flightBooked1Counter[] = "flightBooked1Counter"; + char _flightBooked2Counter[] = "flightBooked2Counter"; + char _flightBooked1Arr[] = "flightBooked1Arr"; + char _flightBooked2Arr[] = "flightBooked2Arr"; + char _cust_ready_queue[] = "cust_ready_queue"; + char _queue_in[] = "queue_in"; + char _queue_out[] = "queue_out"; + + char _cust_ready[] = "cust_ready"; + char _custQueueCS[] = "custQueueCS"; + char _flight1CS[] = "flight1CS"; + char _flight2CS[] = "flight2CS"; + + char _clerk[] = "clerk"; + char _custCounterCS[] = "custCounterCS"; + char _custTerminated[] = "custTerminated"; + char _clerkTerminated[] = "clerkTerminated"; + + char _taircl[] = "taircl"; + char _taircu[] = "taircu"; + + struct Customer * custs; + custs = smalloc(_customers, sizeof(struct Customer)*(numOfCustomers+1), 1); + //sys_createSharedObject("customers", sizeof(struct Customer)*numOfCustomers, 1, (void**)&custs); + + int* flight1Customers = smalloc(_flight1Customers, sizeof(int), 1); *flight1Customers = flight1NumOfCustomers; + int* flight2Customers = smalloc(_flight2Customers, sizeof(int), 1); *flight2Customers = flight2NumOfCustomers; + int* flight3Customers = smalloc(_flight3Customers, sizeof(int), 1); *flight3Customers = flight3NumOfCustomers; + + int* isOpened = smalloc(_isOpened, sizeof(int), 0); + *isOpened = 1; + + int* custCounter = smalloc(_custCounter, sizeof(int), 1); + *custCounter = 0; + + int* flight1Counter = smalloc(_flight1Counter, sizeof(int), 1); + *flight1Counter = flight1NumOfTickets; + + int* flight2Counter = smalloc(_flight2Counter, sizeof(int), 1); + *flight2Counter = flight2NumOfTickets; + + int* flight1BookedCounter = smalloc(_flightBooked1Counter, sizeof(int), 1); + *flight1BookedCounter = 0; + + int* flight2BookedCounter = smalloc(_flightBooked2Counter, sizeof(int), 1); + *flight2BookedCounter = 0; + + int* flight1BookedArr = smalloc(_flightBooked1Arr, sizeof(int)*flight1NumOfTickets, 1); + int* flight2BookedArr = smalloc(_flightBooked2Arr, sizeof(int)*flight2NumOfTickets, 1); + + int* cust_ready_queue = smalloc(_cust_ready_queue, sizeof(int)*(numOfCustomers+1), 1); + + int* queue_in = smalloc(_queue_in, sizeof(int), 1); + *queue_in = 0; + + int* queue_out = smalloc(_queue_out, sizeof(int), 1); + *queue_out = 0; + + // ************************************************************************************************* + /// Semaphores Region ****************************************************************************** + // ************************************************************************************************* + struct semaphore capacity = create_semaphore(_agentCapacity, agentCapacity); + + struct semaphore flight1CS = create_semaphore(_flight1CS, 1); + struct semaphore flight2CS = create_semaphore(_flight2CS, 1); + + struct semaphore custCounterCS = create_semaphore(_custCounterCS, 1); + struct semaphore custQueueCS = create_semaphore(_custQueueCS, 1); + + struct semaphore clerk = create_semaphore(_clerk, 3); + + struct semaphore cust_ready = create_semaphore(_cust_ready, 0); + + struct semaphore custTerminated = create_semaphore(_custTerminated, 0); + struct semaphore clerkTerminated = create_semaphore(_clerkTerminated, 0); + + struct semaphore* cust_finished = smalloc("cust_finished_array", numOfCustomers*sizeof(struct semaphore), 1); + + int s=0; + for(s=0; spage_WS_max_size),(myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + if (clerkEnvIds[k] == E_ENV_CREATION_ERROR) + panic("NO AVAILABLE ENVs... Please reduce the num of customers and try again"); + + char id[20] ; + ltostr(clerkEnvIds[k], id); + char setPriorityWithIDCmd[100] ; + strcconcat(setPriorityCmd, id, setPriorityWithIDCmd); + sys_utilities(setPriorityWithIDCmd, k * 10); + } + + //customers + for(c=0; c< numOfCustomers;++c) + { + custEnvIds[c] = sys_create_env(_taircu, (myEnv->page_WS_max_size),(myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + if (custEnvIds[c] == E_ENV_CREATION_ERROR) + panic("NO AVAILABLE ENVs... Please reduce the num of customers and try again"); + + char id[20] ; + ltostr(custEnvIds[c], id); + char setPriorityWithIDCmd[100] ; + strcconcat(setPriorityCmd, id, setPriorityWithIDCmd); + sys_utilities(setPriorityWithIDCmd, RANDU(0, 30)); + } + } + sys_unlock_cons(); + + //Run Clerks + for (k = 0; k < numOfClerks; ++k) + { + sys_run_env(clerkEnvIds[k]); + } + //Run Customers + for(c=0; c < numOfCustomers;++c) + { + sys_run_env(custEnvIds[c]); + } + + //wait until all customers terminated + for(c=0; c< numOfCustomers;++c) + { + wait_semaphore(custTerminated); + } + + env_sleep(1500); + int b; + + sys_lock_cons(); + { + //print out the results + for(b=0; b< (*flight1BookedCounter);++b) + { + cprintf("cust %d booked flight 1, originally ordered %d\n", flight1BookedArr[b], custs[flight1BookedArr[b]].flightType); + } + + for(b=0; b< (*flight2BookedCounter);++b) + { + cprintf("cust %d booked flight 2, originally ordered %d\n", flight2BookedArr[b], custs[flight2BookedArr[b]].flightType); + } + } + sys_unlock_cons(); + + int numOfBookings = 0; + int numOfFCusts[3] = {0}; + + for(b=0; b< numOfCustomers;++b) + { + if (custs[b].booked) + { + numOfBookings++; + numOfFCusts[custs[b].flightType - 1]++ ; + } + } + + sys_lock_cons(); + { + cprintf("%~[*] FINAL RESULTS:\n"); + cprintf("%~\tTotal number of customers = %d (Flight1# = %d, Flight2# = %d, Flight3# = %d)\n", numOfCustomers, flight1NumOfCustomers,flight2NumOfCustomers,flight3NumOfCustomers); + cprintf("%~\tTotal number of customers who receive tickets = %d (Flight1# = %d, Flight2# = %d, Flight3# = %d)\n", numOfBookings, numOfFCusts[0],numOfFCusts[1],numOfFCusts[2]); + } + sys_unlock_cons(); + + //check out the final results and semaphores + { + for(int c = 0; c < numOfCustomers; ++c) + { + if (custs[c].booked) + { + if(custs[c].flightType ==1 && find(flight1BookedArr, flight1NumOfTickets, c) != 1) + { + panic("Error, wrong booking for user %d\n", c); + } + if(custs[c].flightType ==2 && find(flight2BookedArr, flight2NumOfTickets, c) != 1) + { + panic("Error, wrong booking for user %d\n", c); + } + if(custs[c].flightType ==3 && ((find(flight1BookedArr, flight1NumOfTickets, c) + find(flight2BookedArr, flight2NumOfTickets, c)) != 2)) + { + panic("Error, wrong booking for user %d\n", c); + } + } + } + + assert(semaphore_count(capacity) == agentCapacity); + + assert(semaphore_count(flight1CS) == 1); + assert(semaphore_count(flight2CS) == 1); + + assert(semaphore_count(custCounterCS) == 1); + assert(semaphore_count(custQueueCS) == 1); + + assert(semaphore_count(clerk) == 3); + + assert(semaphore_count(cust_ready) == -3); + + assert(semaphore_count(custTerminated) == 0); + + int s=0; + for(s=0; s + +inline unsigned int nearest_pow2_ceil(unsigned int x) +{ + if (x <= 1) return 1; + int power = 2; + x--; + while (x >>= 1) { + power <<= 1; + } + return power; +} + +void _main(void) +{ +#define NUM_OF_INSTANCES 3 + int WS_Size = 10000 ; + int ID_ArrOps[NUM_OF_INSTANCES]; + + //setPageReplacmentAlgorithmNchanceCLOCK(1); + sys_utilities("__ReplStrat__", -0x6); + + //CREATE SEMAPHORES + struct semaphore arropsFinished = create_semaphore("arropsFinished", 0); + struct semaphore cons_mutex = create_semaphore("Console Mutex", 1); + + //ArrayOperations: 3 programs + { + for (int i = 0; i < NUM_OF_INSTANCES; ++i) + { + ID_ArrOps[i] = sys_create_env("sc_arrops_slave", WS_Size, 0, 0); + if (ID_ArrOps[i] == E_ENV_CREATION_ERROR) + panic("RUNNING OUT OF ENV!! terminating..."); + } + } + + //RUN ALL + { + for (int i = 0; i < NUM_OF_INSTANCES; ++i) + { + sys_run_env(ID_ArrOps[i]); + } + } + + //WAIT UNTIL ALL FINISHED + for (int i = 0; i < NUM_OF_INSTANCES; ++i) + { + wait_semaphore(arropsFinished); + } + + //CHECK SEMAPHORE VALUES + assert(semaphore_count(arropsFinished) == 0); + assert(semaphore_count(cons_mutex) == 1); + + //VALIDATE Results + { + volatile struct Env* env_ArrOps[NUM_OF_INSTANCES]; + for (int i = 0; i < NUM_OF_INSTANCES; ++i) + { + env_ArrOps[i] = &envs[ENVX(ID_ArrOps[i])]; + assert(env_ArrOps[i]->env_id == ID_ArrOps[i]) ; + } + + bool arrOpsCheck = 1; + arrOpsCheck = arrOpsCheck && (env_ArrOps[0]->nPageIn == 0) && (env_ArrOps[1]->nPageIn == 0) && (env_ArrOps[2]->nPageIn == 0); + arrOpsCheck = arrOpsCheck && (env_ArrOps[0]->nPageOut== 0) && (env_ArrOps[1]->nPageOut == 0) && (env_ArrOps[2]->nPageOut == 0); + if (arrOpsCheck) + { + //cprintf("Congratulations... ARRAY OPERATIONS scenario finished\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); + } + else + { + panic("Unexpected result\n"); + } + } + +} diff --git a/user/sc_arrayOperations_slave.c b/user/sc_arrayOperations_slave.c new file mode 100644 index 0000000..e98edcc --- /dev/null +++ b/user/sc_arrayOperations_slave.c @@ -0,0 +1,226 @@ +// Scenario that tests the usage of shared variables +#include + +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeDescending(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +uint32 CheckSorted(int *Elements, int NumOfElements); +void ArrayStats(int *Elements, int NumOfElements, int64 *mean, int64 *var); + +void +_main(void) +{ + /*[0] GET SEMAPHORES FROM MASTER*/ + int32 parentenvID = sys_getparentenvid(); + struct semaphore arropsFinished = get_semaphore(parentenvID, "arropsFinished"); + struct semaphore cons_mutex = get_semaphore(parentenvID, "Console Mutex"); + + /*[1] CREATE SEMAPHORES*/ + struct semaphore ready = create_semaphore("Ready", 0); + struct semaphore finished = create_semaphore("Finished", 0); + + /*[2] RUN THE SLAVES PROGRAMS*/ + int numOfSlaveProgs = 3 ; + + int32 envIdQuickSort, envIdMergeSort , envIdStats ; + + //CRITICAL SECTION TO AVOID CONCURRENCY ISSUE BET MULTIPLE INTANCES OF THIS PROC IN env_create().allocate_environment() + sys_lock_cons(); + { + envIdQuickSort = sys_create_env("slave_qs", (myEnv->page_WS_max_size),(myEnv->SecondListSize) ,(myEnv->percentage_of_WS_pages_to_be_removed)); + envIdMergeSort = sys_create_env("slave_ms_static", (myEnv->page_WS_max_size),(myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + envIdStats = sys_create_env("slave_stats", (myEnv->page_WS_max_size), (myEnv->SecondListSize),(myEnv->percentage_of_WS_pages_to_be_removed)); + } + sys_unlock_cons(); + + if (envIdQuickSort == E_ENV_CREATION_ERROR || envIdMergeSort == E_ENV_CREATION_ERROR || envIdStats == E_ENV_CREATION_ERROR) + panic("NO AVAILABLE ENVs..."); + + sys_run_env(envIdQuickSort); + sys_run_env(envIdMergeSort); + sys_run_env(envIdStats); + + /*[3] CREATE SHARED VARIABLES*/ + //Share the cons_mutex owner ID + int *mutexOwnerID = smalloc("cons_mutex ownerID", sizeof(int) , 0) ; + *mutexOwnerID = parentenvID ; + + int ret; + char Chose; + char Line[30]; + int NumOfElements = RANDU(20000, 50000) ; + int *Elements = NULL; + //lock the console + wait_semaphore(cons_mutex); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!! ARRAY OOERATIONS !!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + + cprintf("Enter the number of elements: %d\n", NumOfElements); + + cprintf("Chose the initialization method:\n") ; + cprintf("a) Ascending\n") ; + cprintf("b) Descending\n") ; + cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + Chose = RANDU('a', 'd'); + cputchar(Chose); + cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + } + signal_semaphore(cons_mutex); + //unlock the console + + //Create the shared array & its size + int *arrSize = smalloc("arrSize", sizeof(int) , 0) ; + *arrSize = NumOfElements ; + Elements = smalloc("arr", sizeof(int) * NumOfElements , 0) ; + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeDescending(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + /*[4] SIGNAL READY TO THE SLAVES*/ + for (int i = 0; i < numOfSlaveProgs; ++i) { + signal_semaphore(ready); + } + + /*[5] WAIT TILL ALL SLAVES FINISHED*/ + for (int i = 0; i < numOfSlaveProgs; ++i) { + wait_semaphore(finished); + } + + /*[6] GET THEIR RESULTS*/ + int *quicksortedArr = NULL; + int *mergesortedArr = NULL; + int64 *mean = NULL; + int64 *var = NULL; + int *min = NULL; + int *max = NULL; + int *med = NULL; + quicksortedArr = sget(envIdQuickSort, "quicksortedArr") ; + mergesortedArr = sget(envIdMergeSort, "mergesortedArr") ; + mean = (int64*)sget(envIdStats, "mean") ; + var = (int64*) sget(envIdStats,"var") ; + min = sget(envIdStats,"min") ; + max = sget(envIdStats,"max") ; + med = sget(envIdStats,"med") ; + + /*[7] VALIDATE THE RESULTS*/ + uint32 sorted = CheckSorted(quicksortedArr, NumOfElements); + if(sorted == 0) panic("The array is NOT quick-sorted correctly") ; + sorted = CheckSorted(mergesortedArr, NumOfElements); + if(sorted == 0) panic("The array is NOT merge-sorted correctly") ; + int64 correctMean, correctVar ; + ArrayStats(Elements, NumOfElements, &correctMean , &correctVar); + int correctMin = quicksortedArr[0]; + int last = NumOfElements-1; + int middle = (NumOfElements+1)/2 - 1; /*-1 to make it ZERO-Based*/ +// if (NumOfElements % 2 != 0) +// middle--; + int correctMax = quicksortedArr[last]; + int correctMed = quicksortedArr[middle]; + wait_semaphore(cons_mutex); + { + //cprintf("Array is correctly sorted\n"); + cprintf("mean = %lld, var = %lld, min = %d, max = %d, med = %d\n", *mean, *var, *min, *max, *med); + cprintf("mean = %lld, var = %lld, min = %d, max = %d, med = %d\n", correctMean, correctVar, correctMin, correctMax, correctMed); + } + signal_semaphore(cons_mutex); + if(*mean != correctMean || *var != correctVar|| *min != correctMin || *max != correctMax || *med != correctMed) + panic("The array STATS are NOT calculated correctly") ; + + //cprintf("Congratulations!! Scenario of Using the Semaphores & Shared Variables completed successfully!!\n\n\n"); + /*[8] CHECK SEMAPHORE VALUES*/ + assert(semaphore_count(ready) == 0); + assert(semaphore_count(finished) == 0); + + /*[9] REPORT a successful end to the master...*/ + signal_semaphore(arropsFinished); + return; +} + + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeDescending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + //cprintf("Elements[%d] = %d\n",i, Elements[i]); + } + +} + +void ArrayStats(int *Elements, int NumOfElements, int64 *mean, int64 *var) +{ + int i ; + *mean =0 ; + for (i = 0 ; i < NumOfElements ; i++) + { + *mean += Elements[i]; + } + *mean /= NumOfElements; + *var = 0; + for (i = 0 ; i < NumOfElements ; i++) + { + *var += (int64) ((Elements[i] - *mean)*(Elements[i] - *mean)); +// if (i%1000 == 0) +// cprintf("current #elements = %d, current var = %lld\n", i , *var); + } + *var /= NumOfElements; +} diff --git a/user/sc_fact_recursive.c b/user/sc_fact_recursive.c new file mode 100644 index 0000000..f9c9a01 --- /dev/null +++ b/user/sc_fact_recursive.c @@ -0,0 +1,30 @@ + +#include + + +int64 factorial(int n); + +void +_main(void) +{ + int n=0; + char buff1[256]; + + n = 20 ; + atomic_cprintf("Please enter a number: %d\n", n); + int64 res = factorial(n) ; + + atomic_cprintf("Factorial %d = %lld\n",n, res); + //To indicate that it's completed successfully + inctst(); + return; +} + + +int64 factorial(int n) +{ + if (n <= 1) + return 1 ; + return n * factorial(n-1) ; +} + diff --git a/user/sc_fib_loop.c b/user/sc_fib_loop.c new file mode 100644 index 0000000..4fc3aae --- /dev/null +++ b/user/sc_fib_loop.c @@ -0,0 +1,43 @@ + +#include + + +int64 fibonacci(int n, int64 *memo); + +void +_main(void) +{ + int index=0; + char buff1[256]; +// atomic_readline("Please enter Fibonacci index:", buff1); +// index = strtol(buff1, NULL, 10); + + index = 1000; + + int64 *memo = malloc((index+1) * sizeof(int64)); + + int64 res = fibonacci(index, memo) ; + + free(memo); + + atomic_cprintf("Fibonacci #%d = %lld\n",index, res); + //To indicate that it's completed successfully + inctst(); + return; +} + + +int64 fibonacci(int n, int64 *memo) +{ + for (int i = 0; i <= n; ++i) + { + if (i <= 1) + memo[i] = 1; + else + memo[i] = memo[i-1] + memo[i-2] ; + } + return memo[n]; +} + + + diff --git a/user/sc_fib_memomize.c b/user/sc_fib_memomize.c new file mode 100644 index 0000000..34fb1b7 --- /dev/null +++ b/user/sc_fib_memomize.c @@ -0,0 +1,42 @@ + +#include + + +int64 fibonacci(int n, int64 *memo); + +void +_main(void) +{ + int index=0; + char buff1[256]; +// atomic_readline("Please enter Fibonacci index:", buff1); +// index = strtol(buff1, NULL, 10); + + index = 1000; + + int64 *memo = malloc((index+1) * sizeof(int64)); + for (int i = 0; i <= index; ++i) + { + memo[i] = 0; + } + int64 res = fibonacci(index, memo) ; + + free(memo); + + atomic_cprintf("Fibonacci #%d = %lld\n",index, res); + //To indicate that it's completed successfully + inctst(); + return; +} + + +int64 fibonacci(int n, int64 *memo) +{ + if (memo[n]!=0) return memo[n]; + if (n <= 1) + return memo[n] = 1 ; + return (memo[n] = fibonacci(n-1, memo) + fibonacci(n-2, memo)) ; +} + + + diff --git a/user/sc_fib_recursive.c b/user/sc_fib_recursive.c new file mode 100644 index 0000000..8cded9e --- /dev/null +++ b/user/sc_fib_recursive.c @@ -0,0 +1,32 @@ + +#include + + +int64 fibonacci(int n); + +void +_main(void) +{ + int index=0; + char buff1[256]; +// atomic_readline("Please enter Fibonacci index:", buff1); +// i1 = strtol(buff1, NULL, 10); + + index = 30; + + int64 res = fibonacci(index) ; + + atomic_cprintf("Fibonacci #%d = %lld\n",index, res); + //To indicate that it's completed successfully + inctst(); + return; +} + + +int64 fibonacci(int n) +{ + if (n <= 1) + return 1 ; + return fibonacci(n-1) + fibonacci(n-2) ; +} + diff --git a/user/sc_fos_add.c b/user/sc_fos_add.c new file mode 100644 index 0000000..c92bf48 --- /dev/null +++ b/user/sc_fos_add.c @@ -0,0 +1,19 @@ +// hello, world +#include + +void +_main(void) +{ + + int i1=0; + int i2=0; + + i1 = strtol("1", NULL, 10); + i2 = strtol("2", NULL, 10); + + atomic_cprintf("number 1 + number 2 = %d\n",i1+i2); + //cprintf("number 1 + number 2 = \n"); + + inctst(); + return; +} diff --git a/user/sc_helloWorld.c b/user/sc_helloWorld.c new file mode 100644 index 0000000..1c4af7f --- /dev/null +++ b/user/sc_helloWorld.c @@ -0,0 +1,13 @@ +// hello, world +#include + +void +_main(void) +{ + extern unsigned char * etext; + //cprintf("HELLO WORLD , FOS IS SAYING HI :D:D:D %d\n",4); + atomic_cprintf("HELLO WORLD , FOS IS SAYING HI :D:D:D \n"); + atomic_cprintf("end of code = %x\n",etext); + + inctst(); +} diff --git a/user/sc_matrix_operations.c b/user/sc_matrix_operations.c new file mode 100644 index 0000000..7e23152 --- /dev/null +++ b/user/sc_matrix_operations.c @@ -0,0 +1,295 @@ +#include + +//Functions Declarations +void InitializeAscending(int **Elements, int NumOfElements); +void InitializeIdentical(int **Elements, int NumOfElements, int value); +void InitializeSemiRandom(int **Elements, int NumOfElements); +void PrintElements(int **Elements, int NumOfElements); +void PrintElements64(int64 **Elements, int NumOfElements); + +int64** MatrixMultiply(int **M1, int **M2, int NumOfElements); +int64** MatrixAddition(int **M1, int **M2, int NumOfElements); +int64** MatrixSubtraction(int **M1, int **M2, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + int val =0 ; + int NumOfElements = 3; + int NumOfRep = 0; + do + { + val = 0; + //2012: lock the interrupt + sys_lock_cons(); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!! MATRIX MULTIPLICATION !!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + + //readline("Enter the number of elements: ", Line); + //NumOfElements = strtol(Line, NULL, 10) ; + NumOfElements = 250 ; //Add & Sub + if (NumOfRep % 3 == 2) NumOfElements = 200 ; //Mul + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + + // cprintf("Chose the initialization method:\n") ; + // cprintf("a) Ascending\n") ; + // cprintf("b) Identical\n") ; + // cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + if (NumOfRep / 3 == 0) { Chose = 'a'; cprintf("a) Ascending\n");} + else if (NumOfRep/3 == 1) { Chose = 'b'; cprintf("b) Identical\n");} + else if (NumOfRep/3 == 2) { Chose = 'c'; cprintf("c) Semi random\n");} + // cputchar(Chose); + // cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + if (Chose == 'b') + { + // readline("Enter the value to be initialized: ", Line); + // val = strtol(Line, NULL, 10) ; + val = 1; + } + } + //2012: lock the interrupt + sys_unlock_cons(); + + int **M1 = malloc(sizeof(int) * NumOfElements) ; + int **M2 = malloc(sizeof(int) * NumOfElements) ; + + for (int i = 0; i < NumOfElements; ++i) + { + M1[i] = malloc(sizeof(int) * NumOfElements) ; + M2[i] = malloc(sizeof(int) * NumOfElements) ; + } + + //cprintf("matrices are created\n"); + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(M1, NumOfElements); + InitializeAscending(M2, NumOfElements); + break ; + case 'b': + InitializeIdentical(M1, NumOfElements, val); + InitializeIdentical(M2, NumOfElements, val); + break ; + case 'c': + InitializeSemiRandom(M1, NumOfElements); + InitializeSemiRandom(M2, NumOfElements); + //PrintElements(M1, NumOfElements); + break ; + default: + InitializeSemiRandom(M1, NumOfElements); + InitializeSemiRandom(M2, NumOfElements); + } + + sys_lock_cons(); + { + // cprintf("Chose the desired operation:\n") ; + // cprintf("a) Addition (+)\n") ; + // cprintf("b) Subtraction (-)\n") ; + // cprintf("c) Multiplication (x)\n"); + do + { + cprintf("Select: ") ; + if (NumOfRep % 3 == 0) { Chose = 'a'; cprintf("a) Add (+) \n");} + else if (NumOfRep%3 == 1) { Chose = 'b'; cprintf("b) Sub (-) \n");} + else if (NumOfRep%3 == 2) { Chose = 'c'; cprintf("c) Mul (x) \n");} + // cputchar(Chose); + // cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + } + sys_unlock_cons(); + + + int64** Res = NULL ; + switch (Chose) + { + case 'a': + Res = MatrixAddition(M1, M2, NumOfElements); + //PrintElements64(Res, NumOfElements); + break ; + case 'b': + Res = MatrixSubtraction(M1, M2, NumOfElements); + //PrintElements64(Res, NumOfElements); + break ; + case 'c': + Res = MatrixMultiply(M1, M2, NumOfElements); + //PrintElements64(Res, NumOfElements); + break ; + default: + Res = MatrixAddition(M1, M2, NumOfElements); + //PrintElements64(Res, NumOfElements); + } + + + sys_lock_cons(); + { + cprintf("Operation is COMPLETED.\n"); + } + sys_unlock_cons(); + + for (int i = 0; i < NumOfElements; ++i) + { + free(M1[i]); + free(M2[i]); + free(Res[i]); + } + free(M1) ; + free(M2) ; + free(Res) ; + + NumOfRep++ ; + + sys_lock_cons(); + { + cprintf("Do you want to repeat (y/n): ") ; + if (NumOfRep == 9) + Chose = 'n' ; + else + Chose = 'y' ; + cputchar(Chose); + cputchar('\n'); + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); +} + +///MATRIX MULTIPLICATION +int64** MatrixMultiply(int **M1, int **M2, int NumOfElements) +{ + int64 **Res = malloc(sizeof(int64) * NumOfElements) ; + for (int i = 0; i < NumOfElements; ++i) + { + Res[i] = malloc(sizeof(int64) * NumOfElements) ; + } + + for (int i = 0; i < NumOfElements; ++i) + { + for (int j = 0; j < NumOfElements; ++j) + { + Res[i][j] = 0 ; + for (int k = 0; k < NumOfElements; ++k) + { + Res[i][j] += M1[i][k] * M2[k][j] ; + } + } + } + return Res; +} + +///MATRIX ADDITION +int64** MatrixAddition(int **M1, int **M2, int NumOfElements) +{ + int64 **Res = malloc(sizeof(int64) * NumOfElements) ; + for (int i = 0; i < NumOfElements; ++i) + { + Res[i] = malloc(sizeof(int64) * NumOfElements) ; + } + + for (int i = 0; i < NumOfElements; ++i) + { + for (int j = 0; j < NumOfElements; ++j) + { + Res[i][j] = M1[i][j] + M2[i][j] ; + } + } + return Res; +} + +///MATRIX SUBTRACTION +int64** MatrixSubtraction(int **M1, int **M2, int NumOfElements) +{ + int64 **Res = malloc(sizeof(int64) * NumOfElements) ; + for (int i = 0; i < NumOfElements; ++i) + { + Res[i] = malloc(sizeof(int64) * NumOfElements) ; + } + + for (int i = 0; i < NumOfElements; ++i) + { + for (int j = 0; j < NumOfElements; ++j) + { + Res[i][j] = M1[i][j] - M2[i][j] ; + } + } + return Res; +} + +///Private Functions + +void InitializeAscending(int **Elements, int NumOfElements) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + (Elements)[i][j] = j ; + } + } +} + +void InitializeIdentical(int **Elements, int NumOfElements, int value) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + (Elements)[i][j] = value ; + } + } +} + +void InitializeSemiRandom(int **Elements, int NumOfElements) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + (Elements)[i][j] = RANDU(0, NumOfElements) ; + // cprintf("i=%d\n",i); + } + } +} + +void PrintElements(int **Elements, int NumOfElements) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + cprintf("%~%d, ",Elements[i][j]); + } + cprintf("%~\n"); + } +} + +void PrintElements64(int64 **Elements, int NumOfElements) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + cprintf("%~%lld, ",Elements[i][j]); + } + cprintf("%~\n"); + } +} diff --git a/user/sc_matrix_operations_small.c b/user/sc_matrix_operations_small.c new file mode 100644 index 0000000..1c22bae --- /dev/null +++ b/user/sc_matrix_operations_small.c @@ -0,0 +1,294 @@ +#include + +//Functions Declarations +void InitializeAscending(int **Elements, int NumOfElements); +void InitializeIdentical(int **Elements, int NumOfElements, int value); +void InitializeSemiRandom(int **Elements, int NumOfElements); +void PrintElements(int **Elements, int NumOfElements); +void PrintElements64(int64 **Elements, int NumOfElements); + +int64** MatrixMultiply(int **M1, int **M2, int NumOfElements); +int64** MatrixAddition(int **M1, int **M2, int NumOfElements); +int64** MatrixSubtraction(int **M1, int **M2, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + int val =0 ; + int NumOfElements = 3; + int NumOfRep = 0; + do + { + val = 0; + NumOfElements = 3; + //2012: lock the interrupt + sys_lock_cons(); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!! MATRIX MULTIPLICATION !!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + + //readline("Enter the number of elements: ", Line); + //NumOfElements = strtol(Line, NULL, 10) ; + int NumOfElements = 600 ; //Add & Sub + if (NumOfRep % 3 == 2) NumOfElements = 40 ; //Mul + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + + // cprintf("Chose the initialization method:\n") ; + // cprintf("a) Ascending\n") ; + // cprintf("b) Identical\n") ; + // cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + if (NumOfRep / 3 == 0) { Chose = 'a'; cprintf("a) Ascending\n");} + else if (NumOfRep/3 == 1) { Chose = 'b'; cprintf("b) Identical\n");} + else if (NumOfRep/3 == 2) { Chose = 'c'; cprintf("c) Semi random\n");} + // cputchar(Chose); + // cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + if (Chose == 'b') + { + // readline("Enter the value to be initialized: ", Line); + // val = strtol(Line, NULL, 10) ; + val = 1; + } + } + //2012: lock the interrupt + sys_unlock_cons(); + + int **M1 = malloc(sizeof(int) * NumOfElements) ; + int **M2 = malloc(sizeof(int) * NumOfElements) ; + + for (int i = 0; i < NumOfElements; ++i) + { + M1[i] = malloc(sizeof(int) * NumOfElements) ; + M2[i] = malloc(sizeof(int) * NumOfElements) ; + } + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(M1, NumOfElements); + InitializeAscending(M2, NumOfElements); + break ; + case 'b': + InitializeIdentical(M1, NumOfElements, val); + InitializeIdentical(M2, NumOfElements, val); + break ; + case 'c': + InitializeSemiRandom(M1, NumOfElements); + InitializeSemiRandom(M2, NumOfElements); + //PrintElements(M1, NumOfElements); + break ; + default: + InitializeSemiRandom(M1, NumOfElements); + InitializeSemiRandom(M2, NumOfElements); + } + + sys_lock_cons(); + { + // cprintf("Chose the desired operation:\n") ; + // cprintf("a) Addition (+)\n") ; + // cprintf("b) Subtraction (-)\n") ; + // cprintf("c) Multiplication (x)\n"); + do + { + cprintf("Select: ") ; + if (NumOfRep % 3 == 0) { Chose = 'a'; cprintf("a) Add (+) \n");} + else if (NumOfRep%3 == 1) { Chose = 'b'; cprintf("b) Sub (-) \n");} + else if (NumOfRep%3 == 2) { Chose = 'c'; cprintf("c) Mul (x) \n");} + // cputchar(Chose); + // cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + } + sys_unlock_cons(); + + + int64** Res = NULL ; + switch (Chose) + { + case 'a': + Res = MatrixAddition(M1, M2, NumOfElements); + //PrintElements64(Res, NumOfElements); + break ; + case 'b': + Res = MatrixSubtraction(M1, M2, NumOfElements); + //PrintElements64(Res, NumOfElements); + break ; + case 'c': + Res = MatrixMultiply(M1, M2, NumOfElements); + //PrintElements64(Res, NumOfElements); + break ; + default: + Res = MatrixAddition(M1, M2, NumOfElements); + //PrintElements64(Res, NumOfElements); + } + + + sys_lock_cons(); + { + cprintf("Operation is COMPLETED.\n"); + } + sys_unlock_cons(); + + for (int i = 0; i < NumOfElements; ++i) + { + free(M1[i]); + free(M2[i]); + free(Res[i]); + } + free(M1) ; + free(M2) ; + free(Res) ; + + NumOfRep++ ; + + sys_lock_cons(); + { + cprintf("Do you want to repeat (y/n): ") ; + if (NumOfRep == 3) + Chose = 'n' ; + else + Chose = 'y' ; + cputchar(Chose); + cputchar('\n'); + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); +} + +///MATRIX MULTIPLICATION +int64** MatrixMultiply(int **M1, int **M2, int NumOfElements) +{ + int64 **Res = malloc(sizeof(int64) * NumOfElements) ; + for (int i = 0; i < NumOfElements; ++i) + { + Res[i] = malloc(sizeof(int64) * NumOfElements) ; + } + + for (int i = 0; i < NumOfElements; ++i) + { + for (int j = 0; j < NumOfElements; ++j) + { + Res[i][j] = 0 ; + for (int k = 0; k < NumOfElements; ++k) + { + Res[i][j] += M1[i][k] * M2[k][j] ; + } + } + } + return Res; +} + +///MATRIX ADDITION +int64** MatrixAddition(int **M1, int **M2, int NumOfElements) +{ + int64 **Res = malloc(sizeof(int64) * NumOfElements) ; + for (int i = 0; i < NumOfElements; ++i) + { + Res[i] = malloc(sizeof(int64) * NumOfElements) ; + } + + for (int i = 0; i < NumOfElements; ++i) + { + for (int j = 0; j < NumOfElements; ++j) + { + Res[i][j] = M1[i][j] + M2[i][j] ; + } + } + return Res; +} + +///MATRIX SUBTRACTION +int64** MatrixSubtraction(int **M1, int **M2, int NumOfElements) +{ + int64 **Res = malloc(sizeof(int64) * NumOfElements) ; + for (int i = 0; i < NumOfElements; ++i) + { + Res[i] = malloc(sizeof(int64) * NumOfElements) ; + } + + for (int i = 0; i < NumOfElements; ++i) + { + for (int j = 0; j < NumOfElements; ++j) + { + Res[i][j] = M1[i][j] - M2[i][j] ; + } + } + return Res; +} + +///Private Functions + +void InitializeAscending(int **Elements, int NumOfElements) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + (Elements)[i][j] = j ; + } + } +} + +void InitializeIdentical(int **Elements, int NumOfElements, int value) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + (Elements)[i][j] = value ; + } + } +} + +void InitializeSemiRandom(int **Elements, int NumOfElements) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + (Elements)[i][j] = RANDU(0, NumOfElements) ; + // cprintf("i=%d\n",i); + } + } +} + +void PrintElements(int **Elements, int NumOfElements) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + cprintf("%~%d, ",Elements[i][j]); + } + cprintf("%~\n"); + } +} + +void PrintElements64(int64 **Elements, int NumOfElements) +{ + int i, j ; + for (i = 0 ; i < NumOfElements ; i++) + { + for (j = 0 ; j < NumOfElements ; j++) + { + cprintf("%~%lld, ",Elements[i][j]); + } + cprintf("%~\n"); + } +} diff --git a/user/sc_ms_leak.c b/user/sc_ms_leak.c new file mode 100644 index 0000000..c1801e5 --- /dev/null +++ b/user/sc_ms_leak.c @@ -0,0 +1,252 @@ +#include + +uint32 ws_size_first=0; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeIdentical(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +void PrintElements(int *Elements, int NumOfElements); + +void MSort(int* A, int p, int r); +void Merge(int* A, int p, int q, int r); + +uint32 CheckSorted(int *Elements, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + int numOfRep = 0; + do + { + numOfRep++ ; + //2012: lock the interrupt + sys_lock_cons(); + + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!!! MERGE SORT !!!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + int NumOfElements = 100000; + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + + cprintf("Chose the initialization method:\n") ; + cprintf("a) Ascending\n") ; + cprintf("b) Descending\n") ; + cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + Chose = 'c' ; + cputchar(Chose); + cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + //2012: lock the interrupt + sys_unlock_cons(); + + int *Elements = malloc(sizeof(int) * NumOfElements) ; + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeIdentical(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + MSort(Elements, 1, NumOfElements); + + sys_lock_cons(); + cprintf("Sorting is Finished!!!!it'll be checked now....\n") ; + //PrintElements(Elements, NumOfElements); + sys_unlock_cons(); + + uint32 Sorted = CheckSorted(Elements, NumOfElements); + + if(Sorted == 0) panic("The array is NOT sorted correctly") ; + else + { + sys_lock_cons(); + cprintf("===============================================\n") ; + cprintf("Congratulations!! The array is sorted correctly\n") ; + cprintf("===============================================\n\n") ; + sys_unlock_cons(); + } + + //free(Elements) ; + + sys_lock_cons(); + Chose = 0 ; + while (Chose != 'y' && Chose != 'n') + { + cprintf("Do you want to repeat (y/n): ") ; + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); + +} + + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +///Private Functions + + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeIdentical(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + if (Repetition == 0) + Repetition = 3; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + // cprintf("i=%d\n",i); + } + +} + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} + + +void MSort(int* A, int p, int r) +{ + if (p >= r) + { + return; + } + + int q = (p + r) / 2; + + MSort(A, p, q); + + MSort(A, q + 1, r); + + Merge(A, p, q, r); + +} + +void Merge(int* A, int p, int q, int r) +{ + int leftCapacity = q - p + 1; + + int rightCapacity = r - q; + + int leftIndex = 0; + + int rightIndex = 0; + + int* Left = malloc(sizeof(int) * leftCapacity); + + int* Right = malloc(sizeof(int) * rightCapacity); + + // int Left[5000] ; + // int Right[5000] ; + + int i, j, k; + for (i = 0; i < leftCapacity; i++) + { + Left[i] = A[p + i - 1]; + } + for (j = 0; j < rightCapacity; j++) + { + Right[j] = A[q + j]; + } + + for ( k = p; k <= r; k++) + { + if (leftIndex < leftCapacity && rightIndex < rightCapacity) + { + if (Left[leftIndex] < Right[rightIndex] ) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + else if (leftIndex < leftCapacity) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + +} + diff --git a/user/sc_ms_leak_small.c b/user/sc_ms_leak_small.c new file mode 100644 index 0000000..e9c5698 --- /dev/null +++ b/user/sc_ms_leak_small.c @@ -0,0 +1,273 @@ +#include + +uint32 ws_size_first=0; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeIdentical(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +void PrintElements(int *Elements, int NumOfElements); + +void MSort(int* A, int p, int r); +void Merge(int* A, int p, int q, int r); + +uint32 CheckSorted(int *Elements, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + int numOfRep = 0; + do + { + numOfRep++ ; + int NumOfElements ; + //2012: lock the interrupt + sys_lock_cons(); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!!! MERGE SORT !!!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + if (numOfRep == 1) + NumOfElements = 4000; + else if (numOfRep == 2) + NumOfElements = 1000; + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + + // cprintf("Chose the initialization method:\n") ; + // cprintf("a) Ascending\n") ; + // cprintf("b) Descending\n") ; + // cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + if (numOfRep == 1) + { + Chose = 'a' ; + cprintf("a) Ascending\n"); + } + else if (numOfRep == 2) + { + Chose = 'c' ; + cprintf("c) Semi random\n"); + } + // cputchar(Chose); + // cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + } + sys_unlock_cons(); + + int *Elements = malloc(sizeof(int) * NumOfElements) ; + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeIdentical(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + MSort(Elements, 1, NumOfElements); + + sys_lock_cons(); + { + cprintf("Sorting is Finished!!!!it'll be checked now....\n") ; + } + sys_unlock_cons(); + + uint32 Sorted = CheckSorted(Elements, NumOfElements); + + if(Sorted == 0) panic("The array is NOT sorted correctly") ; + else + { + sys_lock_cons(); + { + cprintf("===============================================\n") ; + cprintf("Congratulations!! The array is sorted correctly\n") ; + cprintf("===============================================\n\n") ; + } + sys_unlock_cons(); + } + + //free(Elements) ; + + sys_lock_cons(); + { + Chose = 0 ; + while (Chose != 'y' && Chose != 'n') + { + cprintf("Do you want to repeat (y/n): ") ; + if (numOfRep == 1) + Chose = 'y' ; + else + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); + +} + + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +///Private Functions + + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeIdentical(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + if (Repetition == 0) + Repetition = 3; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + // cprintf("i=%d\n",i); + } + +} + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} + + +void MSort(int* A, int p, int r) +{ + if (p >= r) + { + return; + } + + int q = (p + r) / 2; + + MSort(A, p, q); + + MSort(A, q + 1, r); + + Merge(A, p, q, r); + +} + +void Merge(int* A, int p, int q, int r) +{ + int leftCapacity = q - p + 1; + + int rightCapacity = r - q; + + int leftIndex = 0; + + int rightIndex = 0; + + int* Left = malloc(sizeof(int) * leftCapacity); + + int* Right = malloc(sizeof(int) * rightCapacity); + + // int Left[5000] ; + // int Right[5000] ; + + int i, j, k; + for (i = 0; i < leftCapacity; i++) + { + Left[i] = A[p + i - 1]; + } + for (j = 0; j < rightCapacity; j++) + { + Right[j] = A[q + j]; + } + + for ( k = p; k <= r; k++) + { + if (leftIndex < leftCapacity && rightIndex < rightCapacity) + { + if (Left[leftIndex] < Right[rightIndex] ) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + else if (leftIndex < leftCapacity) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + +} + diff --git a/user/sc_ms_noleak.c b/user/sc_ms_noleak.c new file mode 100644 index 0000000..6d78c9f --- /dev/null +++ b/user/sc_ms_noleak.c @@ -0,0 +1,252 @@ +#include + +uint32 ws_size_first=0; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeIdentical(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +void PrintElements(int *Elements, int NumOfElements); + +void MSort(int* A, int p, int r); +void Merge(int* A, int p, int q, int r); + +uint32 CheckSorted(int *Elements, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + do + { + //2012: lock the interrupt + sys_lock_cons(); + + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!!! MERGE SORT !!!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + //readline("Enter the number of elements: ", Line); + int NumOfElements = 100000 ; + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + + cprintf("Chose the initialization method:\n") ; + cprintf("a) Ascending\n") ; + cprintf("b) Descending\n") ; + cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + //Chose = getchar() ; + Chose = 'c'; + cputchar(Chose); + cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + //2012: lock the interrupt + sys_unlock_cons(); + + int *Elements = malloc(sizeof(int) * NumOfElements) ; + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeIdentical(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + MSort(Elements, 1, NumOfElements); + + sys_lock_cons(); + cprintf("Sorting is Finished!!!!it'll be checked now....\n") ; + //PrintElements(Elements, NumOfElements); + sys_unlock_cons(); + + uint32 Sorted = CheckSorted(Elements, NumOfElements); + + if(Sorted == 0) panic("The array is NOT sorted correctly") ; + else + { + sys_lock_cons(); + cprintf("===============================================\n") ; + cprintf("Congratulations!! The array is sorted correctly\n") ; + cprintf("===============================================\n\n") ; + sys_unlock_cons(); + } + + free(Elements) ; + + sys_lock_cons(); + Chose = 0 ; + while (Chose != 'y' && Chose != 'n') + { + cprintf("Do you want to repeat (y/n): ") ; + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); + +} + + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +///Private Functions + + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeIdentical(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + if (Repetition == 0) + Repetition = 3; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + // cprintf("i=%d\n",i); + } + +} + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} + + +void MSort(int* A, int p, int r) +{ + if (p >= r) + { + return; + } + + int q = (p + r) / 2; + + MSort(A, p, q); + + MSort(A, q + 1, r); + + Merge(A, p, q, r); + +} + +void Merge(int* A, int p, int q, int r) +{ + int leftCapacity = q - p + 1; + + int rightCapacity = r - q; + + int leftIndex = 0; + + int rightIndex = 0; + + int* Left = malloc(sizeof(int) * leftCapacity); + + int* Right = malloc(sizeof(int) * rightCapacity); + + int i, j, k; + for (i = 0; i < leftCapacity; i++) + { + Left[i] = A[p + i - 1]; + } + for (j = 0; j < rightCapacity; j++) + { + Right[j] = A[q + j]; + } + + for ( k = p; k <= r; k++) + { + if (leftIndex < leftCapacity && rightIndex < rightCapacity) + { + if (Left[leftIndex] < Right[rightIndex] ) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + else if (leftIndex < leftCapacity) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + + free(Left); + free(Right); + +} + diff --git a/user/sc_ms_noleak_small.c b/user/sc_ms_noleak_small.c new file mode 100644 index 0000000..312d4f4 --- /dev/null +++ b/user/sc_ms_noleak_small.c @@ -0,0 +1,258 @@ +#include + +uint32 ws_size_first=0; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeIdentical(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +void PrintElements(int *Elements, int NumOfElements); + +void MSort(int* A, int p, int r); +void Merge(int* A, int p, int q, int r); + +uint32 CheckSorted(int *Elements, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + do + { + int NumOfElements ; + //2012: lock the interrupt + sys_lock_cons(); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!!! MERGE SORT !!!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + //readline("Enter the number of elements: ", Line); + NumOfElements = 20000 ; + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + + cprintf("Chose the initialization method:\n") ; + cprintf("a) Ascending\n") ; + cprintf("b) Descending\n") ; + cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + //Chose = getchar() ; + Chose = 'c'; + cputchar(Chose); + cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + } + sys_unlock_cons(); + + int *Elements = malloc(sizeof(int) * NumOfElements) ; + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeIdentical(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + MSort(Elements, 1, NumOfElements); + + sys_lock_cons(); + { + cprintf("Sorting is Finished!!!!it'll be checked now....\n") ; + } + sys_unlock_cons(); + + uint32 Sorted = CheckSorted(Elements, NumOfElements); + + if(Sorted == 0) panic("The array is NOT sorted correctly") ; + else + { + sys_lock_cons(); + { + cprintf("===============================================\n") ; + cprintf("Congratulations!! The array is sorted correctly\n") ; + cprintf("===============================================\n\n") ; + } + sys_unlock_cons(); + } + + free(Elements) ; + + sys_lock_cons(); + { + Chose = 0 ; + while (Chose != 'y' && Chose != 'n') + { + cprintf("Do you want to repeat (y/n): ") ; + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); + +} + + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +///Private Functions + + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeIdentical(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + if (Repetition == 0) + Repetition = 3; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + // cprintf("i=%d\n",i); + } + +} + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} + + +void MSort(int* A, int p, int r) +{ + if (p >= r) + { + return; + } + + int q = (p + r) / 2; + + MSort(A, p, q); + + MSort(A, q + 1, r); + + Merge(A, p, q, r); + +} + +void Merge(int* A, int p, int q, int r) +{ + int leftCapacity = q - p + 1; + + int rightCapacity = r - q; + + int leftIndex = 0; + + int rightIndex = 0; + + int* Left = malloc(sizeof(int) * leftCapacity); + + int* Right = malloc(sizeof(int) * rightCapacity); + + int i, j, k; + for (i = 0; i < leftCapacity; i++) + { + Left[i] = A[p + i - 1]; + } + for (j = 0; j < rightCapacity; j++) + { + Right[j] = A[q + j]; + } + + for ( k = p; k <= r; k++) + { + if (leftIndex < leftCapacity && rightIndex < rightCapacity) + { + if (Left[leftIndex] < Right[rightIndex] ) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + else if (leftIndex < leftCapacity) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + + free(Left); + free(Right); + +} + diff --git a/user/sc_ms_static.c b/user/sc_ms_static.c new file mode 100644 index 0000000..3cdc189 --- /dev/null +++ b/user/sc_ms_static.c @@ -0,0 +1,256 @@ +#include + +#define SIZE 16000000 +int __Elements[SIZE] ; +int __Left[SIZE] ; +int __Right[SIZE] ; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeIdentical(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +void PrintElements(int *Elements, int NumOfElements); + +void MSort(int* A, int p, int r); +void Merge(int* A, int p, int q, int r); + +uint32 CheckSorted(int *Elements, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + int numOfRep = 0; + do + { + numOfRep++ ; + //2012: lock the interrupt + sys_lock_cons(); + + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!!! MERGE SORT !!!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + int NumOfElements = 50000; + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + + cprintf("Chose the initialization method:\n") ; + cprintf("a) Ascending\n") ; + cprintf("b) Descending\n") ; + cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + Chose = 'c' ; + cputchar(Chose); + cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + //2012: lock the interrupt + sys_unlock_cons(); + + //int *Elements = malloc(sizeof(int) * NumOfElements) ; + int *Elements = __Elements; + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeIdentical(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + MSort(Elements, 1, NumOfElements); + + sys_lock_cons(); + cprintf("Sorting is Finished!!!!it'll be checked now....\n") ; + //PrintElements(Elements, NumOfElements); + sys_unlock_cons(); + + uint32 Sorted = CheckSorted(Elements, NumOfElements); + + if(Sorted == 0) panic("The array is NOT sorted correctly") ; + else + { + sys_lock_cons(); + cprintf("===============================================\n") ; + cprintf("Congratulations!! The array is sorted correctly\n") ; + cprintf("===============================================\n\n") ; + sys_unlock_cons(); + } + + //free(Elements) ; + + sys_lock_cons(); + Chose = 0 ; + while (Chose != 'y' && Chose != 'n') + { + cprintf("Do you want to repeat (y/n): ") ; + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); + +} + + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +///Private Functions + + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeIdentical(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + if (Repetition == 0) + Repetition = 3; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + // cprintf("i=%d\n",i); + } + +} + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} + + +void MSort(int* A, int p, int r) +{ + if (p >= r) + { + return; + } + + int q = (p + r) / 2; + + MSort(A, p, q); + + MSort(A, q + 1, r); + + Merge(A, p, q, r); + +} + +void Merge(int* A, int p, int q, int r) +{ + int leftCapacity = q - p + 1; + + int rightCapacity = r - q; + + int leftIndex = 0; + + int rightIndex = 0; + + //int* Left = malloc(sizeof(int) * leftCapacity); + int* Left = __Left ; + int* Right = __Right; + //int* Right = malloc(sizeof(int) * rightCapacity); + + // int Left[5000] ; + // int Right[5000] ; + + int i, j, k; + for (i = 0; i < leftCapacity; i++) + { + Left[i] = A[p + i - 1]; + } + for (j = 0; j < rightCapacity; j++) + { + Right[j] = A[q + j]; + } + + for ( k = p; k <= r; k++) + { + if (leftIndex < leftCapacity && rightIndex < rightCapacity) + { + if (Left[leftIndex] < Right[rightIndex] ) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + else if (leftIndex < leftCapacity) + { + A[k - 1] = Left[leftIndex++]; + } + else + { + A[k - 1] = Right[rightIndex++]; + } + } + +} + diff --git a/user/sc_priRR_1.c b/user/sc_priRR_1.c new file mode 100644 index 0000000..3d9cacd --- /dev/null +++ b/user/sc_priRR_1.c @@ -0,0 +1,198 @@ +#include +inline unsigned int nearest_pow2_ceil(unsigned int x) +{ + if (x <= 1) return 1; + int power = 2; + x--; + while (x >>= 1) { + power <<= 1; + } + return power; +} + +#define NUM_OF_PRIORITIES 3 + +struct progInfo +{ + char progName[100]; + int priorityValues[NUM_OF_PRIORITIES]; + int expectedOrder; +}; +//-1: descending +//1: ascending +//0: don't check +struct progInfo programs[] = { + {"sc_fib_recursive",{15, 10, 5},-1} , //UH: None + {"sc_qs_leak", {0, 10, 20}, 1 }, //UH: Page Alloc ==> malloc one time* + {"sc_ms_leak_small", {0, 5, 10}, 1}, //UH: Page Alloc & Block Alloc ==> malloc + {"sc_ms_noleak_small", {10, 5, 0}, -1 }, //UH: Page Alloc & Block Alloc ==> malloc & free + {"sc_qs_noleak", {14, 8, 1}, -1 }, //UH: Page Alloc ==> malloc & free one time* + {"sc_matops_small", {4, 9, 16}, 1}, //UH: Page Alloc & Block Alloc ==> malloc & free + //"fos_static_data_section", + //"fos_data_on_stack", + /*DON'T CHECK ON THE FOLLOWING... JUST TO INCREASE # RUN PROGS*/ + {"sc_fact_recursive", {0, 0, 0}, 0} , + {"sc_fib_loop",{2, 3, 4}, 0}, + {"sc_fib_memomize",{11, 12, 13}, 0} +}; + +#define NUM_OF_PROGS (sizeof(programs) / sizeof(programs[0])) + +#define TOTAL_INSTANCES (NUM_OF_PROGS * NUM_OF_PRIORITIES) + +int fib(int); + +void _main(void) +{ + rsttst(); + + int envsID[TOTAL_INSTANCES] = {0}; + char setPriorityCmd[100] = "__PRIRRSetPriority@"; + for (int i = 0; i < TOTAL_INSTANCES; i++) + { + int prog_idx = (i % NUM_OF_PROGS); + int priority_idx = (i / NUM_OF_PROGS); + char *program_name = programs[prog_idx].progName; + envsID[i] = sys_create_env(program_name, (myEnv->page_WS_max_size), (myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + char id[20] ; + ltostr(envsID[i], id); + + char setPriorityWithIDCmd[100] ; + strcconcat(setPriorityCmd, id, setPriorityWithIDCmd); + //cprintf("%s, %d, %s, %d\n",setNiceWithIDCmd, envsID[i], id, nice_values[(i / NUM_OF_PROGS)]); + sys_utilities(setPriorityWithIDCmd, programs[prog_idx].priorityValues[priority_idx]); + } + for (int i = 0; i < TOTAL_INSTANCES; i++) + { + sys_run_env(envsID[i]); + } + // env_sleep(10000); + + int num_of_sec = 0, n = 21; + int eval = 0; + bool is_correct = 1; + + while (gettst() != TOTAL_INSTANCES) + { + // int x = MAX(fib(--n), 500); + // num_of_sec += x; + // env_sleep(x); + } + + if (is_correct) eval += 20 ; + is_correct = 1; + //cprintf("\nCongratulations... BSD SCENARIO 1 is finished. Will be checked now...\n"); + + //VALIDATE Results #1 + int totalNumOfDiskAccess = 0; + { + volatile struct Env* allEnvs[TOTAL_INSTANCES] ; + bool progsChk[NUM_OF_PROGS] = {0}; + + for (int i = 0; i < TOTAL_INSTANCES; i++) + { + allEnvs[i] = &envs[ENVX(envsID[i])]; + assert(allEnvs[i]->env_id == envsID[i]) ; + } + bool success = 1; + for (int i = 0; i < NUM_OF_PROGS; i++) + { + int index = 0 * NUM_OF_PROGS + i ; + int nPageFaults = allEnvs[index]->pageFaultsCounter; + int nPageIn = allEnvs[index]->nPageIn; + int nPageOut= allEnvs[index]->nPageOut; + int nPageAdded= allEnvs[index]->nNewPageAdded; + totalNumOfDiskAccess += nPageIn + nPageOut ; + progsChk[i] = 1; + for (int j = 1; j < NUM_OF_PRIORITIES; ++j) + { + index = j * NUM_OF_PROGS + i ; + int nPageFaults2 = allEnvs[index]->pageFaultsCounter; + int nPageIn2 = allEnvs[index]->nPageIn; + int nPageOut2= allEnvs[index]->nPageOut; + int nPageAdded2= allEnvs[index]->nNewPageAdded; + totalNumOfDiskAccess += nPageIn2 + nPageOut2 ; + + progsChk[i] = progsChk[i] && ((nPageFaults == nPageFaults2) && (nPageIn == nPageIn2) && (nPageOut == nPageOut2) && (nPageAdded== nPageAdded2)); + } + if (progsChk[i] == 0) + { + is_correct = 0; + success = 0; + break; + } + } + if (is_correct) eval += 40 ; + is_correct = 1; +// if (success) +// { +// cprintf("\nBSD SCENARIO 1 CHECK#1 is finished. Eval = %d\n", eval); +// } +// else +// { +// panic("Unexpected result: the number of Page Faults, PageIn & PageOut for all instances of same program are expected to be equal\n"); +// } + } + + //VALIDATE Results #2 + atomic_cprintf("Order of the EXIT for each program will be checked now...\n"); + { + char chkExitCmd[100] = "__CheckExitOrder@"; + + bool success = 1; + + for (int i = 0; i < NUM_OF_PROGS; i++) + { + char *program_name = programs[i].progName; + char chkExitWithProgNameCmd[100] ; + strcconcat(chkExitCmd, program_name, chkExitWithProgNameCmd); + //cprintf("%s, %d, %s, %d\n",setNiceWithIDCmd, envsID[i], id, nice_values[(i / NUM_OF_PROGS)]); + int numOfInstances2Chk = NUM_OF_PRIORITIES * programs[i].expectedOrder ; + if (numOfInstances2Chk == 0) + continue; + + sys_utilities(chkExitWithProgNameCmd, (uint32)(&numOfInstances2Chk)); + if (numOfInstances2Chk == 0) + { + is_correct = 0; + success = 0; + //break; + } + } + if (is_correct) + eval += 40 ; + is_correct = 1; +// if (success) +// { + sys_lock_cons(); + { + cprintf("%~\n###############################################################\n"); + //cprintf("%~Congratulations... BSD SCENARIO 1 CHECK#2 is passed successfully\n"); + //cprintf("\nPRIORITY_RR SCENARIO 1 CHECK is finished. Eval = %d\n\n", eval); + cprintf("%~\nTOTAL NUMBER OF DISK ACCESS FOR ALL PROGRAMS = %d\n", totalNumOfDiskAccess); + cprintf("%~\neval = %d\n", eval); + cprintf("%~\n###############################################################\n"); + } + sys_unlock_cons(); +// } +// else +// { +// panic("Unexpected result: order of finished instances of one or more programs is NOT correct\n"); +// } + } +} + +int fib(int n) +{ + int a = 0, b = 1, c, i; + if (n == 0) + return a; + for (i = 2; i <= n; i++) + { + + c = a + b; + a = b; + b = c; + } + return b; +} diff --git a/user/sc_priRR_2.c b/user/sc_priRR_2.c new file mode 100644 index 0000000..7df98e8 --- /dev/null +++ b/user/sc_priRR_2.c @@ -0,0 +1,219 @@ +#include +inline unsigned int nearest_pow2_ceil(unsigned int x) +{ + if (x <= 1) return 1; + int power = 2; + x--; + while (x >>= 1) { + power <<= 1; + } + return power; +} + +#define NUM_OF_PRIORITIES 3 + +struct progInfo +{ + char progName[100]; + int priorityValues[NUM_OF_PRIORITIES]; + int expectedOrder; +}; +//-1: descending +//1: ascending +//0: don't check +struct progInfo programs[] = { + {"sc_fib_recursive",{15, 10, 5},-1} , //UH: None + {"sc_qs_leak", {0, 10, 20}, 1 }, //UH: Page Alloc ==> malloc one time* + {"sc_ms_leak_small", {0, 5, 10}, 1}, //UH: Page Alloc & Block Alloc ==> malloc + {"sc_ms_noleak_small", {10, 5, 0}, -1 }, //UH: Page Alloc & Block Alloc ==> malloc & free + {"sc_qs_noleak", {14, 8, 1}, -1 }, //UH: Page Alloc ==> malloc & free one time* + {"sc_matops_small", {4, 9, 16}, 1}, //UH: Page Alloc & Block Alloc ==> malloc & free + {"sc_air", {1, 11, 21}, 1}, //SharedMem, Semaphores + //"fos_data_on_stack", + /*DON'T CHECK ON THE FOLLOWING... JUST TO INCREASE # RUN PROGS*/ + {"sc_fact_recursive", {0, 0, 0}, 0} , + {"sc_fib_loop",{2, 3, 4}, 0}, + {"sc_fib_memomize",{11, 12, 13}, 0} +}; + +#define NUM_OF_PROGS (sizeof(programs) / sizeof(programs[0])) + +#define TOTAL_INSTANCES (NUM_OF_PROGS * NUM_OF_PRIORITIES) + +int fib(int); + +void _main(void) +{ + rsttst(); + + int envsID[TOTAL_INSTANCES] = {0}; + char setPriorityCmd[100] = "__PRIRRSetPriority@"; + for (int i = 0; i < TOTAL_INSTANCES; i++) + { + int prog_idx = (i % NUM_OF_PROGS); + int priority_idx = (i / NUM_OF_PROGS); + char *program_name = programs[prog_idx].progName; + envsID[i] = sys_create_env(program_name, (myEnv->page_WS_max_size), (myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + char id[20] ; + ltostr(envsID[i], id); + + char setPriorityWithIDCmd[100] ; + strcconcat(setPriorityCmd, id, setPriorityWithIDCmd); + //cprintf("%s, %d, %s, %d\n",setNiceWithIDCmd, envsID[i], id, nice_values[(i / NUM_OF_PROGS)]); + sys_utilities(setPriorityWithIDCmd, programs[prog_idx].priorityValues[priority_idx]); + } + for (int i = 0; i < TOTAL_INSTANCES; i++) + { + sys_run_env(envsID[i]); + } + // env_sleep(10000); + + int num_of_sec = 0, n = 21; + int eval = 0; + bool is_correct = 1; + + char getConsLockCntCmd[100] = "__GetConsLockedCnt__"; + char tmpReleaseConsLockCmd[100] = "__tmpReleaseConsLock__"; + + sys_lock_cons(); + { + while (gettst() != TOTAL_INSTANCES) + { + uint32 consLockCnt = 0; + sys_utilities(getConsLockCntCmd, (uint32) &consLockCnt); + if (consLockCnt == (TOTAL_INSTANCES - gettst())) + { + //release console lock to avoid deadlock + //sys_unlock_cons(); + cprintf("%~\n**********************************************\n" + "TEMPORARILY RELEASE CONS LOCK TO AVOID DEADLOCK\n" + "**********************************************\n"); + sys_utilities(tmpReleaseConsLockCmd, 0); + env_sleep(RANDU(1000, 10000)); + sys_lock_cons(); + } + env_sleep(RANDU(10000, 20000)); + } + } + sys_unlock_cons(); + + if (is_correct) eval += 20 ; + is_correct = 1; + cprintf("\nSCHEDULER SCENARIO#2 is finished. Will be checked now...\n"); + + //VALIDATE Results #1 + int totalNumOfDiskAccess = 0; + { + volatile struct Env* allEnvs[TOTAL_INSTANCES] ; + bool progsChk[NUM_OF_PROGS] = {0}; + + for (int i = 0; i < TOTAL_INSTANCES; i++) + { + allEnvs[i] = &envs[ENVX(envsID[i])]; + assert(allEnvs[i]->env_id == envsID[i]) ; + } + bool success = 1; + for (int i = 0; i < NUM_OF_PROGS; i++) + { + int index = 0 * NUM_OF_PROGS + i ; + int nPageFaults = allEnvs[index]->pageFaultsCounter; + int nPageIn = allEnvs[index]->nPageIn; + int nPageOut= allEnvs[index]->nPageOut; + int nPageAdded= allEnvs[index]->nNewPageAdded; + totalNumOfDiskAccess += nPageIn + nPageOut ; + progsChk[i] = 1; + for (int j = 1; j < NUM_OF_PRIORITIES; ++j) + { + index = j * NUM_OF_PROGS + i ; + int nPageFaults2 = allEnvs[index]->pageFaultsCounter; + int nPageIn2 = allEnvs[index]->nPageIn; + int nPageOut2= allEnvs[index]->nPageOut; + int nPageAdded2= allEnvs[index]->nNewPageAdded; + totalNumOfDiskAccess += nPageIn2 + nPageOut2 ; + + progsChk[i] = progsChk[i] && ((nPageFaults == nPageFaults2) && (nPageIn == nPageIn2) && (nPageOut == nPageOut2) && (nPageAdded== nPageAdded2)); + } + if (progsChk[i] == 0) + { + is_correct = 0; + success = 0; + break; + } + } + if (is_correct) eval += 40 ; + is_correct = 1; + cprintf("\nSCHEDULER SCENARIO#2 CHECK#1 is finished.\n"); + // if (success) + // { + // cprintf("\nBSD SCENARIO 1 CHECK#1 is finished. Eval = %d\n", eval); + // } + // else + // { + // panic("Unexpected result: the number of Page Faults, PageIn & PageOut for all instances of same program are expected to be equal\n"); + // } + } + + //VALIDATE Results #2 + atomic_cprintf("Order of the EXIT for each program will be checked now...\n"); + { + char chkExitCmd[100] = "__CheckExitOrder@"; + + bool success = 1; + + for (int i = 0; i < NUM_OF_PROGS; i++) + { + char *program_name = programs[i].progName; + char chkExitWithProgNameCmd[100] ; + strcconcat(chkExitCmd, program_name, chkExitWithProgNameCmd); + //cprintf("%s, %d, %s, %d\n",setNiceWithIDCmd, envsID[i], id, nice_values[(i / NUM_OF_PROGS)]); + int numOfInstances2Chk = NUM_OF_PRIORITIES * programs[i].expectedOrder ; + if (numOfInstances2Chk == 0) + continue; + + sys_utilities(chkExitWithProgNameCmd, (uint32)(&numOfInstances2Chk)); + if (numOfInstances2Chk == 0) + { + is_correct = 0; + success = 0; + //break; + } + } + if (is_correct) + eval += 40 ; + cprintf("\nSCHEDULER SCENARIO#2 CHECK#2 is finished.\n"); + + is_correct = 1; + // if (success) + // { + sys_lock_cons(); + { + cprintf("%~\n###############################################################\n"); + //cprintf("%~Congratulations... BSD SCENARIO 1 CHECK#2 is passed successfully\n"); + //cprintf("\nPRIORITY_RR SCENARIO 2 CHECK is finished. Eval = %d\n\n", eval); + cprintf("%~\nTOTAL NUMBER OF DISK ACCESS FOR ALL PROGRAMS = %d\n", totalNumOfDiskAccess); + cprintf("%~\neval = %d\n", eval); + cprintf("%~\n###############################################################\n"); + } + sys_unlock_cons(); + // } + // else + // { + // panic("Unexpected result: order of finished instances of one or more programs is NOT correct\n"); + // } + } +} + +int fib(int n) +{ + int a = 0, b = 1, c, i; + if (n == 0) + return a; + for (i = 2; i <= n; i++) + { + + c = a + b; + a = b; + b = c; + } + return b; +} diff --git a/user/sc_qs_leakage.c b/user/sc_qs_leakage.c new file mode 100644 index 0000000..f8f4914 --- /dev/null +++ b/user/sc_qs_leakage.c @@ -0,0 +1,211 @@ +#include + +uint32 ws_size_first=0; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeIdentical(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +void PrintElements(int *Elements, int NumOfElements); + +void QuickSort(int *Elements, int NumOfElements); +void QSort(int *Elements,int NumOfElements, int startIndex, int finalIndex); +uint32 CheckSorted(int *Elements, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + do + { + int NumOfElements = 1000000 ; + //2012: lock the interrupt + sys_lock_cons(); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!! QUICK SORT !!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + cprintf("Chose the initialization method:\n") ; + cprintf("a) Ascending\n") ; + cprintf("b) Descending\n") ; + cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + Chose = 'c' ; + cputchar(Chose); + cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + } + sys_unlock_cons(); + + int *Elements = malloc(sizeof(int) * NumOfElements) ; + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeIdentical(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + QuickSort(Elements, NumOfElements); + + sys_lock_cons(); + { + cprintf("Sorting is Finished!!!!it'll be checked now....\n") ; + } + sys_unlock_cons(); + + uint32 Sorted = CheckSorted(Elements, NumOfElements); + + if(Sorted == 0) panic("The array is NOT sorted correctly") ; + else + { + sys_lock_cons(); + { + cprintf("===============================================\n") ; + cprintf("Congratulations!! The array is sorted correctly\n") ; + cprintf("===============================================\n\n") ; + } + sys_unlock_cons(); + + } + + //free(Elements) ; + + sys_lock_cons(); + { + cprintf("Do you want to repeat (y/n): ") ; + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); +} + +///Quick sort +void QuickSort(int *Elements, int NumOfElements) +{ + QSort(Elements, NumOfElements, 0, NumOfElements-1) ; +} + + +void QSort(int *Elements,int NumOfElements, int startIndex, int finalIndex) +{ + if (startIndex >= finalIndex) return; + + int i = startIndex+1, j = finalIndex; + + while (i <= j) + { + while (i <= finalIndex && Elements[startIndex] >= Elements[i]) i++; + while (j > startIndex && Elements[startIndex] <= Elements[j]) j--; + + if (i <= j) + { + Swap(Elements, i, j); + } + } + + Swap( Elements, startIndex, j); + + QSort(Elements, NumOfElements, startIndex, j - 1); + QSort(Elements, NumOfElements, i, finalIndex); + + //cprintf("qs,after sorting: start = %d, end = %d\n", startIndex, finalIndex); + +} + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +///Private Functions + + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeIdentical(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + if (Repetition == 0) + Repetition = 3; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + // cprintf("i=%d\n",i); + } + +} + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} diff --git a/user/sc_qs_leakage_small.c b/user/sc_qs_leakage_small.c new file mode 100644 index 0000000..83e7728 --- /dev/null +++ b/user/sc_qs_leakage_small.c @@ -0,0 +1,206 @@ +#include + +uint32 ws_size_first=0; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeIdentical(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +void PrintElements(int *Elements, int NumOfElements); + +void QuickSort(int *Elements, int NumOfElements); +void QSort(int *Elements,int NumOfElements, int startIndex, int finalIndex); +uint32 CheckSorted(int *Elements, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + do + { + //2012: lock the interrupt + sys_lock_cons(); + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!! QUICK SORT !!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + + int NumOfElements = 20000 ; + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + cprintf("Chose the initialization method:\n") ; + cprintf("a) Ascending\n") ; + cprintf("b) Descending\n") ; + cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + Chose = 'c' ; + cputchar(Chose); + cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + //2012: lock the interrupt + sys_unlock_cons(); + + int *Elements = malloc(sizeof(int) * NumOfElements) ; + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeIdentical(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + QuickSort(Elements, NumOfElements); + + sys_lock_cons(); + cprintf("Sorting is Finished!!!!it'll be checked now....\n") ; + // PrintElements(Elements, NumOfElements); + sys_unlock_cons(); + + uint32 Sorted = CheckSorted(Elements, NumOfElements); + + if(Sorted == 0) panic("The array is NOT sorted correctly") ; + else + { + sys_lock_cons(); + cprintf("===============================================\n") ; + cprintf("Congratulations!! The array is sorted correctly\n") ; + cprintf("===============================================\n\n") ; + sys_unlock_cons(); + + } + + //free(Elements) ; + + sys_lock_cons(); + + cprintf("Do you want to repeat (y/n): ") ; + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); +} + +///Quick sort +void QuickSort(int *Elements, int NumOfElements) +{ + QSort(Elements, NumOfElements, 0, NumOfElements-1) ; +} + + +void QSort(int *Elements,int NumOfElements, int startIndex, int finalIndex) +{ + if (startIndex >= finalIndex) return; + + int i = startIndex+1, j = finalIndex; + + while (i <= j) + { + while (i <= finalIndex && Elements[startIndex] >= Elements[i]) i++; + while (j > startIndex && Elements[startIndex] <= Elements[j]) j--; + + if (i <= j) + { + Swap(Elements, i, j); + } + } + + Swap( Elements, startIndex, j); + + QSort(Elements, NumOfElements, startIndex, j - 1); + QSort(Elements, NumOfElements, i, finalIndex); + + //cprintf("qs,after sorting: start = %d, end = %d\n", startIndex, finalIndex); + +} + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +///Private Functions + + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeIdentical(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + if (Repetition == 0) + Repetition = 3; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + // cprintf("i=%d\n",i); + } + +} + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} diff --git a/user/sc_qs_noleak.c b/user/sc_qs_noleak.c new file mode 100644 index 0000000..669536b --- /dev/null +++ b/user/sc_qs_noleak.c @@ -0,0 +1,211 @@ +#include + +uint32 ws_size_first=0; + +//Functions Declarations +void Swap(int *Elements, int First, int Second); +void InitializeAscending(int *Elements, int NumOfElements); +void InitializeIdentical(int *Elements, int NumOfElements); +void InitializeSemiRandom(int *Elements, int NumOfElements); +void PrintElements(int *Elements, int NumOfElements); + +void QuickSort(int *Elements, int NumOfElements); +void QSort(int *Elements,int NumOfElements, int startIndex, int finalIndex); +uint32 CheckSorted(int *Elements, int NumOfElements); + +void _main(void) +{ + char Line[255] ; + char Chose ; + do + { + int NumOfElements = 200000 ; + //2012: lock the interrupt + sys_lock_cons(); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!! QUICK SORT !!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + + cprintf("Enter the number of elements: %d\n", NumOfElements) ; + cprintf("Chose the initialization method:\n") ; + cprintf("a) Ascending\n") ; + cprintf("b) Descending\n") ; + cprintf("c) Semi random\n"); + do + { + cprintf("Select: ") ; + Chose = 'c' ; + cputchar(Chose); + cputchar('\n'); + } while (Chose != 'a' && Chose != 'b' && Chose != 'c'); + + } + sys_unlock_cons(); + + int *Elements = malloc(sizeof(int) * NumOfElements) ; + + int i ; + switch (Chose) + { + case 'a': + InitializeAscending(Elements, NumOfElements); + break ; + case 'b': + InitializeIdentical(Elements, NumOfElements); + break ; + case 'c': + InitializeSemiRandom(Elements, NumOfElements); + break ; + default: + InitializeSemiRandom(Elements, NumOfElements); + } + + QuickSort(Elements, NumOfElements); + + sys_lock_cons(); + { + cprintf("Sorting is Finished!!!!it'll be checked now....\n") ; + } + sys_unlock_cons(); + + uint32 Sorted = CheckSorted(Elements, NumOfElements); + + if(Sorted == 0) panic("The array is NOT sorted correctly") ; + else + { + sys_lock_cons(); + { + cprintf("===============================================\n") ; + cprintf("Congratulations!! The array is sorted correctly\n") ; + cprintf("===============================================\n\n") ; + } + sys_unlock_cons(); + + } + + free(Elements) ; + + sys_lock_cons(); + { + cprintf("Do you want to repeat (y/n): ") ; + Chose = 'n' ; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + sys_unlock_cons(); + + } while (Chose == 'y'); + + //To indicate that it's completed successfully + inctst(); +} + +///Quick sort +void QuickSort(int *Elements, int NumOfElements) +{ + QSort(Elements, NumOfElements, 0, NumOfElements-1) ; +} + + +void QSort(int *Elements,int NumOfElements, int startIndex, int finalIndex) +{ + if (startIndex >= finalIndex) return; + + int i = startIndex+1, j = finalIndex; + + while (i <= j) + { + while (i <= finalIndex && Elements[startIndex] >= Elements[i]) i++; + while (j > startIndex && Elements[startIndex] <= Elements[j]) j--; + + if (i <= j) + { + Swap(Elements, i, j); + } + } + + Swap( Elements, startIndex, j); + + QSort(Elements, NumOfElements, startIndex, j - 1); + QSort(Elements, NumOfElements, i, finalIndex); + + //cprintf("qs,after sorting: start = %d, end = %d\n", startIndex, finalIndex); + +} + +uint32 CheckSorted(int *Elements, int NumOfElements) +{ + uint32 Sorted = 1 ; + int i ; + for (i = 0 ; i < NumOfElements - 1; i++) + { + if (Elements[i] > Elements[i+1]) + { + Sorted = 0 ; + break; + } + } + return Sorted ; +} + +///Private Functions + + +void Swap(int *Elements, int First, int Second) +{ + int Tmp = Elements[First] ; + Elements[First] = Elements[Second] ; + Elements[Second] = Tmp ; +} + +void InitializeAscending(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + (Elements)[i] = i ; + } + +} + +void InitializeIdentical(int *Elements, int NumOfElements) +{ + int i ; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = NumOfElements - i - 1 ; + } + +} + +void InitializeSemiRandom(int *Elements, int NumOfElements) +{ + int i ; + int Repetition = NumOfElements / 3 ; + if (Repetition == 0) + Repetition = 3; + for (i = 0 ; i < NumOfElements ; i++) + { + Elements[i] = i % Repetition ; + // cprintf("i=%d\n",i); + } + +} + +void PrintElements(int *Elements, int NumOfElements) +{ + int i ; + int NumsPerLine = 20 ; + for (i = 0 ; i < NumOfElements-1 ; i++) + { + if (i%NumsPerLine == 0) + cprintf("\n"); + cprintf("%d, ",Elements[i]); + } + cprintf("%d\n",Elements[i]); + +} diff --git a/user/tst_air.c b/user/tst_air.c index 3f32d35..480c811 100644 --- a/user/tst_air.c +++ b/user/tst_air.c @@ -9,20 +9,67 @@ _main(void) { int envID = sys_getenvid(); - // ************************************************************************************************* - /// Shared Variables Region ************************************************************************ - // ************************************************************************************************* + int numOfClerks = 3; + int agentCapacity = 20; + int numOfCustomers = 30; + int flight1NumOfCustomers = numOfCustomers/3; + int flight2NumOfCustomers = numOfCustomers/3; + int flight3NumOfCustomers = numOfCustomers - (flight1NumOfCustomers + flight2NumOfCustomers); - int numOfCustomers = 15; - int flight1Customers = 3; - int flight2Customers = 8; - int flight3Customers = 4; + int flight1NumOfTickets = 15; + int flight2NumOfTickets = 8; - int flight1NumOfTickets = 8; - int flight2NumOfTickets = 15; + // ************************************************************************************************* + /// Reading Inputs ********************************************************************************* + // ************************************************************************************************* + char Line[255] ; + char Chose; + sys_lock_cons(); + { + cprintf("\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("!!!! AIR PLANE RESERVATION !!!!\n"); + cprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + cprintf("\n"); + cprintf("%~Default #customers = %d (equally divided over the 3 flights).\n" + "Flight1 Tickets = %d, Flight2 Tickets = %d\n" + "Agent Capacity = %d\n", numOfCustomers, flight1NumOfTickets, flight2NumOfTickets, agentCapacity) ; + Chose = 0 ; + while (Chose != 'y' && Chose != 'n' && Chose != 'Y' && Chose != 'N') + { + cprintf("%~Do you want to change these values(y/n)? ") ; + //Chose = getchar() ; + Chose = 'n'; + cputchar(Chose); + cputchar('\n'); + cputchar('\n'); + } + if (Chose == 'y' || Chose == 'Y') + { + readline("Enter the capacity of the agent: ", Line); + agentCapacity = strtol(Line, NULL, 10) ; + readline("Enter the total number of customers: ", Line); + numOfCustomers = strtol(Line, NULL, 10) ; + flight1NumOfCustomers = flight2NumOfCustomers = numOfCustomers / 3; + flight3NumOfCustomers = numOfCustomers - (flight1NumOfCustomers + flight2NumOfCustomers); + readline("Enter # tickets of flight#1: ", Line); + flight1NumOfTickets = strtol(Line, NULL, 10) ; + readline("Enter # tickets of flight#2: ", Line); + flight2NumOfTickets = strtol(Line, NULL, 10) ; + } + } + sys_unlock_cons(); + // ************************************************************************************************* + /// Shared Variables Region ************************************************************************ + // ************************************************************************************************* + char _isOpened[] = "isOpened"; + char _agentCapacity[] = "agentCapacity"; char _customers[] = "customers"; char _custCounter[] = "custCounter"; + char _flight1Customers[] = "flight1Customers"; + char _flight2Customers[] = "flight2Customers"; + char _flight3Customers[] = "flight3Customers"; char _flight1Counter[] = "flight1Counter"; char _flight2Counter[] = "flight2Counter"; char _flightBooked1Counter[] = "flightBooked1Counter"; @@ -41,37 +88,21 @@ _main(void) char _clerk[] = "clerk"; char _custCounterCS[] = "custCounterCS"; char _custTerminated[] = "custTerminated"; + char _clerkTerminated[] = "clerkTerminated"; char _taircl[] = "taircl"; char _taircu[] = "taircu"; struct Customer * custs; - custs = smalloc(_customers, sizeof(struct Customer)*numOfCustomers, 1); + custs = smalloc(_customers, sizeof(struct Customer)*(numOfCustomers+1), 1); //sys_createSharedObject("customers", sizeof(struct Customer)*numOfCustomers, 1, (void**)&custs); + int* flight1Customers = smalloc(_flight1Customers, sizeof(int), 1); *flight1Customers = flight1NumOfCustomers; + int* flight2Customers = smalloc(_flight2Customers, sizeof(int), 1); *flight2Customers = flight2NumOfCustomers; + int* flight3Customers = smalloc(_flight3Customers, sizeof(int), 1); *flight3Customers = flight3NumOfCustomers; - { - int f1 = 0; - for(;f1page_WS_max_size),(myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); - sys_run_env(envId); - - envId = sys_create_env(_taircl, (myEnv->page_WS_max_size), (myEnv->SecondListSize),(myEnv->percentage_of_WS_pages_to_be_removed)); - sys_run_env(envId); - - envId = sys_create_env(_taircl, (myEnv->page_WS_max_size), (myEnv->SecondListSize),(myEnv->percentage_of_WS_pages_to_be_removed)); - sys_run_env(envId); + for (int k = 0; k < numOfClerks; ++k) + { + envId = sys_create_env(_taircl, (myEnv->page_WS_max_size),(myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + sys_run_env(envId); + } //customers int c; @@ -161,9 +191,11 @@ _main(void) } env_sleep(1500); + int b; + sys_lock_cons(); + { //print out the results - int b; for(b=0; b< (*flight1BookedCounter);++b) { cprintf("cust %d booked flight 1, originally ordered %d\n", flight1BookedArr[b], custs[flight1BookedArr[b]].flightType); @@ -173,35 +205,50 @@ _main(void) { cprintf("cust %d booked flight 2, originally ordered %d\n", flight2BookedArr[b], custs[flight2BookedArr[b]].flightType); } + } + sys_unlock_cons(); - //check out the final results and semaphores + int numOfBookings = 0; + int numOfFCusts[3] = {0}; + + for(b=0; b< numOfCustomers;++b) { - int f1 = 0; - for(;f1 #include +extern volatile bool printStats; void _main(void) { + //disable the print of prog stats after finishing + printStats = 0; + int parentenvID = sys_getparentenvid(); // Get the shared variables from the main program *********************************** + char _isOpened[] = "isOpened"; char _customers[] = "customers"; char _custCounter[] = "custCounter"; char _flight1Counter[] = "flight1Counter"; @@ -30,12 +35,15 @@ _main(void) char _clerk[] = "clerk"; char _custCounterCS[] = "custCounterCS"; char _custTerminated[] = "custTerminated"; + char _clerkTerminated[] = "clerkTerminated"; char _taircl[] = "taircl"; char _taircu[] = "taircu"; struct Customer * customers = sget(parentenvID, _customers); + int* isOpened = sget(parentenvID, _isOpened); + int* flight1Counter = sget(parentenvID, _flight1Counter); int* flight2Counter = sget(parentenvID, _flight2Counter); @@ -56,8 +64,9 @@ _main(void) struct semaphore flight1CS = get_semaphore(parentenvID, _flight1CS); struct semaphore flight2CS = get_semaphore(parentenvID, _flight2CS); struct semaphore clerk = get_semaphore(parentenvID, _clerk); + struct semaphore clerkTerminated = get_semaphore(parentenvID, _clerkTerminated); - while(1==1) + while(*isOpened) { int custId; //wait for a customer @@ -68,6 +77,12 @@ _main(void) { //cprintf("*queue_out = %d\n", *queue_out); custId = cust_ready_queue[*queue_out]; + //there's no more customers for now... + if (custId == -1) + { + signal_semaphore(custQueueCS); + continue; + } *queue_out = *queue_out +1; } signal_semaphore(custQueueCS); @@ -92,7 +107,7 @@ _main(void) } else { - + cprintf("%~\nFlight#1 is FULL! Reservation request of customer#%d is rejected\n", custId); } } signal_semaphore(flight1CS); @@ -113,7 +128,7 @@ _main(void) } else { - + cprintf("%~\nFlight#2 is FULL! Reservation request of customer#%d is rejected\n", custId); } } signal_semaphore(flight2CS); @@ -139,7 +154,7 @@ _main(void) } else { - + cprintf("%~\nFlight#1 and/or Flight#2 is FULL! Reservation request of customer#%d is rejected\n", custId); } } signal_semaphore(flight1CS); signal_semaphore(flight2CS); @@ -161,4 +176,7 @@ _main(void) //signal the clerk signal_semaphore(clerk); } + + cprintf("\nclerk is finished...........\n"); + signal_semaphore(clerkTerminated); } diff --git a/user/tst_air_customer.c b/user/tst_air_customer.c index 2e86023..accc4a3 100644 --- a/user/tst_air_customer.c +++ b/user/tst_air_customer.c @@ -3,11 +3,16 @@ #include #include +extern volatile bool printStats; void _main(void) { + //disable the print of prog stats after finishing + printStats = 0; + int32 parentenvID = sys_getparentenvid(); + char _agentCapacity[] = "agentCapacity"; char _customers[] = "customers"; char _custCounter[] = "custCounter"; char _flight1Counter[] = "flight1Counter"; @@ -32,6 +37,10 @@ _main(void) char _taircl[] = "taircl"; char _taircu[] = "taircu"; + char _flight1Customers[] = "flight1Customers"; + char _flight2Customers[] = "flight2Customers"; + char _flight3Customers[] = "flight3Customers"; + // Get the shared variables from the main program *********************************** struct Customer * customers = sget(parentenvID, _customers); @@ -42,8 +51,13 @@ _main(void) int* queue_in = sget(parentenvID, _queue_in); - // ********************************************************************************* + int* flight1Customers = sget(parentenvID, _flight1Customers); + int* flight2Customers = sget(parentenvID, _flight2Customers); + int* flight3Customers = sget(parentenvID, _flight3Customers); + // Get the shared semaphores from the main program *********************************** + + struct semaphore capacity = get_semaphore(parentenvID, _agentCapacity); struct semaphore custCounterCS = get_semaphore(parentenvID, _custCounterCS); struct semaphore clerk = get_semaphore(parentenvID, _clerk); struct semaphore custQueueCS = get_semaphore(parentenvID, _custQueueCS); @@ -56,42 +70,59 @@ _main(void) custId = *custCounter; //cprintf("custCounter= %d\n", *custCounter); *custCounter = *custCounter +1; + repFlightSel: + //get random flight + flightType = RANDU(1, 4); + if(flightType == 1 && *flight1Customers > 0) (*flight1Customers)--; + else if(flightType == 2 && *flight2Customers > 0) (*flight2Customers)--; + else if(flightType == 3 && *flight3Customers > 0) (*flight3Customers)--; + else goto repFlightSel; } signal_semaphore(custCounterCS); - //wait on one of the clerks - wait_semaphore(clerk); + //delay for a random time + env_sleep(RANDU(100, 10000)); - //enqueue the request - flightType = customers[custId].flightType; - wait_semaphore(custQueueCS); - { - cust_ready_queue[*queue_in] = custId; - *queue_in = *queue_in +1; - } - signal_semaphore(custQueueCS); - - //signal ready - signal_semaphore(cust_ready); - - //wait on finished - char prefix[30]="cust_finished"; - char id[5]; char sname[50]; - ltostr(custId, id); - strcconcat(prefix, id, sname); - //sys_waitSemaphore(parentenvID, sname); - struct semaphore cust_finished = get_semaphore(parentenvID, sname); - wait_semaphore(cust_finished); - - //print the customer status - if(customers[custId].booked == 1) - { - atomic_cprintf("cust %d: finished (BOOKED flight %d) \n", custId, flightType); - } - else + //enter the agent if there's a space + wait_semaphore(capacity); { - atomic_cprintf("cust %d: finished (NOT BOOKED) \n", custId); + //wait on one of the clerks + wait_semaphore(clerk); + + //enqueue the request + customers[custId].booked = 0 ; + customers[custId].flightType = flightType ; + wait_semaphore(custQueueCS); + { + cust_ready_queue[*queue_in] = custId; + *queue_in = *queue_in +1; + } + signal_semaphore(custQueueCS); + + //signal ready + signal_semaphore(cust_ready); + + //wait on finished + char prefix[30]="cust_finished"; + char id[5]; char sname[50]; + ltostr(custId, id); + strcconcat(prefix, id, sname); + //sys_waitSemaphore(parentenvID, sname); + struct semaphore cust_finished = get_semaphore(parentenvID, sname); + wait_semaphore(cust_finished); + + //print the customer status + if(customers[custId].booked == 1) + { + cprintf("cust %d: finished (BOOKED flight %d) \n", custId, flightType); + } + else + { + cprintf("cust %d: finished (NOT BOOKED) \n", custId); + } } + //exit the agent + signal_semaphore(capacity); //customer is terminated signal_semaphore(custTerminated); diff --git a/user/tst_free_user_mem.c b/user/tst_free_user_mem.c new file mode 100644 index 0000000..e4e7cfb --- /dev/null +++ b/user/tst_free_user_mem.c @@ -0,0 +1,579 @@ +/* + * tst_free_user_mem.c + * + * Created on: Dec 25, 2023 + * Author: Mohamed Raafat + */ +/* *********************************************************** + * > run tfum 50000 + * *********************************************************** */ +#include + +#define M32 0xffffffff +struct uint64 baseTime; +//int largeGlobalSpace[10000*PAGE_SIZE]; +char *itoa(uint32 value, char *result, int base); +struct uint64 subtractUint64(const struct uint64 num1, const struct uint64 num2); +void addBigNumbers(const char *num1, const char *num2, char *result); +void subtractBigNumbers(const char *num1, const char *num2, char *result); +void multiplyBigNumbers(const char *num1, const char *num2, char *result); +void divideBigNumbers(const char *number, uint32 divisor, char *result); + +struct uint64 calc_execution_time(struct uint64 baseTime); +void fill_range(void *start_address, uint32 numOfFrames); + +void convert_uint64_to_char(struct uint64 number, char *result); +struct uint64 convert_char_to_uint64(const char *bigNumber); + +void _main(void) +{ +// largeGlobalSpace[1] = 10; + + sys_set_uheap_strategy(UHP_PLACE_FIRSTFIT); + /*********************** NOTE **************************** + * WE COMPARE THE DIFF IN FREE FRAMES BY "AT LEAST" RULE + * INSTEAD OF "EQUAL" RULE SINCE IT'S POSSIBLE THAT SOME + * PAGES ARE ALLOCATED IN DYNAMIC ALLOCATOR DUE TO sbrk() + * (e.g. DURING THE DYNAMIC CREATION OF WS ELEMENT in FH). + *********************************************************/ + // Initial test to ensure it works on "PLACEMENT" not "REPLACEMENT" + { + if (LIST_SIZE(&(myEnv->page_WS_list)) >= myEnv->page_WS_max_size) + panic("Please increase the WS size"); + } + /*=================================================*/ + + uint32 pagealloc_start = USER_HEAP_START + DYN_ALLOC_MAX_SIZE + PAGE_SIZE; // UHS + 32MB + 4KB + + int Mega = 1024 * 1024, kilo = 1024; + void *ptr_allocations[10] = {0}; + uint32 allocated_frames[10] = {0}; + int idx ; + int freeFrames, usedDiskPages, arraySizeInMB, actualNumOfFrames, expectedNumOfFrames; + int sizeOf1stAlloc = 250*Mega; + + //[1] Allocate set of blocks + { + cprintf("\n[*] Part 1: Test Pre-Processing Started... \n\tAllocating Dummy LARGE Blocks --> "); + // Allocate 250 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = sizeOf1stAlloc/Mega; + ptr_allocations[5] = malloc(arraySizeInMB * Mega - kilo); + //actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[5] != (pagealloc_start)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start), ptr_allocations[5]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + idx = 5; + allocated_frames[idx] = sizeOf1stAlloc/PAGE_SIZE; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b40%%"); + + // Allocate 35 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = 35; + ptr_allocations[7] = malloc(arraySizeInMB * Mega - kilo); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[7] != (pagealloc_start + sizeOf1stAlloc)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start + 25 * Mega), ptr_allocations[7]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + + freeFrames = sys_calculate_free_frames(); + idx = 7; + allocated_frames[idx] = 8960 - 1; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b50%%"); + + // Allocate 15 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = 15; + ptr_allocations[8] = malloc(arraySizeInMB * Mega - kilo); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[8] != (pagealloc_start + sizeOf1stAlloc + 35 * Mega)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start + 60 * Mega), ptr_allocations[8]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + idx = 8; + allocated_frames[idx] = 3840 - 1; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b55%%"); + + // Allocate 25 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = 25; + ptr_allocations[6] = malloc(arraySizeInMB * Mega - kilo); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[6] != (pagealloc_start + sizeOf1stAlloc + 50 * Mega)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start + 110 * Mega), ptr_allocations[6]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + idx = 6; + allocated_frames[idx] = 6400 - 1; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b65%%"); + + // Allocate 20 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = 20; + ptr_allocations[4] = malloc(arraySizeInMB * Mega - kilo); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[4] != (pagealloc_start + sizeOf1stAlloc + 75 * Mega)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start + 153 * Mega), ptr_allocations[4]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + idx = 4; + allocated_frames[idx] = 5120 - 1; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b75%%"); + + // Allocate 18 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = 18; + ptr_allocations[3] = malloc(arraySizeInMB * Mega - kilo); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[3] != (pagealloc_start + sizeOf1stAlloc + 95 * Mega)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start + 135 * Mega), ptr_allocations[3]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + idx = 3; + allocated_frames[idx] = 4608 - 1; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b82%%"); + + // Allocate 22 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = 22; + ptr_allocations[2] = malloc(arraySizeInMB * Mega - kilo); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[2] != (pagealloc_start + sizeOf1stAlloc + 113 * Mega)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start + 75 * Mega), ptr_allocations[2]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + idx = 2; + allocated_frames[idx] = 5632 - 1; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b92%%"); + + // Allocate 13 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = 13; + ptr_allocations[1] = malloc(arraySizeInMB * Mega - kilo); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[1] != (pagealloc_start + sizeOf1stAlloc + 135 * Mega)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start + 97 * Mega), ptr_allocations[1]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + idx = 1; + allocated_frames[idx] = 3328 - 1; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b95%%"); + + // Allocate 15 MB + usedDiskPages = sys_pf_calculate_allocated_pages(); + arraySizeInMB = 15; + ptr_allocations[0] = malloc(arraySizeInMB * Mega - kilo); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()); + if ((uint32)ptr_allocations[0] != (pagealloc_start + sizeOf1stAlloc + 148 * Mega)) + panic("Wrong start address for the allocated space... (Expected: %x, Received: %x)", (pagealloc_start + 173 * Mega), ptr_allocations[0]); +// if (actualNumOfFrames < (arraySizeInMB / 4)) +// panic("Wrong fault handler: pages are not loaded successfully into memory/WS. Expected diff in frames at least = %d, actual = %d\n", (arraySizeInMB / 4), actualNumOfFrames); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + idx = 0; + allocated_frames[idx] = 3840 - 1; + fill_range(ptr_allocations[idx], allocated_frames[idx]); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_frames[idx]) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + cprintf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b100%%\n"); + } + // cprintf(">>>>>>>>>>>>> %d-MB\n", (USER_HEAP_MAX - pagealloc_start) / Mega); + +#define numOfSmallBlocks 1000 + void *ptr_small_allocations[numOfSmallBlocks] = {0}; + uint32 smallBlockSize = 32*kilo; + uint32 allocated_small_frames = smallBlockSize/PAGE_SIZE; + uint32 startAddr = (pagealloc_start + sizeOf1stAlloc + 163 * Mega); + //[2] Allocate set of SMALL blocks + { + cprintf("\n[*] Part 2: Test Pre-Processing Started... \n\tAllocating Dummy SMALL Blocks --> 0%%"); + int step = numOfSmallBlocks / 100; + for (int i = 0; i < numOfSmallBlocks; ++i) + { + usedDiskPages = sys_pf_calculate_allocated_pages(); + ptr_small_allocations[i] = malloc(smallBlockSize); + if ((uint32)ptr_small_allocations[i] != (startAddr + i*smallBlockSize)) + panic("Wrong start address for the allocated space #%d... (Expected: %x, Received: %x)", i, (startAddr + i*smallBlockSize), ptr_small_allocations[i]); + if ((sys_pf_calculate_allocated_pages() - usedDiskPages) != 0) + panic("Wrong page file allocation: Expected no pages to be allocated."); + freeFrames = sys_calculate_free_frames(); + fill_range(ptr_small_allocations[i], allocated_small_frames); + actualNumOfFrames = (freeFrames - sys_calculate_free_frames()) ; + if (actualNumOfFrames < allocated_small_frames) + panic("wrong number of allocated frames for ptr_allocations[%d]", idx); + if ((i+1)%step == 0) + { + int progress = (i+1) / step; + if (progress <= 10) + cprintf("%~\b\b%d%%", progress); + else + cprintf("%~\b\b\b%d%%", progress); + } + } + } + //[3] Free SMALL allocated memory blocks + struct uint64 start = sys_get_virtual_time(); + { + cprintf("\n\n[*] Part 3: Freeing allocated memory SMALL blocks. Started --> 0%%"); + int step = numOfSmallBlocks / 100; + for (int i = 0; i < numOfSmallBlocks; i++) + { + freeFrames = sys_calculate_free_frames(); + usedDiskPages = sys_pf_calculate_allocated_pages(); + baseTime = sys_get_virtual_time(); + //cprintf("==> Freeing ptr[%d]\n", i); + free(ptr_small_allocations[(i)]); + if ((usedDiskPages - sys_pf_calculate_allocated_pages()) != 0) { panic("Wrong free: Extra or less pages are removed from PageFile\n");} + //cprintf("sys_calculate_free_frames() - freeFrames = %d, allocated_frames[i] = %d\n", sys_calculate_free_frames() - freeFrames, allocated_frames[i]); + if ((sys_calculate_free_frames() - freeFrames) != allocated_small_frames) { panic("Wrong free: WS pages in memory and/or page tables are not freed correctly\n");} + if ((i+1)%step == 0) + { + int progress = (i+1) / step; + if (progress <= 10) + cprintf("%~\b\b%d%%", progress); + else + cprintf("%~\b\b\b%d%%", progress); + } + } + } + //[4] Free LARGE allocated memory blocks + struct uint64 execution_time[10], total_execution_time; + { + cprintf("\n\n[*] Part 4: Freeing allocated memory LARGE blocks. Started...\n"); + + for (int i = 0; i < 5; i++) + { + freeFrames = sys_calculate_free_frames(); + usedDiskPages = sys_pf_calculate_allocated_pages(); + baseTime = sys_get_virtual_time(); + //cprintf("==> Freeing ptr[%d]\n", i); + free(ptr_allocations[(i)]); + execution_time[(i)] = calc_execution_time(baseTime); + if ((usedDiskPages - sys_pf_calculate_allocated_pages()) != 0) { panic("Wrong free: Extra or less pages are removed from PageFile\n");} + //cprintf("sys_calculate_free_frames() - freeFrames = %d, allocated_frames[i] = %d\n", sys_calculate_free_frames() - freeFrames, allocated_frames[i]); + if ((sys_calculate_free_frames() - freeFrames) != allocated_frames[i] ) { panic("Wrong free: WS pages in memory and/or page tables are not freed correctly\n");} + + } + } + struct uint64 end = sys_get_virtual_time(); + total_execution_time = subtractUint64(end, start); + char sub[64]; + convert_uint64_to_char(total_execution_time, sub); + cprintf("@@@@@@@@@@@@@@@ TOTAL EXECUTION TIME: %s (%u:%u) @@@@@@@@@@@@@@@\n", sub, total_execution_time.hi, total_execution_time.low); + + if (total_execution_time.hi > 0 || total_execution_time.low > 2000000000) + panic("The complexity of free_user_mem is not O(1)"); + + //cprintf("Congratulations... test of O(1) free user mem is run successfully within the time limit\n"); + cprintf("[#MS2EVAL#]Congratulations!!... test is completed."); + + return; +} + +struct uint64 calc_execution_time(struct uint64 baseTime) +{ + struct uint64 currentTime = sys_get_virtual_time(); + + char baseTimeStr[64] = {0}, currentTimeStr[64] = {0}, differenceTimeStr[64] = {0}, temp[64] = {0}; + convert_uint64_to_char(currentTime, currentTimeStr); + convert_uint64_to_char(baseTime, baseTimeStr); + // subtract basetime from current time + subtractBigNumbers(currentTimeStr, baseTimeStr, differenceTimeStr); + cprintf(">>>>> StartTime: %s, EndTime: %s, Diff: %s <<<<<\n", baseTimeStr, currentTimeStr, differenceTimeStr); + struct uint64 r = convert_char_to_uint64(differenceTimeStr); + // cprintf(">>>>> Difference Result: %u.%u <<<<<\n", r.hi, r.low); + + // subtract basetime from current time + // struct uint64 res = subtractUint64(currentTime, baseTime); + // cprintf("##### cur: %u.%u - t: %u.%u = sub: %u.%u\n", currentTime.hi, currentTime.low, baseTime.hi, baseTime.low, res.hi, res.low); + return r; +} +struct uint64 subtractUint64(const struct uint64 num1, const struct uint64 num2) +{ + struct uint64 res; + res.low = (num1.low - num2.low) & M32; + res.hi = (num1.hi - num2.hi - (res.low > num1.low)) & M32; + res.low = ((num1.low - num2.low) < 0) ? (-(num1.low - num2.low)) : res.low; + // cprintf("##### cur: %u.%u - t: %u.%u = sub: %u.%u\n", num1.hi, num1.low, num2.hi, num2.low, res.hi, res.low); + return res; +} + +void fill_range(void *start_address, uint32 numOfFrames) +{ + uint8 *ptr = (uint8 *)start_address; + uint32 size_to_be_filled = (numOfFrames * PAGE_SIZE); + for (uint32 i = 0; i < size_to_be_filled; i += PAGE_SIZE) + ptr[i] = i; +} + +char *itoa(uint32 value, char *result, int base) +{ + // check that the base if valid + if (base < 2 || base > 36) + { + *result = '\0'; + return result; + } + + char *ptr = result, *ptr1 = result, tmp_char; + int tmp_value; + + do + { + tmp_value = value; + value /= base; + *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; + } while (value); + + // Apply negative sign + if (tmp_value < 0) + *ptr++ = '-'; + *ptr-- = '\0'; + + // Reverse the string + while (ptr1 < ptr) + { + tmp_char = *ptr; + *ptr-- = *ptr1; + *ptr1++ = tmp_char; + } + return result; +} +void addBigNumbers(const char *num1, const char *num2, char *result) +{ + int carry = 0; + int len1 = strlen(num1); + int len2 = strlen(num2); + + int maxLen = len1 > len2 ? len1 : len2; + + memset(result, '\0', strlen(result)); + + for (int i = 0; i < maxLen; ++i) + { + int digit1 = i < len1 ? num1[len1 - 1 - i] - '0' : 0; + int digit2 = i < len2 ? num2[len2 - 1 - i] - '0' : 0; + + int sum = digit1 + digit2 + carry; + carry = sum / 10; + result[i] = (sum % 10) + '0'; + } + + if (carry > 0) + { + result[maxLen] = carry + '0'; + result[maxLen + 1] = '\0'; + } + else + { + result[maxLen] = '\0'; + } + + // Reverse the result string + int len = strlen(result); + for (int i = 0; i < len / 2; ++i) + { + char temp = result[i]; + result[i] = result[len - 1 - i]; + result[len - 1 - i] = temp; + } +} + +void subtractBigNumbers(const char *num1, const char *num2, char *result) +{ + int len1 = strlen(num1); + int len2 = strlen(num2); + memset(result, '\0', strlen(result)); + + // Ensure num1 is greater than or equal to num2 + if (len1 < len2 || (len1 == len2 && strcmp(num1, num2) < 0)) + { + const char *temp = num1; + num1 = num2; + num2 = temp; + int temp2 = len1; + len1 = len2; + len2 = temp2; + } + int resultSize = len1 + 1; // Maximum size for the result + result[resultSize - 1] = '\0'; + + int carry = 0; + int i, j, k; + + for (i = len1 - 1, j = len2 - 1, k = resultSize - 2; i >= 0; i--, j--, k--) + { + int digit1 = (i >= 0) ? (num1[i] - '0') : 0; + int digit2 = (j >= 0) ? (num2[j] - '0') : 0; + int tempResult = digit1 - digit2 - carry; + if (tempResult < 0) + { + tempResult += 10; + carry = 1; + } + else + carry = 0; + result[k] = tempResult + '0'; + } + + // Remove leading zeros + while (result[0] == '0' && result[1] != '\0') + { + memmove(result, result + 1, resultSize - 1); + } +} +void multiplyBigNumbers(const char *num1, const char *num2, char *result) +{ + int len1 = strlen(num1); + int len2 = strlen(num2); + int product[64] = {0}; + + for (int i = len1 - 1; i >= 0; i--) + { + for (int j = len2 - 1; j >= 0; j--) + { + int digit1 = num1[i] - '0'; + int digit2 = num2[j] - '0'; + int partialProduct = digit1 * digit2 + product[i + j + 1]; + + product[i + j + 1] = partialProduct % 10; + product[i + j] += partialProduct / 10; + } + } + + int resultIndex = 0; + while (resultIndex < len1 + len2 && product[resultIndex] == 0) + { + resultIndex++; + } + + memset(result, '\0', strlen(result)); + for (int i = 0; i < len1 + len2 - resultIndex; i++) + { + result[i] = product[resultIndex + i] + '0'; + } + + result[len1 + len2 - resultIndex] = '\0'; +} +void divideBigNumbers(const char *number, uint32 divisor, char *result) +{ + // As result can be very large store it in string + int length = strlen(number); + + memset(result, '\0', strlen(result)); + // Find prefix of number that is larger + // than divisor. + int idx = 0; + int temp = number[idx] - '0'; + while (idx < (length - 1) && temp < divisor) + temp = temp * 10 + (number[++idx] - '0'); + + // Repeatedly divide divisor with temp. After + // every division, update temp to include one + // more digit. + int i = 0; + while (length > idx) + { + // Store result in answer i.e. temp / divisor + result[i++] = (temp / divisor) + '0'; + + // Take next digit of number + temp = (temp % divisor) * 10 + number[++idx] - '0'; + } +} + +void convert_uint64_to_char(struct uint64 number, char *result) +{ + char low[32] = {0}; + char temp[64] = {0}; + memset(result, '\0', strlen(result)); + + itoa(number.low, low, 10); + + if (number.hi > 0) + { + itoa(number.hi, temp, 10); + for (int i = 0; i < 32; i++) + { + multiplyBigNumbers(temp, "2", result); + strcpy(temp, result); + } + } + addBigNumbers(temp, low, result); +} +struct uint64 convert_char_to_uint64(const char *bigNumber) +{ + char low[32] = {0}; + char resultStr[64] = {0}, temp[64] = {0}; + struct uint64 result; + result.low = (uint32)strtol(bigNumber, NULL, 10); + itoa(result.low, low, 10); + subtractBigNumbers(bigNumber, low, temp); + for (int i = 0; i < 32; i++) + { + divideBigNumbers(temp, 2, resultStr); + strcpy(temp, resultStr); + } + result.hi = (uint32)strtol(temp, NULL, 10); + return result; +} diff --git a/user/tst_page_replacement_alloc.c b/user/tst_page_replacement_alloc.c index c09cc3a..e422c8e 100644 --- a/user/tst_page_replacement_alloc.c +++ b/user/tst_page_replacement_alloc.c @@ -4,9 +4,9 @@ #include -char arr[PAGE_SIZE*12]; -char* ptr = (char* )0x0801000 ; -char* ptr2 = (char* )0x0804000 ; +char __arr__[PAGE_SIZE*12]; +char* __ptr__ = (char* )0x0801000 ; +char* __ptr2__ = (char* )0x0804000 ; uint32 expectedInitialVAs[11] = { 0x200000, 0x201000, 0x202000, 0x203000, 0x204000, 0x205000, //Unused 0x800000, 0x801000, 0x802000, 0x803000, //Code & Data @@ -34,22 +34,22 @@ void _main(void) int usedDiskPages = sys_pf_calculate_allocated_pages(); //Reading (Not Modified) - char garbage1 = arr[PAGE_SIZE*11-1] ; - char garbage2 = arr[PAGE_SIZE*12-1] ; + char garbage1 = __arr__[PAGE_SIZE*11-1] ; + char garbage2 = __arr__[PAGE_SIZE*12-1] ; char garbage4,garbage5; //Writing (Modified) int i ; for (i = 0 ; i < PAGE_SIZE*10 ; i+=PAGE_SIZE/2) { - arr[i] = -1 ; + __arr__[i] = -1 ; /*2016: this BUGGY line is REMOVED el7! it overwrites the KERNEL CODE :( !!!*/ - //*ptr = *ptr2 ; + //*__ptr__ = *__ptr2__ ; /*==========================================================================*/ //always use pages at 0x801000 and 0x804000 - garbage4 = *ptr + garbage5; - garbage5 = *ptr2 + garbage4; - ptr++ ; ptr2++ ; + garbage4 = *__ptr__ + garbage5; + garbage5 = *__ptr2__ + garbage4; + __ptr__++ ; __ptr2__++ ; } //=================== @@ -64,6 +64,8 @@ void _main(void) } - cprintf("Congratulations!! test PAGE replacement [ALLOCATION] is completed successfully\n"); + //cprintf("Congratulations!! test PAGE replacement [ALLOCATION] is completed successfully\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); + return; } diff --git a/user/tst_page_replacement_nthclock_1.c b/user/tst_page_replacement_nthclock_1.c index 10d496b..455203a 100644 --- a/user/tst_page_replacement_nthclock_1.c +++ b/user/tst_page_replacement_nthclock_1.c @@ -4,9 +4,9 @@ #include -char arr[PAGE_SIZE*12]; -char* ptr = (char* )0x0801000 ; -char* ptr2 = (char* )0x0804000 ; +char __arr__[PAGE_SIZE*12]; +char* __ptr__ = (char* )0x0801000 ; +char* __ptr2__ = (char* )0x0804000 ; uint32 expectedInitialVAs[11] = { 0x200000, 0x201000, 0x202000, 0x203000, 0x204000, 0x205000, //Unused 0x800000, 0x801000, 0x802000, 0x803000, //Code & Data @@ -18,11 +18,11 @@ uint32 expectedFinalVAs[11] = { 0x80a000, 0x804000, 0x80b000, 0x80c000,0x807000,0x800000,0x801000,0x808000,0x809000,0x803000, //Code & Data } ; -void fillPage(char* arr, int pageIdx, char val) +void fillPage(char* __arr__, int pageIdx, char val) { for (int i = pageIdx*PAGE_SIZE; i < (pageIdx+1)*PAGE_SIZE; ++i) { - arr[i] = val; + __arr__[i] = val; } } @@ -45,27 +45,27 @@ void _main(void) int usedDiskPages = sys_pf_calculate_allocated_pages(); //Reading (Not Modified) - char garbage1 = arr[PAGE_SIZE*11-1] ; - char garbage2 = arr[PAGE_SIZE*12-1] ; + char garbage1 = __arr__[PAGE_SIZE*11-1] ; + char garbage2 = __arr__[PAGE_SIZE*12-1] ; char garbage4,garbage5; //Writing (Modified) int i ; for (i = 0 ; i < PAGE_SIZE*10 ; i+=PAGE_SIZE/2) { - arr[i] = 'A' ; + __arr__[i] = 'A' ; /*2016: this BUGGY line is REMOVED el7! it overwrites the KERNEL CODE :( !!!*/ - //*ptr = *ptr2 ; + //*__ptr__ = *__ptr2__ ; /*==========================================================================*/ //always use pages at 0x801000 and 0x804000 - garbage4 = *ptr ; + garbage4 = *__ptr__ ; if (i % PAGE_SIZE == 0) - garbage5 = *ptr2 ; + garbage5 = *__ptr2__ ; // if (((i/PAGE_SIZE) + 1) % 3 == 0) // { // cprintf("BEFORE FILL...\n"); -// fillPage(arr, (i/PAGE_SIZE) - 2, 'A'); +// fillPage(__arr__, (i/PAGE_SIZE) - 2, 'A'); // cprintf("AFTER FILL\n"); // } } @@ -78,10 +78,12 @@ void _main(void) if (found != 1) panic("Page Nth clock algo failed.. trace it by printing WS before and after page fault"); } { - if (garbage4 != *ptr) panic("test failed!"); - if (garbage5 != *ptr2) panic("test failed!"); + if (garbage4 != *__ptr__) panic("test failed!"); + if (garbage5 != *__ptr2__) panic("test failed!"); } - cprintf("Congratulations!! test PAGE replacement [Nth clock Alg.] is completed successfully.\n"); + //cprintf("Congratulations!! test PAGE replacement [Nth clock Alg.] is completed successfully.\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); + return; } diff --git a/user/tst_page_replacement_nthclock_2.c b/user/tst_page_replacement_nthclock_2.c index b19fe0e..efe6f5c 100644 --- a/user/tst_page_replacement_nthclock_2.c +++ b/user/tst_page_replacement_nthclock_2.c @@ -4,9 +4,9 @@ #include -char arr[PAGE_SIZE*12]; -char* ptr = (char* )0x0801000 ; -char* ptr2 = (char* )0x0804000 ; +char __arr__[PAGE_SIZE*12]; +char* __ptr__ = (char* )0x0801000 ; +char* __ptr2__ = (char* )0x0804000 ; uint32 expectedInitialVAs[11] = { 0x200000, 0x201000, 0x202000, 0x203000, 0x204000, 0x205000, //Unused 0x800000, 0x801000, 0x802000, 0x803000, //Code & Data @@ -37,22 +37,22 @@ void _main(void) int usedDiskPages = sys_pf_calculate_allocated_pages(); //Reading (Not Modified) - char garbage1 = arr[PAGE_SIZE*11-1] ; - char garbage2 = arr[PAGE_SIZE*12-1] ; + char garbage1 = __arr__[PAGE_SIZE*11-1] ; + char garbage2 = __arr__[PAGE_SIZE*12-1] ; char garbage4,garbage5; //Writing (Modified) int i ; for (i = 0 ; i < PAGE_SIZE*10 ; i+=PAGE_SIZE/2) { - arr[i] = 'A' ; + __arr__[i] = 'A' ; /*2016: this BUGGY line is REMOVED el7! it overwrites the KERNEL CODE :( !!!*/ - //*ptr = *ptr2 ; + //*__ptr__ = *__ptr2__ ; /*==========================================================================*/ //always use pages at 0x801000 and 0x804000 - garbage4 = *ptr ; + garbage4 = *__ptr__ ; if (i % PAGE_SIZE == 0) - garbage5 = *ptr2 ; + garbage5 = *__ptr2__ ; } //=================== @@ -63,10 +63,12 @@ void _main(void) if (found != 1) panic("Page Nth clock algo failed.. trace it by printing WS before and after page fault"); } { - if (garbage4 != *ptr) panic("test failed!"); - if (garbage5 != *ptr2) panic("test failed!"); + if (garbage4 != *__ptr__) panic("test failed!"); + if (garbage5 != *__ptr2__) panic("test failed!"); } - cprintf("Congratulations!! test PAGE replacement [Nth clock Alg.] is completed successfully.\n"); + //cprintf("Congratulations!! test PAGE replacement [Nth clock Alg.] is completed successfully.\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); + return; } diff --git a/user/tst_page_replacement_nthclock_3.c b/user/tst_page_replacement_nthclock_3.c new file mode 100644 index 0000000..050aa28 --- /dev/null +++ b/user/tst_page_replacement_nthclock_3.c @@ -0,0 +1,140 @@ +/* *********************************************************** */ +/* MAKE SURE PAGE_WS_MAX_SIZE = 11 */ +/* *********************************************************** */ + +#include + +char __arr__[PAGE_SIZE*12]; +char* __ptr__ = (char* )0x0801000 ; +char* __ptr2__ = (char* )0x0804000 ; +uint32 expectedInitialVAs[11] = { + 0x200000, 0x201000, 0x202000, 0x203000, 0x204000, 0x205000, //Unused + 0x800000, 0x801000, 0x802000, 0x803000, //Code & Data + 0xeebfd000, //Stack +} ; + + +#define kilo 1024 +void _main(void) +{ + uint32 expectedMidVAs[11] ; + { + expectedMidVAs[0] = 0xeebfd000; + expectedMidVAs[1] = 0x80a000; + expectedMidVAs[2] = 0x804000; + expectedMidVAs[3] = 0x80b000; + expectedMidVAs[4] = 0x80c000; + expectedMidVAs[5] = 0x807000; + expectedMidVAs[6] = 0x800000; + expectedMidVAs[7] = 0x801000; + expectedMidVAs[8] = 0x808000; + expectedMidVAs[9] = 0x809000; + expectedMidVAs[10] = 0x803000; + } +// uint32 expectedFinalVAs[11] = { +// 0x80b000,0x804000,0x80c000,0x800000,0x801000, //Code & Data +// 0xeebfd000, //Stack +// 0x803000,0x805000,0x806000,0x807000,0x808000, //Data +// } ; + + uint32 expectedFinalVAs[11] ; + { + expectedFinalVAs[0] = 0x804000; + expectedFinalVAs[1] = 0x80b000; + expectedFinalVAs[2] = 0x80c000; + expectedFinalVAs[3] = 0x800000; + expectedFinalVAs[4] = 0xeebfd000; + expectedFinalVAs[5] = 0x801000; + expectedFinalVAs[6] = 0x803000; + expectedFinalVAs[7] = 0x805000; + expectedFinalVAs[8] = 0x806000; + expectedFinalVAs[9] = 0x807000; + expectedFinalVAs[10] = 0x808000; + } + + char* tempArr = (char*)0x90000000; + uint32 tempArrSize = 5*PAGE_SIZE; + //("STEP 0: checking Initial WS entries ...\n"); + bool found ; + +#if USE_KHEAP + { + found = sys_check_WS_list(expectedInitialVAs, 11, 0x200000, 1); + if (found != 1) panic("INITIAL PAGE WS entry checking failed! Review size of the WS!!\n*****IF CORRECT, CHECK THE ISSUE WITH THE STAFF*****"); + } +#else + panic("make sure to enable the kernel heap: USE_KHEAP=1"); +#endif + + int freePages = sys_calculate_free_frames(); + int usedDiskPages = sys_pf_calculate_allocated_pages(); + + //Reading (Not Modified) + char garbage1 = __arr__[PAGE_SIZE*11-1]; + char garbage2 = __arr__[PAGE_SIZE*12-1]; + char garbage4, garbage5; + + //Writing (Modified) + int i; + for (i = 0 ; i < PAGE_SIZE*10 ; i+=PAGE_SIZE/2) + { + __arr__[i] = 'A' ; + /*2016: this BUGGY line is REMOVED el7! it overwrites the KERNEL CODE :( !!!*/ + //*__ptr__ = *__ptr2__ ; + //__ptr__++ ; __ptr2__++ ; + /*==========================================================================*/ + //always use pages at 0x801000 and 0x804000 + garbage4 = *__ptr__ ; + garbage5 = *__ptr2__ ; + } + + //Check Nth Clock 1 + { + found = sys_check_WS_list(expectedMidVAs, 11, 0x807000, 1); + if (found != 1) panic("Page Nth Clock algo failed.. trace it by printing WS before and after page fault"); + } + + //char* tempArr = malloc(4*PAGE_SIZE); + sys_allocate_user_mem((uint32)tempArr, tempArrSize); + //cprintf("1\n"); + + int c; + for(c = 0;c < tempArrSize - 1;c++) + { + tempArr[c] = 'a'; + } + + //cprintf("2\n"); + + sys_free_user_mem((uint32)tempArr, tempArrSize); + + //cprintf("3\n"); + + //Check after free either push records up or leave them empty + for (i = PAGE_SIZE*0 ; i < PAGE_SIZE*6 ; i+=PAGE_SIZE/2) + { + __arr__[i] = 'A' ; + //always use pages at 0x801000 and 0x804000 + garbage4 = *__ptr__ ; + garbage5 = *__ptr2__ ; + } + //cprintf("4\n"); + + //=================== + + //cprintf("Checking Nth Clock algorithm after Free and replacement... \n"); + { + found = sys_check_WS_list(expectedFinalVAs, 11, 0x804000, 1); + if (found != 1) panic("Page Nth Clock algo failed [AFTER Freeing an Allocated Space].. MAKE SURE to update the last_WS_element & the correct FIFO order after freeing space"); + } + + { + if (garbage4 != *__ptr__) panic("test failed!"); + if (garbage5 != *__ptr2__) panic("test failed!"); + } + + //cprintf("Congratulations!! test PAGE replacement [Nth Clock after free user mem] is completed successfully\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); + + return; +} diff --git a/user/tst_page_replacement_stack.c b/user/tst_page_replacement_stack.c index 91ce4f4..c459145 100644 --- a/user/tst_page_replacement_stack.c +++ b/user/tst_page_replacement_stack.c @@ -30,7 +30,8 @@ void _main(void) if( (freePages - (sys_calculate_free_frames() + sys_calculate_modified_frames())) != 0 ) panic("Extra memory are wrongly allocated... It's REplacement: expected that no extra frames are allocated"); }//consider tables of PF, disk pages - cprintf("Congratulations: stack pages created, modified and read is completed successfully\n\n"); + //cprintf("Congratulations: stack pages created, modified and read is completed successfully\n\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); return; diff --git a/user/tst_protection.c b/user/tst_protection.c index db01533..9f7b612 100644 --- a/user/tst_protection.c +++ b/user/tst_protection.c @@ -32,6 +32,7 @@ _main(void) while (gettst() != numOfSlaves) ; - cprintf("%~\nCongratulations... test protection is run successfully\n"); + //cprintf("%~\nCongratulations... test protection is run successfully\n"); + cprintf("[#MS2EVAL#]Congratulations!!... test is completed."); } diff --git a/user/tst_sbrk.c b/user/tst_sbrk.c new file mode 100644 index 0000000..1026669 --- /dev/null +++ b/user/tst_sbrk.c @@ -0,0 +1,135 @@ + +#include +#include +//#include + +#define Mega (1024*1024) +#define kilo (1024) + +int inRange(int val, int min, int max) +{ + return (val >= min && val <= max) ? 1 : 0; +} + +void _main() +{ + int i, freeFrames, freeDiskFrames; + char *ptr; + int eval = 0; + bool correct = 1; + uint32 oldBrk, newBrk; + + uint32 numOfCases = 5; + uint32 incNumOfPages[] = {0, 1, 2, 11, (32*Mega)/PAGE_SIZE - 13}; + uint32 expectedVAs[] = { + USER_HEAP_START, // 0 + USER_HEAP_START, // 1 + USER_HEAP_START + 0x1000, // 2 + USER_HEAP_START + 0x3000, // 11 + -1, // exceed (RETURN -1) + }; + uint32 expectedSbrks[] = { + USER_HEAP_START, // 0 + USER_HEAP_START + 0x1000, // 1 + USER_HEAP_START + 0x3000, // 2 + USER_HEAP_START + 0xe000, // 11 + USER_HEAP_START + 0xe000, // exceed + }; + + cprintf("\nSTEP A: checking sbrk() increment with zero & +ve values [80%]\n\n"); + { + //cprintf("THE WHOLE BLOCK ALLOCATOR IS %d\n",(myEnv->uh_dynalloc_limit-USER_HEAP_START)/PAGE_SIZE); + for (int i = 0; i < numOfCases - 1; ++i) + { + freeFrames = (int)sys_calculate_free_frames(); + freeDiskFrames = (int)sys_pf_calculate_allocated_pages(); + oldBrk = (uint32)sbrk(0); + char* VA = sbrk(incNumOfPages[i]); + newBrk = (uint32)sbrk(0); + correct = 1; + char c='a'; + if (((int)sys_pf_calculate_allocated_pages() - freeDiskFrames) != 0) + { + correct = 0; + cprintf("A.%d: Page file is changed while it's not expected to. (pages are wrongly allocated/de-allocated in PageFile)\n", i); + } + if (!inRange((freeFrames - (int)sys_calculate_free_frames()),0,1)) + { + correct = 0; + cprintf("A.%d: Wrong memory allocation\n", i); + } + if ((uint32)VA != expectedVAs[i]) + { + correct = 0; + cprintf("A.%d: Wrong returned break: Expected: %x, Actual: %x\n", i, expectedVAs[i], VA); + } + if (newBrk != expectedSbrks[i]) + { + correct = 0; + cprintf("A.%d: Wrong new break: Expected: %x, Actual: %x\n", i, expectedSbrks[i], newBrk); + } + //TO CHECK THE MARKING OF THE PAGES + if (i==2) + { + for(int j=0;j<2;j++) + { + *VA=c; + c++; + VA+=PAGE_SIZE; + } + for(int j=0;j<2;j++) + { + VA-=PAGE_SIZE; + c--; + if(*VA != c) + { + correct = 0; + cprintf("Wrong values\n"); + } + } + } + + + if (correct) + eval += 20; + } + } + cprintf("\nSTEP B: checking sbrk() increment with LARGE +ve value (EXCEED LIMIT) [20%]\n\n"); + { + for (int i = numOfCases - 1; i < numOfCases ; ++i) + { + freeFrames = (int)sys_calculate_free_frames(); + freeDiskFrames = (int)sys_pf_calculate_allocated_pages(); + oldBrk = (uint32)sbrk(0); + void* VA = sbrk(incNumOfPages[i]); + newBrk = (uint32)sbrk(0); + correct = 1; + if (((int)sys_pf_calculate_allocated_pages() - freeDiskFrames) != 0) + { + correct = 0; + cprintf("B.%d: Page file is changed while it's not expected to. (pages are wrongly allocated/de-allocated in PageFile)\n", i); + } + if ((freeFrames - (int)sys_calculate_free_frames()) != 0) + { + correct = 0; + cprintf("B.%d: Wrong memory allocation\n", i); + } + if ((uint32)VA != expectedVAs[i]) + { + correct = 0; + cprintf("B.%d: Wrong returned break: Expected: %x, Actual: %x\n", i, expectedVAs[i], VA); + } + if (newBrk != expectedSbrks[i]) + { + correct = 0; + cprintf("B.%d: Wrong new break: Expected: %x, Actual: %x\n", i, expectedSbrks[i], newBrk); + } + if (correct) + eval += 20; + } + } + + cprintf("\nTest sys_sbrk completed. Eval = %d%%\n\n", eval); + + cprintf("=================\n\n"); +} diff --git a/user/tst_semaphore_1master.c b/user/tst_semaphore_1master.c index 7dd46c7..80f7321 100644 --- a/user/tst_semaphore_1master.c +++ b/user/tst_semaphore_1master.c @@ -26,9 +26,10 @@ _main(void) int sem1val = semaphore_count(cs1); int sem2val = semaphore_count(depend1); if (sem2val == 0 && sem1val == 1) - cprintf("Congratulations!! Test of Semaphores [1] completed successfully!!\n\n\n"); + //cprintf("Congratulations!! Test of Semaphores [1] completed successfully!!\n\n\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); else - panic("Error: wrong semaphore value... please review your semaphore code again! Expected = %d, %d, Actual = %d, %d", 1, 0, sem1val, sem2val); + atomic_cprintf("Error: wrong semaphore value... please review your semaphore code again! Expected = %d, %d, Actual = %d, %d", 1, 0, sem1val, sem2val); return; } diff --git a/user/tst_semaphore_1slave.c b/user/tst_semaphore_1slave.c index 607baed..91081f9 100644 --- a/user/tst_semaphore_1slave.c +++ b/user/tst_semaphore_1slave.c @@ -11,7 +11,7 @@ _main(void) struct semaphore cs1 = get_semaphore(parentenvID, "cs1"); struct semaphore depend1 = get_semaphore(parentenvID, "depend1"); - cprintf("%d: before the critical section\n", id); + atomic_cprintf("%d: before the critical section\n", id); wait_semaphore(cs1); { cprintf("%d: inside the critical section\n", id) ; @@ -22,7 +22,7 @@ _main(void) env_sleep(1000) ; } signal_semaphore(cs1); - cprintf("%d: after the critical section\n", id); + atomic_cprintf("%d: after the critical section\n", id); signal_semaphore(depend1); return; diff --git a/user/tst_semaphore_2master.c b/user/tst_semaphore_2master.c index 1073df0..741bd0f 100644 --- a/user/tst_semaphore_2master.c +++ b/user/tst_semaphore_2master.c @@ -7,10 +7,17 @@ _main(void) { int envID = sys_getenvid(); char line[256] ; - readline("Enter total number of customers: ", line) ; - int totalNumOfCusts = strtol(line, NULL, 10); - readline("Enter shop capacity: ", line) ; - int shopCapacity = strtol(line, NULL, 10); +// readline("Enter total number of customers: ", line) ; +// int totalNumOfCusts = strtol(line, NULL, 10); + + int totalNumOfCusts = 100 ; + atomic_cprintf("Enter total number of customers: %d\n", totalNumOfCusts) ; + +// readline("Enter shop capacity: ", line) ; +// int shopCapacity = strtol(line, NULL, 10); + + int shopCapacity = 30; + atomic_cprintf("Enter shop capacity: %d\n", shopCapacity) ; struct semaphore shopCapacitySem = create_semaphore("shopCapacity", shopCapacity); struct semaphore dependSem = create_semaphore("depend", 0); @@ -35,9 +42,10 @@ _main(void) //wait a while to allow the slaves to finish printing their closing messages env_sleep(10000); if (sem2val == 0 && sem1val == shopCapacity) - cprintf("\nCongratulations!! Test of Semaphores [2] completed successfully!!\n\n\n"); + //cprintf("\nCongratulations!! Test of Semaphores [2] completed successfully!!\n\n\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); else - cprintf("\nError: wrong semaphore value... please review your semaphore code again...\n"); + atomic_cprintf("\nError: wrong semaphore value... please review your semaphore code again...\n"); return; } diff --git a/user/tst_semaphore_2slave.c b/user/tst_semaphore_2slave.c index be4e359..2cc6a95 100644 --- a/user/tst_semaphore_2slave.c +++ b/user/tst_semaphore_2slave.c @@ -2,10 +2,12 @@ // Slave program: enter the shop, leave it and signal the master program #include +extern volatile bool printStats; void _main(void) { + printStats = 0; int id = sys_getenvindex(); int32 parentenvID = sys_getparentenvid(); @@ -15,12 +17,12 @@ _main(void) wait_semaphore(shopCapacitySem); { - cprintf("Cust %d: inside the shop\n", id) ; - env_sleep(1000) ; + atomic_cprintf("Cust %d: inside the shop\n", id) ; + env_sleep(RANDU(100,1000)) ; } signal_semaphore(shopCapacitySem); - cprintf("Cust %d: exit the shop\n", id); + atomic_cprintf("Cust %d: exit the shop\n", id); signal_semaphore(dependSem); return; } diff --git a/user/tst_sharing_4.c b/user/tst_sharing_4.c index 030f5ff..403e5fc 100644 --- a/user/tst_sharing_4.c +++ b/user/tst_sharing_4.c @@ -170,7 +170,8 @@ _main(void) if (is_correct) eval+=25; is_correct = 1; - cprintf("\n%~Test of freeSharedObjects [4] completed. Eval = %d%%\n\n", eval); + //cprintf("\n%~Test of freeSharedObjects [4] completed. Eval = %d%%\n\n", eval); + cprintf("%~\neval = %d\n", eval); return; } diff --git a/user/tst_sharing_5_slaveB2.c b/user/tst_sharing_5_slaveB2.c index 10a2e8d..70bf6a4 100644 --- a/user/tst_sharing_5_slaveB2.c +++ b/user/tst_sharing_5_slaveB2.c @@ -41,7 +41,8 @@ _main(void) cprintf("Step B completed successfully!!\n\n\n"); - cprintf("\n%~Congratulations!! Test of freeSharedObjects [5] completed successfully!!\n\n\n"); + //cprintf("\n%~Congratulations!! Test of freeSharedObjects [5] completed successfully!!\n\n\n"); + atomic_cprintf("%~\nCongratulations!!... test is completed.\n"); return; } diff --git a/user/tst_sleeplock_master.c b/user/tst_sleeplock_master.c new file mode 100644 index 0000000..c5e0181 --- /dev/null +++ b/user/tst_sleeplock_master.c @@ -0,0 +1,60 @@ +// Test the Sleep Lock for applying critical section +// Master program: create and run slaves, wait them to finish +#include + +void +_main(void) +{ + int envID = sys_getenvid(); + char slavesCnt[10]; + readline("Enter the number of Slave Programs: ", slavesCnt); + int numOfSlaves = strtol(slavesCnt, NULL, 10); + + rsttst(); + + //Create and run slave programs that should sleep + int id; + for (int i = 0; i < numOfSlaves; ++i) + { + id = sys_create_env("tstSleepLockSlave", (myEnv->page_WS_max_size),(myEnv->SecondListSize), (myEnv->percentage_of_WS_pages_to_be_removed)); + if (id== E_ENV_CREATION_ERROR) + { + cprintf("\n%~insufficient number of processes in the system! only %d slave processes are created\n", i); + numOfSlaves = i; + break; + } + sys_run_env(id); + } + + //Wait until all slaves, except one, are blocked + int numOfBlockedProcesses = 0; + sys_utilities("__GetLockQueueSize__", (uint32)(&numOfBlockedProcesses)); + int cnt = 0; + while (numOfBlockedProcesses != numOfSlaves-1) + { + env_sleep(5000); + if (cnt == numOfSlaves) + { + panic("%~test sleeplock failed! unexpected number of blocked slaves. Expected = %d, Current = %d", numOfSlaves-1, numOfBlockedProcesses); + } + sys_utilities("__GetLockQueueSize__", (uint32)(&numOfBlockedProcesses)); + cnt++ ; + } + + //signal the slave inside the critical section to leave it + inctst(); + + //Wait until all slave finished + cnt = 0; + while (gettst() != numOfSlaves +1/*since master already increment it by 1*/) + { + env_sleep(5000); + if (cnt == numOfSlaves) + { + panic("%~test sleeplock failed! not all slaves finished. Expected %d, Actual %d", numOfSlaves +1, gettst()); + } + cnt++ ; + } + + cprintf("%~\n\nCongratulations!! Test of Sleep Lock completed successfully!!\n\n"); +} diff --git a/user/tst_sleeplock_slave.c b/user/tst_sleeplock_slave.c new file mode 100644 index 0000000..8cef121 --- /dev/null +++ b/user/tst_sleeplock_slave.c @@ -0,0 +1,39 @@ +// Test the Sleep Lock for applying critical section +// Slave program: acquire, release then increment test to declare finishing +#include + +void +_main(void) +{ + int envID = sys_getenvid(); + + //Acquire the lock + sys_utilities("__AcquireSleepLock__", 0); + { + if (gettst() > 1) + { + //Other slaves: wait for a while + env_sleep(RAND(1000, 5000)); + } + else + { + //this is the first slave inside C.S.! so wait until receiving signal from master + while (gettst() != 1); + } + + //Check lock value inside C.S. + int lockVal = 0; + sys_utilities("__GetLockValue__", (int)(&lockVal)); + if (lockVal != 1) + { + panic("%~test sleeplock failed! lock is not held while it's expected to be"); + } + } + //Release the lock + sys_utilities("__ReleaseSleepLock__", 0); + + //indicates wakenup + inctst(); + + return; +} diff --git a/user/tst_utilities.h b/user/tst_utilities.h index 8738023..568718d 100644 --- a/user/tst_utilities.h +++ b/user/tst_utilities.h @@ -30,4 +30,5 @@ int check_block(void* va, void* expectedVA, uint32 expectedSize, uint8 expectedF return 1; } + #endif /* USER_TST_UTILITIES_H_ */