diff --git a/Kernel/asm/interrupts.asm b/Kernel/asm/interrupts.asm index ba1944e..7d7104b 100755 --- a/Kernel/asm/interrupts.asm +++ b/Kernel/asm/interrupts.asm @@ -287,9 +287,9 @@ _systemCallsHandler: and rsp, -16 sub rsp, 108 fsave [rsp] - and rsp, -16 - sub rsp, 512 - fxsave [rsp] + ; and rsp, -16 + ; sub rsp, 512 + ; fxsave [rsp] push rsi mov rsi, [auxRSI] @@ -304,9 +304,9 @@ _systemCallsHandler: and rsp, -16 sub rsp, 108 frstor [rsp] - and rsp, -16 - sub rsp, 512 - fxrstor [rsp] + ; and rsp, -16 + ; sub rsp, 512 + ; fxrstor [rsp] mov rsp, rax mov rax, [auxRAX] diff --git a/Kernel/drivers/keyboard.c b/Kernel/drivers/keyboard.c index 90d88af..dd5123a 100644 --- a/Kernel/drivers/keyboard.c +++ b/Kernel/drivers/keyboard.c @@ -75,8 +75,8 @@ unsigned char getKeyFromBuffer() { } char aux = *current; - *current++ = 0; - return aux; + *current++ = 0; + return aux; } void keyboard_handler() { diff --git a/Kernel/drivers/time.c b/Kernel/drivers/time.c index 9b85a6c..71a0d48 100755 --- a/Kernel/drivers/time.c +++ b/Kernel/drivers/time.c @@ -34,7 +34,7 @@ int getTime(char option) { } // TODO -void wait(long seconds) { +/* void wait(long seconds) { // int initialSeconds = getTimeGen(SECONDS); // int initialMinutes = getTimeGen(MINUTES); // int runSeconds = 0; @@ -48,7 +48,7 @@ void wait(long seconds) { // } // while (seconds_elapsed() < seconds); -} +} */ static long getTimeFrom2000() { long years = 00 * 31557600; diff --git a/Kernel/include/time.h b/Kernel/include/time.h index 936c2ee..4299a09 100755 --- a/Kernel/include/time.h +++ b/Kernel/include/time.h @@ -14,7 +14,7 @@ int seconds_elapsed(); int getTimeGen(char option); int getTime(char option); -void wait(long seconds); +// void wait(long seconds); long getTimeOfDay(); #endif diff --git a/Kernel/interruptions/systemCalls.c b/Kernel/interruptions/systemCalls.c index d7eeb06..df30591 100644 --- a/Kernel/interruptions/systemCalls.c +++ b/Kernel/interruptions/systemCalls.c @@ -34,6 +34,9 @@ uint64_t read(uint64_t fd, uint64_t buffer, uint64_t length) { char * bufferAux = (char *) buffer; int readBytes = 0; + if (!isForeground()) + return 0; + fd = getFdIn(); if (fd == STDIN) { diff --git a/Kernel/interruptions/systemCallsDispatcher.c b/Kernel/interruptions/systemCallsDispatcher.c index 1778a4c..49a7619 100644 --- a/Kernel/interruptions/systemCallsDispatcher.c +++ b/Kernel/interruptions/systemCallsDispatcher.c @@ -61,6 +61,8 @@ uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_ return block(rsi); case 20: return unblock(rsi); + case 21: + return wait(); default: return -1; } diff --git a/Kernel/utils/scheduler.c b/Kernel/utils/scheduler.c index b2e7a0c..7385f8a 100644 --- a/Kernel/utils/scheduler.c +++ b/Kernel/utils/scheduler.c @@ -5,7 +5,7 @@ // void _initialize_stack_frame(void *, void *, int, char**, void *, void *); uint64_t _initialize_stack_frame(void *, void *, int, char**); -enum states {READY = 0, DEAD, BLOCKED}; +enum states {READY = 0, DEAD, BLOCKED, BBCHILDREN, WAITING}; typedef struct processCDT { struct processCDT * next; @@ -19,6 +19,8 @@ typedef struct processCDT { char foreground; enum states state; int * fd; + int children; + char backWait; } processCDT; typedef struct sleepCDT { @@ -39,10 +41,6 @@ static int pids = IDLE_PID; static char update = 1; static char idleFlag = 2; -void debug() { - return; -} - void removeProcess(processCDT * del, processCDT * prev, processCDT ** first, processCDT ** last) { if (prev == NULL) { *first = del->next; @@ -60,9 +58,13 @@ uint64_t nextProcess(uint64_t currentRSP) { if (currentProcess != NULL /*&& currentProcess->state != BLOCKED*/) currentProcess->rsp = currentRSP; processCDT * prev = currentProcess; - if (currentProcess != NULL) - currentProcess = currentProcess->next; - while (currentProcess == NULL || currentProcess->state == BLOCKED || currentProcess->state == DEAD) { + // if (currentProcess != NULL) + // currentProcess = currentProcess->next; + if (currentProcess != NULL && currentProcess->state == READY && currentProcess->executions == MAX_PRIORITY - currentProcess->priority + 1) { + currentProcess->executions = 0; + currentProcess = currentProcess->next; + } + while (currentProcess == NULL || currentProcess->state == BLOCKED || currentProcess->state == DEAD || currentProcess->state == WAITING) { if (currentProcess == NULL) { currentProcess = firstProcess; } @@ -73,26 +75,21 @@ uint64_t nextProcess(uint64_t currentRSP) { currentProcess = currentProcess->next; } else if (currentProcess->state == DEAD) { - debug(); processCDT * del = currentProcess; currentProcess = currentProcess->next; removeProcess(del, prev, &firstProcess, &lastProcess); vPortFree((void *) del); } - else if (currentProcess->state == BLOCKED) { + else if (currentProcess->state == BLOCKED || currentProcess->state == WAITING) { if (firstBlockedIteration == NULL) firstBlockedIteration = currentProcess; prev = currentProcess; currentProcess = currentProcess->next; } - else if (currentProcess->state == READY && currentProcess->executions == MAX_PRIORITY - currentProcess->priority + 1) { - currentProcess->executions = 0; - prev = currentProcess; - currentProcess = currentProcess->next; - } } - if (currentProcess->pid != IDLE_PID) + if (currentProcess->pid != IDLE_PID) { block(IDLE_PID); + } firstBlockedIteration = NULL; currentProcess->executions++; return currentProcess->rsp; @@ -119,6 +116,14 @@ int enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *a if (!idleFlag) block(IDLE_PID); + if (currentProcess != NULL) { + currentProcess->children++; + if (currentProcess->foreground && foreground) { + currentProcess->foreground = 0; + currentProcess->backWait = 1; + } + } + processADT process = pvPortMalloc(sizeof(processCDT)); uint64_t * auxi = pvPortMalloc(STACK_SIZE); uint64_t * rbp = STACK_SIZE + auxi; @@ -126,7 +131,6 @@ int enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *a char priority = (foreground == 1) ? DEF_PRIORITY : MAX_PRIORITY/2; - // char aux[MAX_NAME_SIZE]; char * aux = pvPortMalloc(10); int j; for (j = 0; j < MAX_NAME_SIZE - 1 && argv[0][j] != 0; j++) { @@ -145,6 +149,8 @@ int enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *a process->state = READY; process->fd = fd; process->next = NULL; + process->children = 0; + process->backWait = 0; process->rsp = _initialize_stack_frame(fn, rbp, argc, argv); // _initialize_stack_frame(fn, rbp, argc, argv); @@ -197,19 +203,6 @@ void checkSleeping() { } } -// void * getSSEaddress() { -// // return currentProcess->sseBytes; -// return currentProcess->bytes->s.sseBytes; -// } - -// void * getFPUaddress() { -// // return currentProcess->fpuBytes; -// return currentProcess->bytes->s.fpuBytes; -// } - -void newProcess(processADT process, char * name, char priority, char foreground, uint64_t rsp, uint64_t rbp) { -} - processADT searchProcess(processADT * previous, int pid, processADT first) { processADT curr = first; * previous = NULL; @@ -230,176 +223,61 @@ processADT searchProcess(processADT * previous, int pid, processADT first) { char block(int pid) { processADT prev = NULL; processADT del = searchProcess(&prev, pid, firstProcess); - if (del == NULL) + if (del == NULL || del->state == DEAD) return EXIT_FAILURE; else { - // removeProcess(del, prev, &firstReady, &lastReady); del->state = BLOCKED; - //blockProcess(del, prev); -// if (prev != NULL) { -// prev->next = del->next; -// if (lastReady == del) -// lastReady = prev; -// } -// else { -// firstReady = del->next; -// if (del == lastReady) -// lastReady = NULL; -// } } - // processCDT * next = del->next; - // del->next = NULL; - - // del->state = BLOCKED; - // if (lastBlocked != NULL) - // lastBlocked->next = del; - // else - // firstBlocked = del; - // lastBlocked = del; - - // processCDT * auxCurr = pvPortMalloc(sizeof(processCDT)); - // auxCurr->next = next; - // auxCurr->pid = pid; - // currentProcess->state = BLOCKED; - if (pid == currentProcess->pid) { - // update = 0; - // currentProcess = next; - forceTimer(); } return EXIT_SUCCESS; } -// void debug() { -// return; -// } - char unblock(int pid) { processADT prev = NULL; processADT del = searchProcess(&prev, pid, firstProcess); - if (del == NULL) { - // debug(); + if (del == NULL || del->state == DEAD) { return EXIT_FAILURE; } else { - // removeProcess(del, prev, &firstBlocked, &lastBlocked); del->state = READY; -// if (prev != NULL) { -// prev->next = del->next; -// if (del == lastBlocked) -// lastBlocked = prev; -// } -// else { -// firstBlocked = del->next; -// if (lastBlocked == del) -// lastBlocked = NULL; -// } } - - // del->next = NULL; - // if (lastReady != NULL) - // lastReady->next = del; - // else - // firstReady = del; - // lastReady = del; -// - // del->state = READY; - // if (firstReady != NULL && firstReady->pid == IDLE_PID && lastReady->pid != IDLE_PID) if (idleFlag && !(--idleFlag)) block(IDLE_PID); return EXIT_SUCCESS; } -/* -char unblockFirst(int pid) { - processADT prev = NULL; - processADT del = searchProcess(&prev, pid, firstBlocked); - if (del == NULL) - return EXIT_FAILURE; - else { - // removeProcess(del, prev, &firstBlocked, &lastBlocked); - -// if (prev != NULL) { -// prev->next = del->next; -// if (lastBlocked == del) -// lastBlocked = prev; -// } -// else { -// firstBlocked = del->next; -// if (lastBlocked == del) -// lastBlocked = NULL; -// } - } - - if (currentProcess != NULL) { - del->next = currentProcess->next; - currentProcess->next = del; - if (lastReady == currentProcess) - lastReady = del; - } - else { - if (firstReady != NULL) - del->next = firstReady->next; - else del->next = NULL; - firstReady = del; - if (lastReady == NULL) - lastReady = del; - } - - del->state = READY; - - // if (firstReady != NULL && lastReady->pid == IDLE_PID && firstReady->pid != IDLE_PID) - if (idleFlag && !(--idleFlag)) - block(IDLE_PID); - - return EXIT_SUCCESS; +void debug() { + return; } -*/ char kill(int pid) { processADT prev = NULL; processADT del = searchProcess(&prev, pid, firstProcess); if (del == NULL) { - // del = searchProcess(&prev, pid, firstBlocked); - // if (del == NULL) - return EXIT_FAILURE; - // else { - // removeProcess(del, prev, &firstBlocked, &lastBlocked); - // // if (prev != NULL) { - // // prev->next = del->next; - // // if (del == lastBlocked) - // // lastBlocked = prev; - // // } - // // else - // // firstBlocked = del->next; - // } + return EXIT_FAILURE; } - // else { - // removeProcess(del, prev, &firstReady, &lastReady); - // if (prev != NULL) { - // prev->next = del->next; - // if (del == lastReady) - // lastReady = prev; - // } - // else - // firstReady = del->next; - // } - - // processCDT * next = del->next; + processADT parent = searchProcess(&prev, del->ppid, firstProcess); + parent->children--; + if (!parent->children && parent->state == WAITING) { + debug(); + parent->state = READY; + } + if (del->foreground) + if (parent->backWait) { + parent->backWait = 0; + parent->foreground = 1; + } vPortFree(del->fd); vPortFree((void *) del->rbp - STACK_SIZE); - currentProcess->state = DEAD; + del->state = DEAD; if (pid == currentProcess->pid) { - // if (pid < 9) - // update = 0; - // currentProcess = next; - forceTimer(); } @@ -429,11 +307,7 @@ char nice(int pid, char offset) { processADT prev = NULL; processADT del = searchProcess(&prev, pid, firstProcess); if (del == NULL) { - // del = searchProcess(&prev, pid, firstBlocked); - // if (del == NULL) - return EXIT_FAILURE; - // else - // del->priority = offset + 20; + return EXIT_FAILURE; } else { del->priority = offset + 20; @@ -441,6 +315,13 @@ char nice(int pid, char offset) { return EXIT_SUCCESS; } +void wait() { + if (currentProcess != NULL && currentProcess->children != 0) { + currentProcess->state = WAITING; + forceTimer(); + } +} + char updateRSP(uint64_t newRsp) { if (currentProcess == NULL) { return -1; @@ -465,6 +346,12 @@ char quitCPU() { return EXIT_SUCCESS; } +char isForeground() { + if (currentProcess == NULL) + return -1; + return currentProcess->foreground; +} + void getGenProcessData(char ** out, char * written, char toAdd, char * in, char isLast) { char copied = strcpy(*out, in); *out += copied; @@ -511,7 +398,7 @@ char * processes(){ char * ans = pvPortMalloc(pids * PROCESS_DATA_MAX_SIZE); char * ret = ans; - char * info = "name pid prio rsp rbp fore state\n"; + char * info = "name pid prio rsp rbp fore state\n"; ans += strcpy(ans, info); // ans += 56; diff --git a/Kernel/utils/sem.c b/Kernel/utils/sem.c index ee445a9..918f455 100644 --- a/Kernel/utils/sem.c +++ b/Kernel/utils/sem.c @@ -75,6 +75,13 @@ char semClose(sem_t * sem) { return EXIT_SUCCESS; } +void debug2() { + return; +} +void debug3() { + return; +} + void semWait(sem_t * sem) { enter_region(&semLock); @@ -83,6 +90,7 @@ void semWait(sem_t * sem) { } else { leave_region(&semLock); + debug2(); pid_t * curr = pvPortMalloc(sizeof(pid_t)); curr->pid = getPid(); @@ -107,9 +115,12 @@ void semPost(sem_t * sem) { sem->value++; if (sem->entering != NULL) { + debug3(); pid_t * aux = sem->entering; sem->entering = sem->entering->next; - unblock(sem->entering->pid); + if (sem->entering == NULL) + sem->last = NULL; + unblock(aux->pid); vPortFree(aux); } diff --git a/Userland/SampleCodeModule/asm/libasm.asm b/Userland/SampleCodeModule/asm/libasm.asm index dda0ecd..46cdcda 100644 --- a/Userland/SampleCodeModule/asm/libasm.asm +++ b/Userland/SampleCodeModule/asm/libasm.asm @@ -4,7 +4,8 @@ GLOBAL raiseOpcodeExc GLOBAL _getRegs, sys_switchContext GLOBAL cpu_id, cpu_id_support GLOBAL sys_exit, sys_ps, sys_free, sys_malloc, sys_sem, sys_openPipe, sys_semClose -GLOBAL sys_nice, sys_semWait, sys_semPost, sys_semOpen, sys_sleep, sys_kill, sys_getPid, sys_block, sys_unblock +GLOBAL sys_nice, sys_semWait, sys_semPost, sys_semOpen, sys_sleep, sys_kill, sys_getPid, +GLOBAL sys_block, sys_unblock, sys_wait section .text @@ -166,51 +167,6 @@ sys_free: pop rbp ret -; sys_fork: -; push rbp -; mov rbp, rsp - -; push rdi -; push rsi -; push rdx - -; mov rdx, rbp -; mov rsi, rsp -; mov rdi, 3 -; int 80h - -; pop rdx -; pop rsi -; pop rdi - -; mov rsp, rbp -; pop rbp -; ret - -; sys_exec: -; push rbp -; mov rbp, rsp - -; push rdi -; push rsi -; push rdx -; push rcx - -; mov rcx, rdx -; mov rdx, rsi -; mov rsi, rdi -; mov rdi, 5 -; int 80h - -; pop rcx -; pop rdx -; pop rsi -; pop rdi - -; mov rsp, rbp -; pop rbp -; ret - sys_ps: push rbp mov rbp, rsp @@ -256,6 +212,21 @@ sys_getPid: pop rbp ret +sys_wait: + push rbp + mov rbp, rsp + + push rdi + + mov rdi, 21 + int 80h + + pop rdi + + mov rsp, rbp + pop rbp + ret + sys_nice: push rbp mov rbp, rsp diff --git a/Userland/SampleCodeModule/bottler/bottler.c b/Userland/SampleCodeModule/bottler/bottler.c index c636651..d807b1e 100644 --- a/Userland/SampleCodeModule/bottler/bottler.c +++ b/Userland/SampleCodeModule/bottler/bottler.c @@ -34,7 +34,7 @@ void bottler(int argc, char ** argv) { printStringLen( " %%%%%%%%%%%%% ", 80); new_line(); printStringLen( " %%%%%%% ", 80); new_line(); printStringLen( " ", 80); new_line(); - sys_sleep(3); + // sys_sleep(3); winClear(); sys_exit(); diff --git a/Userland/SampleCodeModule/sampleCodeModule.c b/Userland/SampleCodeModule/sampleCodeModule.c index 20210d8..ad88b9f 100644 --- a/Userland/SampleCodeModule/sampleCodeModule.c +++ b/Userland/SampleCodeModule/sampleCodeModule.c @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) { char * argv1[] = {"bottler"}; sys_loadProcess(bottler, 1, 1, argv1, NULL); - sys_sleep(4); + // sys_sleep(4); // winClear(); char * argv2[] = {"shell"}; diff --git a/Userland/SampleCodeModule/shell/commands/phylo.c b/Userland/SampleCodeModule/shell/commands/phylo.c index b9870a8..c9bc3d6 100644 --- a/Userland/SampleCodeModule/shell/commands/phylo.c +++ b/Userland/SampleCodeModule/shell/commands/phylo.c @@ -6,21 +6,7 @@ #define BUFF_SIZE 20 #define MAX_PHILO_SIZE 3 #define MAX_NAME_SIZE 10 -#define STARTING 2 - -// typedef uint64_t sem_t; -// typedef struct pid_t { -// int pid; -// struct pid_t * next; -// } pid_t; - -// typedef struct sem_t { -// unsigned int value; -// // char name[MAX_NAME]; -// char * name; -// pid_t * entering; -// pid_t * last; -// } sem_t; +#define STARTING 5 int * state; typedef enum states {EATING = 0, HUNGRY, THINKING} states; @@ -58,9 +44,6 @@ void test(philosopher_t * phil) { if (phil->state == HUNGRY && phil->left->state != EATING && phil->right->state != EATING) { phil->state = EATING; - - // sys_sleep(2); - sys_semPost(phil->sem); } } @@ -70,14 +53,17 @@ void philosopher(int argc, char ** argv); void addPhilo() { philoCount++; - philosopher_t * new = sys_malloc(sizeof(philosopher_t *)); + philosopher_t * new = sys_malloc(sizeof(philosopher_t)); new->argv = sys_malloc(sizeof(char *) * ARGV_SIZE); - new->buffer = sys_malloc(sizeof(char ) * BUFF_SIZE); + new->buffer = sys_malloc(sizeof(char) * BUFF_SIZE); new->state = THINKING; new->sem = sys_semOpen("filosofo", 0); new->argv[0] = "filosofo"; - new->argv[1] = itoa((uint64_t) new, new->argv[1], 10); + // new->argv[1] = itoa((uint64_t) new, new->argv[1], 10); + // strcpy(phil->buffer, itoa((uint64_t) phil, phil->buffer, 10)); + strcpy(new->buffer, itoa((uint64_t) new, new->buffer, 10)); + new->argv[1] = new->buffer; new->left = firstPhil->left; new->right = firstPhil; @@ -85,7 +71,7 @@ void addPhilo() { firstPhil->left->right = new; firstPhil->left = new; - new->pid = sys_loadProcess(philosopher, 1, 2, new->argv, NULL); + new->pid = sys_loadProcess(philosopher, 0, 2, new->argv, NULL); } void removePhilo() { @@ -138,14 +124,16 @@ void philosopher(int argc, char ** argv) while (1) { // sys_sleep(1); + sys_sleep(1); take_fork(i); - // printState(); + printState(); - // sys_sleep(1); + sys_sleep(1); + // sys_sleep(2); put_fork(i); - // printState(); + printState(); } sys_exit(); } @@ -197,38 +185,54 @@ void phylo(int argc, char ** argv) { philosopher_t * phil = firstPhil; do { - phil->pid = sys_loadProcess(philosopher, 1, 2, phil->argv, NULL); + phil->pid = sys_loadProcess(philosopher, 0, 2, phil->argv, NULL); phil = phil->right; } while (phil != firstPhil); - //char c; - //while (1) { - // while ((c = getChar()) != 0 && c != -1) { - // if (c == 'a') { - // addPhilo(); - // } - // else if (c == 'r') { - // removePhilo(); - // } - // else if (c == 'q') { - // break; - // } - // } - //} - - //phil = firstPhil; - //do { - // sys_semClose(phil); - // sys_free(phil); - // sys_free(phil); - // sys_free(phil); - // sys_kill(phil->pid); - // phil = phil->right; - //} while (phil != firstPhil); // PROBLEMA - + char c; + while (1) { + while ((c = getChar()) != 0 && c != -1) { + if (c == 'a') { + addPhilo(); + } + else if (c == 'r') { + removePhilo(); + } + else if (c == 'q') { + end(); + } + } + } sys_exit(); } +#include "ps.h" + +void freePhilo(philosopher_t * phil) { + sys_semClose(phil->sem); + sys_free(phil); + sys_free(phil->buffer); + sys_free(phil->argv); + sys_kill(phil->pid); +} + +void end() { + sys_semWait(mutex); + philosopher_t * phil = firstPhil->right; + do { + freePhilo(phil); + phil = phil->right; + } while (phil != firstPhil); + + + freePhilo(firstPhil); + sys_semPost(mutex); + + sys_semClose(mutex); + sys_exit(); +} + + // La primera es muy similar a: @@ -236,4 +240,4 @@ void phylo(int argc, char ** argv) { * Taken from "Operating Systems - Design and Implementation" by Tanenbaum * Section 2.3, page 91, Figure 2-10 * https://gist.github.com/codelance/4186161 -*/ \ No newline at end of file +*/ diff --git a/Userland/SampleCodeModule/shell/shell.c b/Userland/SampleCodeModule/shell/shell.c index 1d3cc20..9295d2c 100644 --- a/Userland/SampleCodeModule/shell/shell.c +++ b/Userland/SampleCodeModule/shell/shell.c @@ -152,6 +152,7 @@ void processInput(char * input) { sys_loadProcess(commands[comm1].func, 1, end - pipe - 1, argv1, fd2); } else sys_loadProcess(commands[comm0].func, 1, end, argv0, fd1); + sys_wait(); } if (!comm_flag0) {