Start the pipes implementation

Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar>
Co-authored-by: Juan Barmasch <jbarmasch@itba.edu.ar>
This commit is contained in:
Santiago Lo Coco 2021-10-26 15:33:06 -03:00
parent d29d6ced63
commit 86f6f72574
12 changed files with 396 additions and 123 deletions

View File

@ -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

View File

@ -1,5 +1,6 @@
#include <stdint.h> #include <stdint.h>
#include "systemCalls.h" #include "systemCalls.h"
#include "memManager.h"
void exitProcess(); void exitProcess();
// void setFn(uint64_t, uint64_t, uint64_t); // 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; break;
case 6: case 6:
return (uint64_t) processes(); return (uint64_t) processes();
case 7:
return (uint64_t) getSems();
case 8:
return pvPortMalloc(rsi);
case 9:
vPortFree(rsi);
break;
default: default:
return -1; return -1;
} }

View File

@ -0,0 +1,111 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#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;
}

View File

@ -1,5 +1,5 @@
#include "scheduler.h" #include "scheduler.h"
#define INIT_PID 1 #define IDLE_PID 1
void _initialize_stack_frame(void *, void *, int, char**); void _initialize_stack_frame(void *, void *, int, char**);
@ -16,6 +16,7 @@ typedef struct processCDT {
char executions; char executions;
char foreground; char foreground;
enum states state; enum states state;
int * fd;
} processCDT; } processCDT;
processCDT * firstReady = NULL; processCDT * firstReady = NULL;
@ -23,48 +24,27 @@ processCDT * lastReady = NULL;
processCDT * firstBlocked = NULL; processCDT * firstBlocked = NULL;
processCDT * lastBlocked = NULL; processCDT * lastBlocked = NULL;
int readyLen = 0;
int blockedLen = 0;
static processCDT * currentProcess = NULL; static processCDT * currentProcess = NULL;
static int pids = INIT_PID; static int pids = IDLE_PID;
static char update = 1; static char update = 1;
#include "naiveConsole.h"
#include "time.h"
uint64_t nextProcess() { uint64_t nextProcess() {
update = 1; update = 1;
if (currentProcess == NULL) { 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) if (firstReady == NULL)
unblock(INIT_PID); unblock(IDLE_PID);
currentProcess = firstReady; currentProcess = firstReady;
return firstReady->rsp; return firstReady->rsp;
} }
if (currentProcess->executions < MAX_PRIORITY - currentProcess->priority + 1) { if (currentProcess->executions < MAX_PRIORITY - currentProcess->priority + 1) {
currentProcess->executions++; currentProcess->executions++;
// ncClear();
// ncPrint("Hola");
// ncPrintDec(firstReady->pid);
// wait(4);
return currentProcess->rsp; return currentProcess->rsp;
} }
// ncPrint("Chau");
currentProcess->executions = 0; currentProcess->executions = 0;
if (currentProcess->next != NULL) if (currentProcess->next != NULL)
currentProcess = currentProcess->next; currentProcess = currentProcess->next;
else { else {
// ncPrint("Una colombiana para el socio biza");
// wait(4);
currentProcess = firstReady; currentProcess = firstReady;
} }
return currentProcess->rsp; return currentProcess->rsp;
@ -77,7 +57,7 @@ void idle() {
} }
void initScheduler() { void initScheduler() {
char * argv[] = {"Dummy"}; char * argv[] = {"Idle"};
enqueueProcess(idle, 0, 1, argv); enqueueProcess(idle, 0, 1, argv);
} }
@ -87,8 +67,8 @@ void initScheduler() {
// } // }
void enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]) { void enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]) {
if (firstReady != NULL && firstReady->pid == INIT_PID) if (firstReady != NULL && firstReady->pid == IDLE_PID)
block(INIT_PID); block(IDLE_PID);
processADT process = pvPortMalloc(sizeof(processCDT)); processADT process = pvPortMalloc(sizeof(processCDT));
uint64_t * auxi = pvPortMalloc(STACK_SIZE); uint64_t * auxi = pvPortMalloc(STACK_SIZE);
@ -279,9 +259,6 @@ char nice(char offset) {
void updateRSP(uint64_t newRsp) { void updateRSP(uint64_t newRsp) {
if (currentProcess == NULL) { if (currentProcess == NULL) {
// ncClear();
// ncPrint("ES NULL");
// wait(4);
return; return;
} }
if (update) if (update)
@ -311,6 +288,17 @@ char addSpaces(char * str, char qty) {
return aux; 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) { char getProcessData(char * out, processCDT * proc) {
if (proc == NULL) if (proc == NULL)
return EXIT_FAILURE; return EXIT_FAILURE;
@ -332,44 +320,45 @@ char getProcessData(char * out, processCDT * proc) {
written += 2; written += 2;
char buffer[10]; char buffer[10];
char copied = strcpy(out, itoa(proc->pid, buffer, 10, 10)); getGenProcessData(&out, &written, MAX_ATTR_SIZE, itoa(proc->pid, buffer, 10, 10), 0);
out += copied; // char copied = strcpy(out, itoa(proc->pid, buffer, 10, 10));
out += addSpaces(out, MAX_ATTR_SIZE - copied); // out += copied;
written += MAX_ATTR_SIZE - copied; // out += addSpaces(out, MAX_ATTR_SIZE - copied);
out += addSpaces(out, 2); // written += MAX_ATTR_SIZE;
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;
// out += addSpaces(out, 2); // out += addSpaces(out, 2);
// *out++; // written += 2;
// *out = '\0';
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; return written;
} }
@ -379,15 +368,15 @@ char * processes(){
char * ret = ans; char * ret = ans;
char * info = "name pid prio rsp rbp fore\n"; char * info = "name pid prio rsp rbp fore\n";
strcpy(ans, info); ans += strcpy(ans, info);
ans += 56; // ans += 56;
processCDT * aux = firstReady; processCDT * aux = firstReady;
while (aux != NULL) { while (aux != NULL) {
char writtenChars = getProcessData(ans, aux); char writtenChars = getProcessData(ans, aux);
if (writtenChars == EXIT_FAILURE) if (writtenChars == EXIT_FAILURE)
return NULL; return NULL;
ans += writtenChars; ans += writtenChars - 1;
*ans++ = '\n'; *ans++ = '\n';
if (aux == lastBlocked) if (aux == lastBlocked)
@ -397,7 +386,7 @@ char * processes(){
else else
aux = aux->next; aux = aux->next;
} }
*ans = 0; *--ans = 0;
return ret; return ret;
} }
@ -406,7 +395,7 @@ char * processes(){
Crear un proceso. DEBERÁ soportar el pasaje de parámetros. LISTO Crear un proceso. DEBERÁ soportar el pasaje de parámetros. LISTO
Obtener el ID del proceso que llama. LISTO Obtener el ID del proceso que llama. LISTO
Listar todos los procesos: nombre, ID, prioridad, stack y base pointer, foreground y 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 Matar un proceso arbitrario. LISTO
Modificar la prioridad de un proceso arbitrario. LISTO Modificar la prioridad de un proceso arbitrario. LISTO
Bloquear y desbloquear un proceso arbitrario. LISTO Bloquear y desbloquear un proceso arbitrario. LISTO

View File

@ -1,51 +1,50 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include "libc.h" #include "lib.h"
#include "scheduler.h" #include "scheduler.h"
#include "memManager.h"
#define MAX_SEM 100 #define MAX_SEM 100
#define MAX_NAME 100 #define MAX_NAME 100
#define SEM_DATA_MAX_SIZE 100
void enter_region(uint32_t * lock); void enter_region(uint32_t * lock);
void leave_region(uint32_t * lock); void leave_region(uint32_t * lock);
static uint32_t semLock; 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 { typedef struct pid_t {
int pid; int pid;
struct pid_t * next; struct pid_t * next;
} pid_t; } 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]; static sem_t semaphores[MAX_SEM];
/* node_t * first = NULL;
int semOpen(char * name, unsigned int value) {} 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) { sem_t * semOpen(char * name, unsigned int value) {
enter_region(&semLock); enter_region(&semLock);
sem_t * sem = pvPortMalloc(sizeof(sem_t)); 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); strcpy(sem->name, name);
sem->value = value; sem->value = value;
counter++;
leave_region(&semLock); leave_region(&semLock);
} }
@ -56,6 +55,30 @@ int semClose(sem_t * sem) {
enter_region(&semLock); 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; pid_t * pid = sem->entering;
while (pid != NULL) { while (pid != NULL) {
pid_t * aux = pid; pid_t * aux = pid;
@ -63,7 +86,9 @@ int semClose(sem_t * sem) {
vPortFree(aux); vPortFree(aux);
} }
vPortFree(sem); vPortFree(sem);
vPortFree(del);
counter--;
leave_region(&semLock); leave_region(&semLock);
} }
@ -98,7 +123,71 @@ int semPost(sem_t * sem) {
pid_t * aux = sem->entering; pid_t * aux = sem->entering;
sem->entering = sem->entering->next; sem->entering = sem->entering->next;
unblock(sem->entering->pid); unblock(sem->entering->pid);
pvPortFree(aux); vPortFree(aux);
leave_region(&semLock); leave_region(&semLock);
} }
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;
}

View File

@ -4,16 +4,15 @@
extern char bss; extern char bss;
extern char endOfBinary; extern char endOfBinary;
int main(); int main(int argc, char *argv[]);
void * memset(void * destiny, int32_t c, uint64_t length); void * memset(void * destiny, int32_t c, uint64_t length);
int _start() { int _start(int argc, char *argv[]) {
//Clean BSS //Clean BSS
memset(&bss, 0, &endOfBinary - &bss); memset(&bss, 0, &endOfBinary - &bss);
return main(); return main(argc, argv);
} }

View File

@ -3,7 +3,7 @@ GLOBAL _getMem, sys_loadProcess
GLOBAL raiseOpcodeExc GLOBAL raiseOpcodeExc
GLOBAL _getRegs, sys_switchContext GLOBAL _getRegs, sys_switchContext
GLOBAL cpu_id, cpu_id_support 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 section .text
@ -70,50 +70,83 @@ sys_exit:
pop rbp pop rbp
ret ret
sys_fork: sys_malloc:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push rdi push rdi
push rsi
push rdx
mov rdx, rbp mov rdi, 8
mov rsi, rsp
mov rdi, 3
int 80h int 80h
pop rdx
pop rsi
pop rdi pop rdi
mov rsp, rbp mov rsp, rbp
pop rbp pop rbp
ret ret
sys_exec: sys_free:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push rdi push rdi
push rsi push rsi
push rdx
push rcx
mov rcx, rdx
mov rdx, rsi
mov rsi, rdi mov rsi, rdi
mov rdi, 5 mov rdi, 9
int 80h int 80h
pop rcx
pop rdx
pop rsi pop rsi
pop rdi pop rdi
mov rsp, rbp mov rsp, rbp
pop rbp pop rbp
ret 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: sys_ps:
push rbp push rbp
@ -130,6 +163,21 @@ sys_ps:
pop rbp pop rbp
ret ret
sys_sem:
push rbp
mov rbp, rsp
push rdi
mov rdi, 7
int 80h
pop rdi
mov rsp, rbp
pop rbp
ret
_getMem: _getMem:
push rbp push rbp
mov rbp, rsp mov rbp, rsp

View File

@ -6,5 +6,9 @@
int sys_time(char); int sys_time(char);
void sys_write(int, char *, int); void sys_write(int, char *, int);
char sys_read(int, char *, int); char sys_read(int, char *, int);
char * sys_ps();
char * sys_sem();
void * sys_malloc(int);
void * sys_free(void *);
#endif #endif

View File

@ -1,11 +1,10 @@
#include "libc.h" #include "libc.h"
#include "shell.h" #include "shell.h"
char * sys_ps();
void ps(char * window, int * offset) { void ps(char * window, int * offset) {
char * output = sys_ps(); char * output = sys_ps();
addText(output, window, offset); addText(output, window, offset);
printWindow(window); printWindow(window);
substractLine(window, offset); substractLine(window, offset);
sys_free(output);
} }

View File

@ -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);
}

View File

@ -0,0 +1,6 @@
#ifndef SEM_LIB
#define SEM_LIB
void sem(char * window, int * offset);
#endif

View File

@ -11,6 +11,7 @@
#include "cpu_id.h" #include "cpu_id.h"
#include "change.h" #include "change.h"
#include "ps.h" #include "ps.h"
#include "sem.h"
#define SIZE 100 #define SIZE 100
#define MAX_ARGS 5 #define MAX_ARGS 5
@ -18,9 +19,9 @@
#define COLS 80 #define COLS 80
#define ROWS 25 #define ROWS 25
const int len = 8; const int len = 9;
char *commands_void[] = {"help", "time", "inforeg", "excdiv", "excop", "clear", "cpufeatures", "ps"}; char *commands_void[] = {"help", "time", "inforeg", "excdiv", "excop", "clear", "cpufeatures", "ps", "sem"};
void (*func []) (char *, int *) = {help, time, inforeg, excdiv, excop, clear, cpufeatures, ps}; void (*func []) (char *, int *) = {help, time, inforeg, excdiv, excop, clear, cpufeatures, ps, sem};
void substractLine(char * window, int * offset) { void substractLine(char * window, int * offset) {
for (int i = 0; i < ROWS - 1; i++) { for (int i = 0; i < ROWS - 1; i++) {