Add wait and make blocking syscalls

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-31 07:53:33 -03:00
parent 0041b86135
commit 9c5486e091
13 changed files with 159 additions and 280 deletions

View File

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

View File

@ -75,8 +75,8 @@ unsigned char getKeyFromBuffer() {
}
char aux = *current;
*current++ = 0;
return aux;
*current++ = 0;
return aux;
}
void keyboard_handler() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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