From 9c5486e091ff02c03eaf67af31b77015c813222b Mon Sep 17 00:00:00 2001
From: Santiago Lo Coco <slococo@itba.edu.ar>
Date: Sun, 31 Oct 2021 07:53:33 -0300
Subject: [PATCH] Add wait and make blocking syscalls

Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar>
Co-authored-by: Juan Barmasch <jbarmasch@itba.edu.ar>
---
 Kernel/asm/interrupts.asm                     |  12 +-
 Kernel/drivers/keyboard.c                     |   4 +-
 Kernel/drivers/time.c                         |   4 +-
 Kernel/include/time.h                         |   2 +-
 Kernel/interruptions/systemCalls.c            |   3 +
 Kernel/interruptions/systemCallsDispatcher.c  |   2 +
 Kernel/utils/scheduler.c                      | 223 +++++-------------
 Kernel/utils/sem.c                            |  13 +-
 Userland/SampleCodeModule/asm/libasm.asm      |  63 ++---
 Userland/SampleCodeModule/bottler/bottler.c   |   2 +-
 Userland/SampleCodeModule/sampleCodeModule.c  |   2 +-
 .../SampleCodeModule/shell/commands/phylo.c   | 108 +++++----
 Userland/SampleCodeModule/shell/shell.c       |   1 +
 13 files changed, 159 insertions(+), 280 deletions(-)

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) {