From 86f6f7257474b4cbf38ec721a0e966b6e5975bb7 Mon Sep 17 00:00:00 2001 From: Santiago Lo Coco Date: Tue, 26 Oct 2021 15:33:06 -0300 Subject: [PATCH] Start the pipes implementation Co-authored-by: Ezequiel Bellver Co-authored-by: Juan Barmasch --- Kernel/include/semaphore.h | 9 ++ Kernel/interruptions/systemCallsDispatcher.c | 8 + Kernel/utils/pipe.c | 111 ++++++++++++++ Kernel/utils/scheduler.c | 133 ++++++++--------- Kernel/utils/semaphore.c | 139 ++++++++++++++---- Userland/SampleCodeModule/_loader.c | 7 +- Userland/SampleCodeModule/asm/libasm.asm | 82 ++++++++--- Userland/SampleCodeModule/include/system.h | 4 + Userland/SampleCodeModule/shell/commands/ps.c | 3 +- .../SampleCodeModule/shell/commands/sem.c | 10 ++ Userland/SampleCodeModule/shell/include/sem.h | 6 + Userland/SampleCodeModule/shell/shell.c | 7 +- 12 files changed, 396 insertions(+), 123 deletions(-) create mode 100644 Kernel/include/semaphore.h create mode 100644 Userland/SampleCodeModule/shell/commands/sem.c create mode 100644 Userland/SampleCodeModule/shell/include/sem.h diff --git a/Kernel/include/semaphore.h b/Kernel/include/semaphore.h new file mode 100644 index 0000000..3031668 --- /dev/null +++ b/Kernel/include/semaphore.h @@ -0,0 +1,9 @@ +#ifndef SEM_H +#define SEM_H + +sem_t * semOpen(char * name, unsigned int value); +int semClose(sem_t * sem); +int semWait(sem_t * sem); +int semPost(sem_t * sem); + +#endif \ No newline at end of file diff --git a/Kernel/interruptions/systemCallsDispatcher.c b/Kernel/interruptions/systemCallsDispatcher.c index 4e18486..d211781 100644 --- a/Kernel/interruptions/systemCallsDispatcher.c +++ b/Kernel/interruptions/systemCallsDispatcher.c @@ -1,5 +1,6 @@ #include #include "systemCalls.h" +#include "memManager.h" void exitProcess(); // void setFn(uint64_t, uint64_t, uint64_t); @@ -26,6 +27,13 @@ uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_ break; case 6: return (uint64_t) processes(); + case 7: + return (uint64_t) getSems(); + case 8: + return pvPortMalloc(rsi); + case 9: + vPortFree(rsi); + break; default: return -1; } diff --git a/Kernel/utils/pipe.c b/Kernel/utils/pipe.c index e69de29..e490902 100644 --- a/Kernel/utils/pipe.c +++ b/Kernel/utils/pipe.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include "lib.h" +#include "scheduler.h" +#include "memManager.h" +#include "semaphore.h" + +#define MAX_SEM 100 +#define MAX_NAME 100 +#define PIPE_MAX_SIZE 1024 +#define SEM_NAME "Pipes" + +typedef struct pipe_t { + char buffer[PIPE_MAX_SIZE]; + int current; + char name[MAX_NAME]; + sem_t * sem; +} pipe_t; + +typedef struct node_t { + pipe_t * pipe; + struct node_t * next; +} node_t; + +node_t * first; + +// char initPipes() { + // if ((sem = semOpen(SEM_NAME)) == NULL) + // return EXIT_FAILURE; + // return EXIT_SUCCESS; +// } + +pipe_t * openPipe(char * name) { + // semWait(sem); + + pipe_t * pipe = pvPortMalloc(sizeof(pipe_t)); + strcpy(pipe->name, name); + if ((pipe->sem = semOpen(SEM_NAME)) == NULL) + return NULL; + + return pipe; + // semPost(sem); +} + +void writePipe(pipe_t * pipe, char c) { + if (!exists(pipe)) + return; + + semWait(pipe->sem); + + pipe->buffer[pipe->current++ % PIPE_MAX_SIZE] = c; + + semPost(pipe->sem); +} + +char readPipe(pipe_t * pipe) { + if (!exists(pipe)) + return -1; + + semWait(pipe->sem); + + char c = pipe->buffer[pipe->current-- % PIPE_MAX_SIZE]; + + semPost(pipe->sem); + + return c; +} + +void closePipe(pipe_t * pipe) { + node_t * prev = NULL; + node_t * del = search(&prev, pipe); + if (del == NULL) + return; + + semWait(pipe->sem); + if (prev != NULL) + prev->next = del->next; + else first->next = del->next; + + vPortFree(pipe); + vPortFree(del); + + semPost(pipe->sem); +} + +int exists(pipe_t * pipe) { + node_t * prev = NULL; + return search(&prev, pipe) != NULL; +} + +node_t * search(node_t ** previous, pipe_t * pipe) { + node_t * curr = first; + * previous = NULL; + while (curr != NULL) { + if (curr->pipe == pipe) { + break; + } + * previous = curr; + curr = curr->next; + } + if (curr == NULL) { + * previous = NULL; + return NULL; + } + if (curr == first) { + * previous = NULL; + return curr; + } + return curr; +} \ No newline at end of file diff --git a/Kernel/utils/scheduler.c b/Kernel/utils/scheduler.c index aa4e655..16a6920 100644 --- a/Kernel/utils/scheduler.c +++ b/Kernel/utils/scheduler.c @@ -1,5 +1,5 @@ #include "scheduler.h" -#define INIT_PID 1 +#define IDLE_PID 1 void _initialize_stack_frame(void *, void *, int, char**); @@ -16,6 +16,7 @@ typedef struct processCDT { char executions; char foreground; enum states state; + int * fd; } processCDT; processCDT * firstReady = NULL; @@ -23,48 +24,27 @@ processCDT * lastReady = NULL; processCDT * firstBlocked = NULL; processCDT * lastBlocked = NULL; -int readyLen = 0; -int blockedLen = 0; - static processCDT * currentProcess = NULL; -static int pids = INIT_PID; +static int pids = IDLE_PID; static char update = 1; -#include "naiveConsole.h" -#include "time.h" - - uint64_t nextProcess() { update = 1; if (currentProcess == NULL) { - // ncClear(); - // ncPrint("Una cubana para el socio biza"); - // ncPrint(firstReady->name); - // // ncPrintDec(firstReady->pid); - // ncPrintHex(firstReady->rsp); - // ncPrintHex(firstReady->rbp); - // wait(4); if (firstReady == NULL) - unblock(INIT_PID); + unblock(IDLE_PID); currentProcess = firstReady; return firstReady->rsp; } if (currentProcess->executions < MAX_PRIORITY - currentProcess->priority + 1) { currentProcess->executions++; - // ncClear(); - // ncPrint("Hola"); - // ncPrintDec(firstReady->pid); - // wait(4); return currentProcess->rsp; } - // ncPrint("Chau"); currentProcess->executions = 0; if (currentProcess->next != NULL) currentProcess = currentProcess->next; else { - // ncPrint("Una colombiana para el socio biza"); - // wait(4); currentProcess = firstReady; } return currentProcess->rsp; @@ -77,7 +57,7 @@ void idle() { } void initScheduler() { - char * argv[] = {"Dummy"}; + char * argv[] = {"Idle"}; enqueueProcess(idle, 0, 1, argv); } @@ -87,8 +67,8 @@ void initScheduler() { // } void enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]) { - if (firstReady != NULL && firstReady->pid == INIT_PID) - block(INIT_PID); + if (firstReady != NULL && firstReady->pid == IDLE_PID) + block(IDLE_PID); processADT process = pvPortMalloc(sizeof(processCDT)); uint64_t * auxi = pvPortMalloc(STACK_SIZE); @@ -279,9 +259,6 @@ char nice(char offset) { void updateRSP(uint64_t newRsp) { if (currentProcess == NULL) { - // ncClear(); - // ncPrint("ES NULL"); - // wait(4); return; } if (update) @@ -311,6 +288,17 @@ char addSpaces(char * str, char qty) { return aux; } +char getGenProcessData(char ** out, char * written, char toAdd, char * in, char isLast) { + char copied = strcpy(*out, in); + *out += copied; + *out += addSpaces(*out, toAdd - copied); + *written += toAdd; + if (!isLast) { + *out += addSpaces(*out, 2); + *written += 2; + } +} + char getProcessData(char * out, processCDT * proc) { if (proc == NULL) return EXIT_FAILURE; @@ -332,44 +320,45 @@ char getProcessData(char * out, processCDT * proc) { written += 2; char buffer[10]; - char copied = strcpy(out, itoa(proc->pid, buffer, 10, 10)); - out += copied; - out += addSpaces(out, MAX_ATTR_SIZE - copied); - written += MAX_ATTR_SIZE - copied; - out += addSpaces(out, 2); - written += copied + 2; - - // buffer = itoa(proc->priority, buffer, 10, 2); - copied = strcpy(out, itoa(proc->priority, buffer, 10, 2)); - out += copied; - out += addSpaces(out, MAX_ATTR_SIZE - copied); - written += MAX_ATTR_SIZE - copied; - out += addSpaces(out, 2); - written += copied + 2; - - copied = strcpy(out, itoa(proc->rsp, buffer, 16, 10)); - out += copied; - out += addSpaces(out, MAX_NAME_SIZE - copied); - written += MAX_NAME_SIZE - copied; - out += addSpaces(out, 2); - written += copied + 2; - - copied = strcpy(out, itoa(proc->rbp, buffer, 16, 10)); - out += copied; - out += addSpaces(out, MAX_NAME_SIZE - copied); - written += MAX_NAME_SIZE - copied; - out += addSpaces(out, 2); - written += copied + 2; - - copied = strcpy(out, (proc->foreground == 1) ? "F" : "B"); - out += copied; - out += addSpaces(out, MAX_ATTR_SIZE - copied); - written += MAX_ATTR_SIZE - copied; - out += addSpaces(out, 2); - written += copied + 2; + getGenProcessData(&out, &written, MAX_ATTR_SIZE, itoa(proc->pid, buffer, 10, 10), 0); + // char copied = strcpy(out, itoa(proc->pid, buffer, 10, 10)); + // out += copied; + // out += addSpaces(out, MAX_ATTR_SIZE - copied); + // written += MAX_ATTR_SIZE; // out += addSpaces(out, 2); - // *out++; - // *out = '\0'; + // written += 2; + + getGenProcessData(&out, &written, MAX_ATTR_SIZE, itoa(proc->priority, buffer, 10, 2), 0); + // copied = strcpy(out, itoa(proc->priority, buffer, 10, 2)); + // out += copied; + // out += addSpaces(out, MAX_ATTR_SIZE - copied); + // written += MAX_ATTR_SIZE; + // out += addSpaces(out, 2); + // written += 2; + + getGenProcessData(&out, &written, MAX_NAME_SIZE, itoa(proc->rsp, buffer, 16, 10), 0); + // copied = strcpy(out, itoa(proc->rsp, buffer, 16, 10)); + // out += copied; + // out += addSpaces(out, MAX_NAME_SIZE - copied); + // written += MAX_NAME_SIZE; + // out += addSpaces(out, 2); + // written += 2; + + getGenProcessData(&out, &written, MAX_NAME_SIZE, itoa(proc->rbp, buffer, 16, 10), 0); + // copied = strcpy(out, itoa(proc->rbp, buffer, 16, 10)); + // out += copied; + // out += addSpaces(out, MAX_NAME_SIZE - copied); + // written += MAX_NAME_SIZE; + // out += addSpaces(out, 2); + // written += 2; + + getGenProcessData(&out, &written, MAX_ATTR_SIZE, (proc->foreground == 1) ? "F" : "B", 1); + // *out++ = (proc->foreground == 1) ? 'F' : 'B'; + // out += addSpaces(out, MAX_ATTR_SIZE - 1); + // written += MAX_ATTR_SIZE; + + // out += addSpaces(out, 2); + // written += 2; return written; } @@ -379,15 +368,15 @@ char * processes(){ char * ret = ans; char * info = "name pid prio rsp rbp fore\n"; - strcpy(ans, info); - ans += 56; + ans += strcpy(ans, info); + // ans += 56; processCDT * aux = firstReady; while (aux != NULL) { char writtenChars = getProcessData(ans, aux); if (writtenChars == EXIT_FAILURE) return NULL; - ans += writtenChars; + ans += writtenChars - 1; *ans++ = '\n'; if (aux == lastBlocked) @@ -397,7 +386,7 @@ char * processes(){ else aux = aux->next; } - *ans = 0; + *--ans = 0; return ret; } @@ -406,7 +395,7 @@ char * processes(){ ● Crear un proceso. DEBERÁ soportar el pasaje de parámetros. LISTO ● Obtener el ID del proceso que llama. LISTO ● Listar todos los procesos: nombre, ID, prioridad, stack y base pointer, foreground y -cualquier otra variable que consideren necesaria. +cualquier otra variable que consideren necesaria. LISTO ● Matar un proceso arbitrario. LISTO ● Modificar la prioridad de un proceso arbitrario. LISTO ● Bloquear y desbloquear un proceso arbitrario. LISTO diff --git a/Kernel/utils/semaphore.c b/Kernel/utils/semaphore.c index 90e6bc4..f15b79b 100644 --- a/Kernel/utils/semaphore.c +++ b/Kernel/utils/semaphore.c @@ -1,51 +1,50 @@ #include #include #include -#include "libc.h" +#include "lib.h" #include "scheduler.h" +#include "memManager.h" #define MAX_SEM 100 #define MAX_NAME 100 +#define SEM_DATA_MAX_SIZE 100 void enter_region(uint32_t * lock); void leave_region(uint32_t * lock); static uint32_t semLock; -typedef struct sem { - unsigned int value; - char name[MAX_NAME]; - // cola FIFO - pid_t * entering; - pid_t * last; -} sem_t; - typedef struct pid_t { int pid; struct pid_t * next; } pid_t; -// Podemos manejarnos con indices. +typedef struct sem_t { + unsigned int value; + char name[MAX_NAME]; + pid_t * entering; + pid_t * last; +} sem_t; + +typedef struct node_t { + sem_t * sem; + struct node_t * next; +} node_t; + static sem_t semaphores[MAX_SEM]; -/* -int semOpen(char * name, unsigned int value) {} +node_t * first = NULL; +static char counter = 0; -// int semClose(char * name) {} -int semClose(char semaphore) {} - -int semInit(char semaphore, unsigned int value) {} - -int semWait(char semaphore) {} - -int semPost(char semaphore) {} -*/ - -// o pasando la estructura de sem. esta es la q hace posix sem_t * semOpen(char * name, unsigned int value) { enter_region(&semLock); sem_t * sem = pvPortMalloc(sizeof(sem_t)); + node_t * node = pvPortMalloc(sizeof(node_t)); + node->sem = sem; + node->next = first; + first = node; strcpy(sem->name, name); sem->value = value; + counter++; leave_region(&semLock); } @@ -56,6 +55,30 @@ int semClose(sem_t * sem) { enter_region(&semLock); + node_t * del = NULL; + + if (first == sem) { + del = first; + first = first->next; + } + else { + node_t * aux = first; + while (aux != NULL) { + if (aux->next != NULL) + if (aux->next->sem == sem) { + del = aux->next; + aux->next = aux->next->next; + break; + } + aux = aux->next; + } + } + + if (del == NULL) { + leave_region(&semLock); + return EXIT_FAILURE; + } + pid_t * pid = sem->entering; while (pid != NULL) { pid_t * aux = pid; @@ -63,7 +86,9 @@ int semClose(sem_t * sem) { vPortFree(aux); } vPortFree(sem); + vPortFree(del); + counter--; leave_region(&semLock); } @@ -98,7 +123,71 @@ int semPost(sem_t * sem) { pid_t * aux = sem->entering; sem->entering = sem->entering->next; unblock(sem->entering->pid); - pvPortFree(aux); + vPortFree(aux); leave_region(&semLock); -} \ No newline at end of file +} + +char getSemaphoresData(char * out, node_t * node) { + if (node == NULL) + return EXIT_FAILURE; + + char written = 0; + + char flag = 0; + for (int j = 0; j < MAX_NAME_SIZE; j++) { + if (!flag && node->sem->name[j] == 0) + flag = 1; + else if (flag) + out += addSpaces(out, 1); + else + *out++ = node->sem->name[j]; + } + written += MAX_NAME_SIZE; + + out += addSpaces(out, 2); + written += 2; + + char buffer[10]; + char copied = strcpy(out, itoa(node->sem->value, buffer, 10, 2)); + out += copied; + out += addSpaces(out, MAX_ATTR_SIZE - copied); + written += MAX_ATTR_SIZE; + out += addSpaces(out, 2); + written += 2; + + pid_t *aux_pid = node->sem->entering; + + while (aux_pid != NULL) { + copied = strcpy(out, itoa(aux_pid->pid, buffer, 10, 10)); + aux_pid = aux_pid->next; + copied += addSpaces(out, 1); + out += copied; + written += copied; + } + return written; +} + +char * getSems() { + char * ans = pvPortMalloc(counter * SEM_DATA_MAX_SIZE); + char * ret = ans; + + char * info = "name value pidsWaiting\n"; + ans += strcpy(ans, info); + // ans += 56; + + node_t * aux = first; + while (aux != NULL) { + char writtenChars = getSemaphoresData(ans, aux); + if (writtenChars == EXIT_FAILURE) + return NULL; + ans += writtenChars - 1; + *ans++ = '\n'; + + aux = aux->next; + + } + *--ans = 0; + + return ret; +} diff --git a/Userland/SampleCodeModule/_loader.c b/Userland/SampleCodeModule/_loader.c index c558fef..8c9752d 100644 --- a/Userland/SampleCodeModule/_loader.c +++ b/Userland/SampleCodeModule/_loader.c @@ -4,16 +4,15 @@ extern char bss; extern char endOfBinary; -int main(); +int main(int argc, char *argv[]); void * memset(void * destiny, int32_t c, uint64_t length); -int _start() { +int _start(int argc, char *argv[]) { //Clean BSS memset(&bss, 0, &endOfBinary - &bss); - return main(); - + return main(argc, argv); } diff --git a/Userland/SampleCodeModule/asm/libasm.asm b/Userland/SampleCodeModule/asm/libasm.asm index 7184d3c..82ee7c0 100644 --- a/Userland/SampleCodeModule/asm/libasm.asm +++ b/Userland/SampleCodeModule/asm/libasm.asm @@ -3,7 +3,7 @@ GLOBAL _getMem, sys_loadProcess GLOBAL raiseOpcodeExc GLOBAL _getRegs, sys_switchContext GLOBAL cpu_id, cpu_id_support -GLOBAL sys_exit, sys_exec, sys_fork, sys_ps +GLOBAL sys_exit, sys_ps, sys_free, sys_malloc, sys_sem section .text @@ -70,50 +70,83 @@ sys_exit: pop rbp ret -sys_fork: +sys_malloc: push rbp mov rbp, rsp push rdi - push rsi - push rdx - mov rdx, rbp - mov rsi, rsp - mov rdi, 3 + mov rdi, 8 int 80h - pop rdx - pop rsi pop rdi mov rsp, rbp pop rbp ret -sys_exec: +sys_free: 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 + mov rdi, 9 int 80h - pop rcx - pop rdx pop rsi pop rdi mov rsp, rbp 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 @@ -130,6 +163,21 @@ sys_ps: pop rbp ret +sys_sem: + push rbp + mov rbp, rsp + + push rdi + + mov rdi, 7 + int 80h + + pop rdi + + mov rsp, rbp + pop rbp + ret + _getMem: push rbp mov rbp, rsp diff --git a/Userland/SampleCodeModule/include/system.h b/Userland/SampleCodeModule/include/system.h index 1ec37ce..0fac742 100644 --- a/Userland/SampleCodeModule/include/system.h +++ b/Userland/SampleCodeModule/include/system.h @@ -6,5 +6,9 @@ int sys_time(char); void sys_write(int, char *, int); char sys_read(int, char *, int); +char * sys_ps(); +char * sys_sem(); +void * sys_malloc(int); +void * sys_free(void *); #endif \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/commands/ps.c b/Userland/SampleCodeModule/shell/commands/ps.c index 21f3553..6e4eb79 100644 --- a/Userland/SampleCodeModule/shell/commands/ps.c +++ b/Userland/SampleCodeModule/shell/commands/ps.c @@ -1,11 +1,10 @@ #include "libc.h" #include "shell.h" -char * sys_ps(); - void ps(char * window, int * offset) { char * output = sys_ps(); addText(output, window, offset); printWindow(window); substractLine(window, offset); + sys_free(output); } \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/commands/sem.c b/Userland/SampleCodeModule/shell/commands/sem.c new file mode 100644 index 0000000..fbdda01 --- /dev/null +++ b/Userland/SampleCodeModule/shell/commands/sem.c @@ -0,0 +1,10 @@ +#include "libc.h" +#include "shell.h" + +void sem(char * window, int * offset) { + char * output = sys_sem(); + addText(output, window, offset); + printWindow(window); + substractLine(window, offset); + sys_free(output); +} \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/include/sem.h b/Userland/SampleCodeModule/shell/include/sem.h new file mode 100644 index 0000000..0f9d5ed --- /dev/null +++ b/Userland/SampleCodeModule/shell/include/sem.h @@ -0,0 +1,6 @@ +#ifndef SEM_LIB +#define SEM_LIB + +void sem(char * window, int * offset); + +#endif \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/shell.c b/Userland/SampleCodeModule/shell/shell.c index c82ed01..85ca57a 100644 --- a/Userland/SampleCodeModule/shell/shell.c +++ b/Userland/SampleCodeModule/shell/shell.c @@ -11,6 +11,7 @@ #include "cpu_id.h" #include "change.h" #include "ps.h" +#include "sem.h" #define SIZE 100 #define MAX_ARGS 5 @@ -18,9 +19,9 @@ #define COLS 80 #define ROWS 25 -const int len = 8; -char *commands_void[] = {"help", "time", "inforeg", "excdiv", "excop", "clear", "cpufeatures", "ps"}; -void (*func []) (char *, int *) = {help, time, inforeg, excdiv, excop, clear, cpufeatures, ps}; +const int len = 9; +char *commands_void[] = {"help", "time", "inforeg", "excdiv", "excop", "clear", "cpufeatures", "ps", "sem"}; +void (*func []) (char *, int *) = {help, time, inforeg, excdiv, excop, clear, cpufeatures, ps, sem}; void substractLine(char * window, int * offset) { for (int i = 0; i < ROWS - 1; i++) {