Finish implementing pipes

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-27 22:15:13 -03:00
parent 6c805191d0
commit 42139b44eb
20 changed files with 288 additions and 118 deletions

View File

@ -170,6 +170,13 @@ picSlaveMask:
;8254 Timer (Timer Tick)
_irq00Handler:
pushState
; mov rsi, rsp
; and rsp, -16
; sub rsp, 108
; fsave [rsp]
; push rsi
; push rax
; call getFPUaddress
; fsave [rax]
@ -199,6 +206,14 @@ _irq00Handler:
; call getSSEaddress
; fxrstor [rax]
; pop rax
; mov rax, rsp
; pop rsp
; and rsp, -16
; sub rsp, 108
; frstor [rsp]
; mov rsp, rax
popState
iretq
@ -284,6 +299,13 @@ _initialize_stack_frame:
mov rdi, rdx
pushState
; mov rsi, rsp
; and rsp, -16
; sub rsp, 108
; fsave [rsp]
; push rsi
; fsave [bytesForFPU]
; push rax
; mov dword [auxi], 1

View File

@ -8,9 +8,10 @@
typedef struct pipe_t {
int fd[2];
char buffer[PIPE_MAX_SIZE];
int current;
char name[MAX_NAME];
char * buffer;
int currentR;
int currentW;
char * name;
sem_t * sem;
} pipe_t;

View File

@ -9,7 +9,7 @@ char block(int pid);
char unblock(int pid);
char kill(int pid);
void exitProcess();
char nice(char offset);
char nice(int pid, char offset);
int getPid();
char quitCPU();
char * processes();

View File

@ -10,14 +10,15 @@ typedef struct pid_t {
typedef struct sem_t {
unsigned int value;
char name[MAX_NAME];
// char name[MAX_NAME];
char * name;
pid_t * entering;
pid_t * last;
} sem_t;
sem_t * semOpen(char * name, unsigned int value);
int semClose(sem_t * sem);
int semWait(sem_t * sem);
int semPost(sem_t * sem);
char semClose(sem_t * sem);
void semWait(sem_t * sem);
void semPost(sem_t * sem);
#endif

View File

@ -21,8 +21,8 @@ uint64_t write(uint64_t fd, uint64_t buffer, uint64_t length) {
if (fd != STDOUT) {
int i = 0;
while (bufferAux[i] != '\0' && i++ <= length) {
writePipe(fd, bufferAux[i]);
while (bufferAux[i] != '\0' && i <= length) {
writePipe(fd, bufferAux[i++]);
}
return i;
}
@ -46,8 +46,13 @@ uint64_t read(uint64_t fd, uint64_t buffer, uint64_t length) {
}
}
else {
fd = getFdIn();
readBytes += strcpy(buffer, readPipe(fd));
while (length-- > 0) {
*bufferAux = readPipe(fd);
if (*bufferAux == 0)
break;
bufferAux++;
readBytes++;
}
}
return readBytes;

View File

@ -7,6 +7,7 @@ void exitProcess();
char * processes();
void enqueueProcess(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
char openPipe(int *, char *);
char nice(int, char);
uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9) {
switch (rdi) {
@ -31,12 +32,14 @@ uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_
case 7:
return (uint64_t) getSems();
case 8:
return pvPortMalloc(rsi);
return pvPortMalloc((void *) rsi);
case 9:
vPortFree(rsi);
vPortFree((void *) rsi);
break;
case 10:
return (uint64_t) openPipe(rsi, rdx);
case 11:
return nice(rsi, rdx);
default:
return -1;
}

View File

@ -1,42 +1,102 @@
#include "pipe.h"
int fds = 2;
static int fdIndex = 2;
node_t * firstPipe;
char openPipe(int fds[2] ,char * name) {
char openPipe(int fds[2], char * name) {
pipe_t * pipe = pvPortMalloc(sizeof(pipe_t));
pipe->name = pvPortMalloc(MAX_NAME);
pipe->buffer = pvPortMalloc(PIPE_MAX_SIZE);
strcpy(pipe->name, name);
if ((pipe->sem = semOpen(SEM_NAME, 1)) == NULL)
return EXIT_FAILURE;
pipe->fd[0] = fds++;
pipe->fd[1] = fds++;
node_t * node = pvPortMalloc(sizeof(node_t));
node->pipe = pipe;
node->next = firstPipe;
firstPipe = node;
pipe->currentR = 0;
pipe->currentW = 0;
pipe->fd[0] = fdIndex++;
pipe->fd[1] = fdIndex++;
fds[0] = pipe->fd[0];
fds[1] = pipe->fd[1];
return EXIT_SUCCESS;
}
node_t * searchPipe(node_t ** previous, int fd) {
node_t * curr = firstPipe;
* previous = NULL;
while (curr != NULL) {
if (curr->pipe->fd[0] == fd || curr->pipe->fd[1] == fd) {
break;
}
* previous = curr;
curr = curr->next;
}
if (curr == NULL) {
* previous = NULL;
return NULL;
}
return curr;
}
node_t * searchWPipe(node_t ** previous, int fd) {
node_t * curr = firstPipe;
* previous = NULL;
while (curr != NULL) {
if (curr->pipe->fd[1] == fd) {
break;
}
* previous = curr;
curr = curr->next;
}
if (curr == NULL) {
* previous = NULL;
return NULL;
}
return curr;
}
node_t * searchRPipe(node_t ** previous, int fd) {
node_t * curr = firstPipe;
* previous = NULL;
while (curr != NULL) {
if (curr->pipe->fd[0] == fd) {
break;
}
* previous = curr;
curr = curr->next;
}
if (curr == NULL) {
* previous = NULL;
return NULL;
}
return curr;
}
void writePipe(int fd, char c) {
node_t * prev = NULL;
node_t * node = searchPipe(&prev, fd);
node_t * node = searchWPipe(&prev, fd);
semWait(node->pipe->sem);
node->pipe->buffer[node->pipe->current++ % PIPE_MAX_SIZE] = c;
node->pipe->buffer[node->pipe->currentW++ % PIPE_MAX_SIZE] = c;
semPost(node->pipe->sem);
}
char readPipe(int fd) {
node_t * prev = NULL;
node_t * node = searchPipe(&prev, fd);
node_t * node = searchRPipe(&prev, fd);
semWait(node->pipe->sem);
char c = node->pipe->buffer[node->pipe->current-- % PIPE_MAX_SIZE];
char c = node->pipe->buffer[node->pipe->currentR++ % PIPE_MAX_SIZE];
semPost(node->pipe->sem);
@ -54,25 +114,10 @@ void closePipe(int fd) {
prev->next = del->next;
else firstPipe = del->next;
semClose(del->pipe->sem);
vPortFree(del->pipe->fd);
vPortFree(del->pipe->name);
vPortFree(del->pipe->buffer);
vPortFree(del->pipe);
vPortFree(del);
semPost(del->pipe->sem);
}
node_t * searchPipe(node_t ** previous, int fd) {
node_t * curr = firstPipe;
* previous = NULL;
while (curr != NULL) {
if (curr->pipe->fd == fd) {
break;
}
* previous = curr;
curr = curr->next;
}
if (curr == NULL) {
* previous = NULL;
return NULL;
}
return curr;
}

View File

@ -22,6 +22,27 @@ typedef struct processCDT {
// void * fpuBytes;
} processCDT;
// typedef long Align;
// typedef union processCDT {
// struct {
// struct p * next;
// char * name;
// int pid;
// int ppid;
// uint64_t rsp;
// uint64_t rbp;
// char priority;
// char executions;
// char foreground;
// enum states state;
// int * fd;
// void * sseBytes;
// void * fpuBytes;
// } p;
// Align x;
// } processCDT;
processCDT * firstReady = NULL;
processCDT * lastReady = NULL;
processCDT * firstBlocked = NULL;
@ -72,7 +93,7 @@ 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[], int * fd) {
if (fd == NULL) {
int * aux = pvPortMalloc(2);
int * aux = pvPortMalloc(2 * sizeof(int));
aux[0] = 0;
aux[1] = 1;
fd = aux;
@ -105,6 +126,7 @@ void enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *
process->foreground = foreground;
process->state = READY;
process->fd = fd;
process->next = NULL;
// process->sseBytes = pvPortMalloc(64);
// process->fpuBytes = pvPortMalloc(14);
@ -207,21 +229,28 @@ char kill(int pid) {
if (del == NULL)
return EXIT_FAILURE;
else {
if (prev != NULL)
if (prev != NULL) {
prev->next = del->next;
if (del == lastBlocked)
lastBlocked = prev;
}
else
firstBlocked = del->next;
}
}
else {
if (prev != NULL)
if (prev != NULL) {
prev->next = del->next;
if (del == lastReady)
lastReady = prev;
}
else
firstReady = del->next;
}
processCDT * next = del->next;
vPortFree(del->fd);
vPortFree((void *) del->rbp - STACK_SIZE);
vPortFree((void *) del);
@ -250,10 +279,22 @@ void exitProcess() {
kill(currentProcess->pid);
}
char nice(char offset) {
if (currentProcess == NULL)
char nice(int pid, char offset) {
if (offset >= 20 || offset < -20)
return EXIT_FAILURE;
currentProcess->priority += offset;
processADT prev = NULL;
processADT del = searchProcess(&prev, pid, firstReady);
if (del == NULL) {
del = searchProcess(&prev, pid, firstBlocked);
if (del == NULL)
return EXIT_FAILURE;
else
del->priority = offset + 20;
}
else {
del->priority = offset + 20;
}
return EXIT_SUCCESS;
}
@ -280,7 +321,7 @@ char quitCPU() {
return EXIT_SUCCESS;
}
char getGenProcessData(char ** out, char * written, char toAdd, char * in, char isLast) {
void getGenProcessData(char ** out, char * written, char toAdd, char * in, char isLast) {
char copied = strcpy(*out, in);
*out += copied;
*out += addSpaces(*out, toAdd - copied);
@ -313,44 +354,10 @@ char getProcessData(char * out, processCDT * proc) {
char buffer[10];
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);
// 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;
}
@ -381,15 +388,4 @@ char * processes(){
*--ans = 0;
return ret;
}
/*
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. LISTO
Matar un proceso arbitrario. LISTO
Modificar la prioridad de un proceso arbitrario. LISTO
Bloquear y desbloquear un proceso arbitrario. LISTO
Renunciar al CPU. LISTO
*/
}

View File

@ -7,7 +7,7 @@ typedef struct node_t {
struct node_t * next;
} node_t;
static sem_t semaphores[MAX_SEM];
// static sem_t semaphores[MAX_SEM];
node_t * firstSem = NULL;
static char counter = 0;
@ -19,14 +19,17 @@ sem_t * semOpen(char * name, unsigned int value) {
node->sem = sem;
node->next = firstSem;
firstSem = node;
sem->name = pvPortMalloc(MAX_NAME);
strcpy(sem->name, name);
sem->value = value;
counter++;
leave_region(&semLock);
return sem;
}
int semClose(sem_t * sem) {
char semClose(sem_t * sem) {
if (sem == NULL)
return EXIT_FAILURE;
@ -34,7 +37,7 @@ int semClose(sem_t * sem) {
node_t * del = NULL;
if (firstSem == sem) {
if (firstSem->sem == sem) {
del = firstSem;
firstSem = firstSem->next;
}
@ -62,14 +65,17 @@ int semClose(sem_t * sem) {
pid = pid->next;
vPortFree(aux);
}
vPortFree(sem->name);
vPortFree(sem);
vPortFree(del);
counter--;
leave_region(&semLock);
return EXIT_SUCCESS;
}
int semWait(sem_t * sem) {
void semWait(sem_t * sem) {
enter_region(&semLock);
if (sem->value > 0) {
@ -81,7 +87,10 @@ int semWait(sem_t * sem) {
pid_t * curr = pvPortMalloc(sizeof(pid_t));
curr->pid = getPid();
curr->next = NULL;
sem->last->next = curr;
if (sem->entering == NULL)
sem->entering = curr;
if (sem->last != NULL)
sem->last->next = curr;
sem->last = curr;
block(curr->pid);
@ -92,7 +101,7 @@ int semWait(sem_t * sem) {
leave_region(&semLock);
}
int semPost(sem_t * sem) {
void semPost(sem_t * sem) {
enter_region(&semLock);
sem->value++;
@ -151,7 +160,6 @@ char * getSems() {
char * info = "name value pidsWaiting\n";
ans += strcpy(ans, info);
// ans += 56;
node_t * aux = firstSem;
while (aux != NULL) {

View File

@ -3,7 +3,7 @@ GLOBAL _getMem, sys_loadProcess
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
GLOBAL sys_exit, sys_ps, sys_free, sys_malloc, sys_sem, sys_openPipe, sys_nice
section .text
@ -199,6 +199,27 @@ sys_sem:
pop rbp
ret
sys_nice:
push rbp
mov rbp, rsp
push rdi
push rsi
push rdx
mov rdx, rsi
mov rsi, rdi
mov rdi, 11
int 80h
pop rdx
pop rsi
pop rdi
mov rsp, rbp
pop rbp
ret
_getMem:
push rbp
mov rbp, rsp

View File

@ -12,5 +12,6 @@ char * sys_sem();
void * sys_malloc(int);
void * sys_free(void *);
void * sys_openPipe(int *, char *);
char sys_nice(int, char);
#endif

View File

@ -141,12 +141,31 @@ char* itoa(int value, char* buffer, int base) {
return reverse(buffer, 0, i - 1);
}
int atoi(char * string, int length) {
int res = 0, i = 0;
while (i < length) {
res = res * 10 + string[i++] - '0';
// int atoi(char * string, int length) {
// int res = 0, i = 0;
// while (string[i] != 0 && i < length) {
// res = res * 10 + string[i++] - '0';
// }
// return res;
// }
int atoi(char *str, int length) {
int i = 0, sign = 1, val = 0, nbr = 0;
while (str[i] != '\0') {
if (str[i] == '-') {
sign = -sign;
str++;
}
i++;
}
return res;
i = 0;
while (str[i] >= '0' && str[i] <= '9' && str[i] != '\0') {
nbr = (int) (str[i] - '0');
val = (val * 10) + nbr;
i++;
}
i++;
return (val * sign);
}
int pow(int base, int exponent) {

View File

@ -0,0 +1,11 @@
#include "nice.h"
void nice(int argc, char ** argv) {
if (argc != 3)
printStringLen("nice receives a pid and an offset\n", 35);
int pid = atoi(argv[1], MAX_LEN);
char offset = (char) atoi(argv[2], MAX_LEN);
sys_nice(pid, offset);
sys_exit();
}

View File

@ -30,4 +30,5 @@ void printmem(int argc, char *argv[]) {
printString(itoa(buffer[i], bufferAux, 16));
new_line();
}
sys_exit();
}

View File

@ -6,4 +6,5 @@ void ps(int argc, char *argv[]) {
printString(output);
new_line();
sys_free(output);
sys_exit();
}

View File

@ -40,4 +40,5 @@ void quadratic(int argc, char *argv[]) {
ftoa(sol2, buffer2, 10);
printString(buffer2);
new_line();
sys_exit();
}

View File

@ -6,4 +6,5 @@ void sem(int argc, char *argv[]) {
printString(output);
new_line();
sys_free(output);
sys_exit();
}

View File

@ -47,4 +47,5 @@ void time(int argc, char *argv[]) {
printTime(getMinutes());
putChar(':');
printTime(getSeconds());
sys_exit();
}

View File

@ -0,0 +1,11 @@
#ifndef NICE_LIB
#define NICE_LIB
#include "libc.h"
#include "system.h"
#define MAX_LEN 10
void nice(int argc, char *argv[]);
#endif

View File

@ -15,6 +15,7 @@
#include "cat.h"
#include "semCom.h"
#include "stddef.h"
#include "nice.h"
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
@ -30,7 +31,7 @@ typedef struct cmd_t {
char isBuiltIn;
} cmd_t;
const int len = 14;
const int len = 15;
cmd_t commands[] = {
{ "help", help, 1 },
{ "cat", cat, 0 },
@ -41,6 +42,7 @@ cmd_t commands[] = {
{ "filter", filter, 0 },
{ "clear", clear, 1 },
{ "cpufeatures", cpufeatures, 1 },
{ "nice", nice, 0 },
{ "ps", ps, 1 },
{ "sem", sem, 1 },
{ "quadratic", quadratic, 0 },
@ -82,34 +84,45 @@ void processInput(char * input) {
break;
}
}
int fd[2];
int * fd, * fd1, * fd2;
fd1 = sys_malloc(2 * sizeof(int));
fd1[0] = 0;
fd1[1] = 1;
if (pipe != -1) {
fd = sys_malloc(2 * sizeof(int));
if (sys_openPipe(fd, "pipe"))
return;
// return EXIT_FAILURE;
fd2 = sys_malloc(2 * sizeof(int));
fd1[0] = 0;
fd1[1] = fd[1];
fd2[0] = fd[0];
fd2[1] = 1;
}
char ** argv0 = NULL;
char ** argv1 = NULL;
int comm0 = -1;
int comm1 = -1;
if (pipe != -1) {
argv0 = sys_malloc(sizeof(char *) * pipe);
for (int i = 0; i < pipe; i++)
argv0[i] = tokens[i];
argv1 = sys_malloc(sizeof(char *) * (end - pipe - 1));
for (int i = pipe + 1; i < end - pipe - 1; i++)
argv1[i] = tokens[i];
for (int i = pipe + 1; i < end; i++)
argv1[i - pipe - 1] = tokens[i];
}
else {
*argv0 = sys_malloc(sizeof(char *) * end);
argv0 = sys_malloc(sizeof(char *) * end);
for (int i = 0; i < end; i++)
argv0[i] = tokens[i];
}
for (int i = 0; i < len; i++) {
if (!strcmp(tokens[0], commands[i].name)) {
comm_flag0 = 1;
if (pipe != -1)
sys_loadProcess(commands[i].func, 1, pipe, argv0, fd);
else
sys_loadProcess(commands[i].func, 1, end, argv0, NULL);
comm0 = i;
break;
}
}
@ -117,12 +130,20 @@ void processInput(char * input) {
for (int i = 0; i < len; i++) {
if (!strcmp(tokens[pipe + 1], commands[i].name)) {
comm_flag1 = 1;
sys_loadProcess(commands[i].func, 1, end - pipe - 1, argv1, fd);
comm1 = i;
break;
}
}
}
if (comm_flag0 && (comm_flag1 || pipe == -1)) {
if (pipe != -1) {
sys_loadProcess(commands[comm0].func, 1, pipe, argv0, fd1);
sys_loadProcess(commands[comm1].func, 1, end - pipe - 1, argv1, fd2);
}
else sys_loadProcess(commands[comm0].func, 1, end, argv0, fd1);
}
if (!comm_flag0) {
if (*tokens[0] != 0)
incorrect_comm(tokens[0]);