Continue with the implementation of the scheduler
Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar> Co-authored-by: Juan Barmasch <jbarmasch@itba.edu.ar>
This commit is contained in:
parent
60764ea9d7
commit
750006abbf
|
@ -19,9 +19,11 @@ GLOBAL _exception6Handler
|
||||||
EXTERN irqDispatcher
|
EXTERN irqDispatcher
|
||||||
EXTERN exceptionDispatcher
|
EXTERN exceptionDispatcher
|
||||||
EXTERN systemCallsDispatcher
|
EXTERN systemCallsDispatcher
|
||||||
EXTERN preserveStack
|
; EXTERN preserveStack
|
||||||
EXTERN newStack
|
; EXTERN newStack
|
||||||
EXTERN changeWindow
|
EXTERN changeWindow
|
||||||
|
EXTERN updateRSP
|
||||||
|
EXTERN nextProcess
|
||||||
|
|
||||||
GLOBAL switchContext
|
GLOBAL switchContext
|
||||||
GLOBAL loadProcess
|
GLOBAL loadProcess
|
||||||
|
@ -136,7 +138,26 @@ picSlaveMask:
|
||||||
|
|
||||||
;8254 Timer (Timer Tick)
|
;8254 Timer (Timer Tick)
|
||||||
_irq00Handler:
|
_irq00Handler:
|
||||||
irqHandlerMaster 0
|
pushState
|
||||||
|
fsave [bytesForFPU]
|
||||||
|
fxsave [bytesForSSEAligned]
|
||||||
|
|
||||||
|
mov rdi, 0
|
||||||
|
call irqDispatcher
|
||||||
|
|
||||||
|
mov rdi, rsp
|
||||||
|
call updateRSP
|
||||||
|
|
||||||
|
call nextProcess
|
||||||
|
mov rsp, rax
|
||||||
|
|
||||||
|
mov al, 20h
|
||||||
|
out 20h, al
|
||||||
|
|
||||||
|
fxrstor [bytesForSSEAligned]
|
||||||
|
frstor [bytesForFPU]
|
||||||
|
popState
|
||||||
|
iretq
|
||||||
|
|
||||||
;Keyboard
|
;Keyboard
|
||||||
_irq01Handler:
|
_irq01Handler:
|
||||||
|
@ -208,21 +229,21 @@ haltcpu:
|
||||||
|
|
||||||
_initialize_stack_frame:
|
_initialize_stack_frame:
|
||||||
mov r10, rsp
|
mov r10, rsp
|
||||||
mov rsp, rsi
|
; mov rsp, rsi
|
||||||
|
|
||||||
push 0x0 ; ss
|
push 0x0 ; ss
|
||||||
push rsi ; sp
|
push rsi ; sp
|
||||||
push 0x202 ; rflags
|
push 0x202 ; rflags
|
||||||
push 0x08 ; cs -- offset de la GDT
|
push 0x08 ; cs -- offset de la GDT
|
||||||
push rdi ; IP
|
push rdi ; IP
|
||||||
push rdx
|
push rdx ; argc
|
||||||
push rcx
|
push rcx ; argv
|
||||||
|
|
||||||
pushState
|
pushState
|
||||||
mov rdi, rsp
|
; mov rdi, rsp
|
||||||
call newStack
|
; call newStack
|
||||||
|
|
||||||
mov rax, rsp
|
; mov rax, rsp
|
||||||
mov rsp, r10
|
mov rsp, r10
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -240,16 +261,32 @@ _systemCallsHandler:
|
||||||
iretq
|
iretq
|
||||||
|
|
||||||
; switch Context (int 81h)
|
; switch Context (int 81h)
|
||||||
_switchContext:
|
; _switchContext:
|
||||||
pushState
|
; pushState
|
||||||
|
;
|
||||||
call changeWindow
|
; call changeWindow
|
||||||
mov rdi, rsp
|
; mov rdi, rsp
|
||||||
call preserveStack
|
; call preserveStack
|
||||||
|
;
|
||||||
|
; mov rsp, rax
|
||||||
|
; popState
|
||||||
|
; pop rsi ; argv
|
||||||
|
; pop rdi ; argc
|
||||||
|
; iretq
|
||||||
|
|
||||||
mov rsp, rax
|
; _switchContext:
|
||||||
popState
|
; pushState
|
||||||
iretq
|
|
||||||
|
; mov rdi, rsp
|
||||||
|
; call updateRSP
|
||||||
|
|
||||||
|
; call nextProcess
|
||||||
|
|
||||||
|
; mov rsp, rax
|
||||||
|
; popState
|
||||||
|
; pop rsi ; argv
|
||||||
|
; pop rdi ; argc
|
||||||
|
; iretq
|
||||||
|
|
||||||
SECTION .data
|
SECTION .data
|
||||||
align 16
|
align 16
|
||||||
|
|
|
@ -21,5 +21,4 @@
|
||||||
#define ACS_DATA (ACS_PRESENT | ACS_DSEG | ACS_WRITE)
|
#define ACS_DATA (ACS_PRESENT | ACS_DSEG | ACS_WRITE)
|
||||||
#define ACS_STACK (ACS_PRESENT | ACS_DSEG | ACS_WRITE)
|
#define ACS_STACK (ACS_PRESENT | ACS_DSEG | ACS_WRITE)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -10,5 +10,7 @@ void swap(char * x, char * y);
|
||||||
char * reverse(char * buffer, int i, int j);
|
char * reverse(char * buffer, int i, int j);
|
||||||
int abs(int value);
|
int abs(int value);
|
||||||
char * itoa(int value, char * buffer, int base, int length);
|
char * itoa(int value, char * buffer, int base, int length);
|
||||||
|
void strlen(const char *str, int *len);
|
||||||
|
int strcpy(char * strDest, const char * strSrc);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,8 +1,8 @@
|
||||||
#include "scheduler.h"
|
// #include "scheduler.h"
|
||||||
|
|
||||||
typedef struct queueCDT * queueADT;
|
// typedef struct queueCDT * queueADT;
|
||||||
|
|
||||||
void queue(queueADT * my_queue, processADT * process);
|
// void queue(queueADT * my_queue, processADT * process);
|
||||||
char isEmpty(queueADT * my_queue);
|
// char isEmpty(queueADT * my_queue);
|
||||||
processADT * dequeue(queueADT * my_queue);
|
// processADT * dequeue(queueADT * my_queue);
|
||||||
queueADT createQueue();
|
// queueADT createQueue();
|
|
@ -1 +1,40 @@
|
||||||
typedef struct processCDT * processADT;
|
#ifndef SCHEDULER_H
|
||||||
|
#define SCHEDULER_H
|
||||||
|
|
||||||
|
#include "queue.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "memManager.h"
|
||||||
|
#include "lib.h"
|
||||||
|
|
||||||
|
void forceTimer();
|
||||||
|
void haltcpu();
|
||||||
|
|
||||||
|
#define STACK_SIZE 1024
|
||||||
|
#define MAX_PRIORITY 40 // Maximum number for a priority
|
||||||
|
#define MIN_PRIORITY 0 // Minimum number for a priority (yet maximum level of priority) // me gusta
|
||||||
|
#define DEF_PRIORITY 0
|
||||||
|
#define PROCESS_DATA_MAX_SIZE 100
|
||||||
|
#define MAX_ATTR_SIZE 6
|
||||||
|
#define MAX_NAME_SIZE 10
|
||||||
|
|
||||||
|
typedef struct processCDT * processADT;
|
||||||
|
|
||||||
|
uint64_t nextProcess();
|
||||||
|
void idle();
|
||||||
|
void initScheduler();
|
||||||
|
void enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]);
|
||||||
|
void newProcess(processADT process, char * name, char priority, char foreground, uint64_t rsp, uint64_t rbp);
|
||||||
|
char block(int pid);
|
||||||
|
char unblock(int pid);
|
||||||
|
char kill(int pid);
|
||||||
|
void exitProcess();
|
||||||
|
char nice(char offset);
|
||||||
|
void updateRSP(uint64_t newRsp);
|
||||||
|
int getPid();
|
||||||
|
char quitCPU();
|
||||||
|
char getProcessData(char * out, processADT proc);
|
||||||
|
char * processes();
|
||||||
|
|
||||||
|
#endif
|
|
@ -83,7 +83,7 @@ static void startOver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
cleanProcesses();
|
// cleanProcesses();
|
||||||
moveToWindowVideo(1);
|
moveToWindowVideo(1);
|
||||||
//((fn)sampleCodeAddress)();
|
//((fn)sampleCodeAddress)();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,12 @@ void load_idt() {
|
||||||
setup_IDT_entry (0x06, (uint64_t)&_exception6Handler);
|
setup_IDT_entry (0x06, (uint64_t)&_exception6Handler);
|
||||||
|
|
||||||
setup_IDT_entry (0x80, (uint64_t)&_systemCallsHandler);
|
setup_IDT_entry (0x80, (uint64_t)&_systemCallsHandler);
|
||||||
setup_IDT_entry (0x81, (uint64_t)&_switchContext);
|
// setup_IDT_entry (0x81, (uint64_t)&_switchContext);
|
||||||
|
|
||||||
picMasterMask(0xFC);
|
picMasterMask(0xFC);
|
||||||
picSlaveMask(0xFF);
|
picSlaveMask(0xFF);
|
||||||
|
|
||||||
_sti();
|
// _sti();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_IDT_entry (int index, uint64_t offset) {
|
static void setup_IDT_entry (int index, uint64_t offset) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "systemCalls.h"
|
#include "systemCalls.h"
|
||||||
|
|
||||||
uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx) {
|
uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8) {
|
||||||
switch (rdi) {
|
switch (rdi) {
|
||||||
case 0:
|
case 0:
|
||||||
return write(rsi, rdx, rcx);
|
return write(rsi, rdx, rcx);
|
||||||
|
@ -10,7 +10,8 @@ uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_
|
||||||
case 2:
|
case 2:
|
||||||
return getTime(rsi, rdx, rcx);
|
return getTime(rsi, rdx, rcx);
|
||||||
case 3:
|
case 3:
|
||||||
createProcess(rsi);
|
// createProcess(rsi);
|
||||||
|
enqueueProcess(rsi, rdx, rcx, r8);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
// #include <string.h>
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#include <moduleLoader.h>
|
#include <moduleLoader.h>
|
||||||
#include <naiveConsole.h>
|
#include <naiveConsole.h>
|
||||||
|
@ -140,7 +140,17 @@ void test_mm(){
|
||||||
// new_line();
|
// new_line();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]);
|
||||||
|
void initScheduler();
|
||||||
|
|
||||||
|
void _cli();
|
||||||
|
void _sti();
|
||||||
|
void haltcpu();
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
// _cli();
|
||||||
|
|
||||||
load_idt();
|
load_idt();
|
||||||
|
|
||||||
// if (initMemoryManager(memoryModuleAddress, memoryModuleAddress + sizeof(void *)) == -1) {
|
// if (initMemoryManager(memoryModuleAddress, memoryModuleAddress + sizeof(void *)) == -1) {
|
||||||
|
@ -150,6 +160,7 @@ int main() {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
initMemoryManager(memoryModuleAddress);
|
initMemoryManager(memoryModuleAddress);
|
||||||
|
initScheduler();
|
||||||
|
|
||||||
#ifndef BUDDY
|
#ifndef BUDDY
|
||||||
// SACAR DESPUÉS! ES SOLO PARA TESTEO... CORRER DE A UNO!
|
// SACAR DESPUÉS! ES SOLO PARA TESTEO... CORRER DE A UNO!
|
||||||
|
@ -159,12 +170,17 @@ int main() {
|
||||||
// return EXIT_FAILURE;
|
// return EXIT_FAILURE;
|
||||||
#endif
|
#endif
|
||||||
// test_mm();
|
// test_mm();
|
||||||
|
|
||||||
saveSampleRSP(getRSP());
|
saveSampleRSP(getRSP());
|
||||||
|
|
||||||
|
|
||||||
|
// ((EntryPoint)sampleCodeModuleAddress)();
|
||||||
|
char * argv[] = {"SampleCode"};
|
||||||
|
enqueueProcess(sampleCodeModuleAddress, 1, 1, argv);
|
||||||
|
// haltcpu();
|
||||||
|
_sti();
|
||||||
|
|
||||||
printBottlerAndWait();
|
printBottlerAndWait();
|
||||||
|
|
||||||
((EntryPoint)sampleCodeModuleAddress)();
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +219,7 @@ void printBottlerAndWait() {
|
||||||
printStringLen(13, " %%%%%%% ", 80); new_line();
|
printStringLen(13, " %%%%%%% ", 80); new_line();
|
||||||
printStringLen(13, " ", 80); new_line();
|
printStringLen(13, " ", 80); new_line();
|
||||||
|
|
||||||
wait(3);
|
// wait(3);
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
12
Kernel/lib.c
12
Kernel/lib.c
|
@ -97,4 +97,16 @@ char * itoa(int value, char * buffer, int base, int length) {
|
||||||
|
|
||||||
buffer[i] = '\0';
|
buffer[i] = '\0';
|
||||||
return reverse(buffer, 0, i - 1);
|
return reverse(buffer, 0, i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void strlen(const char *str, int *len) {
|
||||||
|
for (*len = 0; str[*len]; (*len)++);
|
||||||
|
}
|
||||||
|
|
||||||
|
int strcpy(char * strDest, const char * strSrc) {
|
||||||
|
int i = 0;
|
||||||
|
while (*strDest++ = *strSrc++) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
}
|
}
|
|
@ -1,36 +1,36 @@
|
||||||
#include "pcb.h"
|
#include "pcb.h"
|
||||||
|
|
||||||
static const uint8_t * firstProcessAddress = (uint8_t *) 0x18000000;
|
// static const uint8_t * firstProcessAddress = (uint8_t *) 0x18000000;
|
||||||
static const long stackSize = 0x4000000; // 2^26
|
// static const long stackSize = 0x4000000; // 2^26
|
||||||
static const uint8_t * lastProcessAddress = (uint8_t *) 0x10000001; // 2^29 - 1
|
// static const uint8_t * lastProcessAddress = (uint8_t *) 0x10000001; // 2^29 - 1
|
||||||
|
|
||||||
int activeProcesses = 0, currentProcess = -1;
|
// int activeProcesses = 0, currentProcess = -1;
|
||||||
uint64_t priority0[MAX_PROCESSES];
|
// uint64_t priority0[MAX_PROCESSES];
|
||||||
uint64_t priority1[MAX_PROCESSES];
|
// uint64_t priority1[MAX_PROCESSES];
|
||||||
uint64_t priority2[MAX_PROCESSES];
|
// uint64_t priority2[MAX_PROCESSES];
|
||||||
|
|
||||||
void cleanProcesses() {
|
// void cleanProcesses() {
|
||||||
activeProcesses = 0;
|
// activeProcesses = 0;
|
||||||
currentProcess = -1;
|
// currentProcess = -1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void newProcess(void (*fn)) {
|
// void newProcess(void (*fn)) {
|
||||||
if (firstProcessAddress - activeProcesses * stackSize + stackSize <= lastProcessAddress) return;
|
// if (firstProcessAddress - activeProcesses * stackSize + stackSize <= lastProcessAddress) return;
|
||||||
_initialize_stack_frame(fn, firstProcessAddress - activeProcesses * stackSize);
|
// _initialize_stack_frame(fn, firstProcessAddress - activeProcesses * stackSize);
|
||||||
}
|
// }
|
||||||
|
|
||||||
void newStack(uint64_t rsp) {
|
// void newStack(uint64_t rsp) {
|
||||||
priority0[activeProcesses++] = rsp;
|
// priority0[activeProcesses++] = rsp;
|
||||||
}
|
// }
|
||||||
|
|
||||||
uint64_t preserveStack(uint64_t rsp) {
|
// uint64_t preserveStack(uint64_t rsp) {
|
||||||
if (currentProcess != -1) {
|
// if (currentProcess != -1) {
|
||||||
priority0[currentProcess] = rsp;
|
// priority0[currentProcess] = rsp;
|
||||||
}
|
// }
|
||||||
if (++currentProcess >= activeProcesses) currentProcess = 0;
|
// if (++currentProcess >= activeProcesses) currentProcess = 0;
|
||||||
if (activeProcesses == 0) return 0;
|
// if (activeProcesses == 0) return 0;
|
||||||
return priority0[currentProcess];
|
// return priority0[currentProcess];
|
||||||
}
|
// }
|
||||||
|
|
||||||
static uint64_t sampleRSP;
|
static uint64_t sampleRSP;
|
||||||
|
|
||||||
|
|
|
@ -1,51 +1,51 @@
|
||||||
#include "queue.h"
|
// #include "queue.h"
|
||||||
#include "memManager.h"
|
// #include "memManager.h"
|
||||||
#include <stdint.h>
|
// #include <stdint.h>
|
||||||
|
|
||||||
typedef struct nodeT {
|
// typedef struct nodeT {
|
||||||
processADT * process;
|
// processADT * process;
|
||||||
struct nodeT * next;
|
// struct nodeT * next;
|
||||||
} nodeT;
|
// } nodeT;
|
||||||
|
|
||||||
typedef struct queueCDT {
|
// typedef struct queueCDT {
|
||||||
nodeT * first;
|
// nodeT * first;
|
||||||
nodeT * last;
|
// nodeT * last;
|
||||||
int length;
|
// int length;
|
||||||
} queueCDT;
|
// } queueCDT;
|
||||||
|
|
||||||
queueADT createQueue() {
|
// queueADT createQueue() {
|
||||||
queueADT aux = pvPortMalloc(sizeof(queueCDT));
|
// queueADT aux = pvPortMalloc(sizeof(queueCDT));
|
||||||
if (aux == NULL)
|
// if (aux == NULL)
|
||||||
return NULL;
|
// return NULL;
|
||||||
aux->first = NULL;
|
// aux->first = NULL;
|
||||||
aux->last = NULL;
|
// aux->last = NULL;
|
||||||
aux->length = 0;
|
// aux->length = 0;
|
||||||
return aux;
|
// return aux;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void queue(queueADT * my_queue, processADT * process) {
|
// void queue(queueADT * my_queue, processADT * process) {
|
||||||
if (my_queue == NULL)
|
// if (my_queue == NULL)
|
||||||
return;
|
// return;
|
||||||
nodeT * new_node = pvPortMalloc(sizeof(nodeT));
|
// nodeT * new_node = pvPortMalloc(sizeof(nodeT));
|
||||||
if (new_node == NULL)
|
// if (new_node == NULL)
|
||||||
return;
|
// return;
|
||||||
new_node->process = process;
|
// new_node->process = process;
|
||||||
new_node->next = NULL;
|
// new_node->next = NULL;
|
||||||
(*my_queue)->last->next = new_node;
|
// (*my_queue)->last->next = new_node;
|
||||||
(*my_queue)->last = new_node;
|
// (*my_queue)->last = new_node;
|
||||||
(*my_queue)->length++;
|
// (*my_queue)->length++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
processADT * dequeue(queueADT * my_queue) {
|
// processADT * dequeue(queueADT * my_queue) {
|
||||||
if (my_queue == NULL || isEmpty(my_queue))
|
// if (my_queue == NULL || isEmpty(my_queue))
|
||||||
return NULL;
|
// return NULL;
|
||||||
nodeT * aux = (*my_queue)->first;
|
// nodeT * aux = (*my_queue)->first;
|
||||||
(*my_queue)->first = (*my_queue)->first->next;
|
// (*my_queue)->first = (*my_queue)->first->next;
|
||||||
processADT * ans = aux->process;
|
// processADT * ans = aux->process;
|
||||||
vPortFree(aux);
|
// vPortFree(aux);
|
||||||
return ans;
|
// return ans;
|
||||||
}
|
// }
|
||||||
|
|
||||||
char isEmpty(queueADT * my_queue) {
|
// char isEmpty(queueADT * my_queue) {
|
||||||
return (*my_queue)->length == 0;
|
// return (*my_queue)->length == 0;
|
||||||
}
|
// }
|
|
@ -1,172 +1,101 @@
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "queue.h"
|
void _initialize_stack_frame(void *, void *, int, char**);
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "memManager.h"
|
|
||||||
|
|
||||||
void forceTimer();
|
|
||||||
|
|
||||||
#define STACK_SIZE 1024
|
|
||||||
|
|
||||||
enum states {READY = 0, BLOCKED};
|
enum states {READY = 0, BLOCKED};
|
||||||
|
|
||||||
typedef struct processCDT {
|
typedef struct processCDT {
|
||||||
|
struct processCDT * next;
|
||||||
char * name;
|
char * name;
|
||||||
int pid;
|
int pid;
|
||||||
int ppid;
|
int ppid;
|
||||||
uint64_t rsp;
|
uint64_t rsp;
|
||||||
uint64_t rbp;
|
uint64_t rbp;
|
||||||
char priority;
|
char priority;
|
||||||
|
char executions;
|
||||||
char foreground;
|
char foreground;
|
||||||
enum states state;
|
enum states state;
|
||||||
} processCDT;
|
} processCDT;
|
||||||
|
|
||||||
typedef struct nodeT {
|
processCDT * firstReady = NULL;
|
||||||
processADT * process;
|
processCDT * lastReady = NULL;
|
||||||
struct nodeT * next;
|
processCDT * firstBlocked = NULL;
|
||||||
struct nodeT * previous;
|
processCDT * lastBlocked = NULL;
|
||||||
} nodeT;
|
|
||||||
|
|
||||||
typedef struct listT {
|
int readyLen = 0;
|
||||||
nodeT * first;
|
int blockedLen = 0;
|
||||||
nodeT * last;
|
|
||||||
int length;
|
|
||||||
} listT;
|
|
||||||
|
|
||||||
listT * ready = {NULL, NULL, 0};
|
processCDT * currentProcess = NULL;
|
||||||
listT * blocked = {NULL, NULL, 0};
|
|
||||||
nodeT * current = NULL;
|
|
||||||
int pids = 0;
|
int pids = 0;
|
||||||
|
|
||||||
processADT * next() {
|
uint64_t nextProcess() {
|
||||||
if (ready->first == NULL)
|
if (currentProcess == NULL)
|
||||||
return NULL;
|
return firstReady->rsp;
|
||||||
current = current->next;
|
if (currentProcess->executions < MAX_PRIORITY - currentProcess->priority + 1) {
|
||||||
if (current == NULL)
|
currentProcess->executions++;
|
||||||
current = ready->first;
|
return currentProcess->rsp;
|
||||||
return current->process;
|
}
|
||||||
|
currentProcess->executions = 0;
|
||||||
|
currentProcess = currentProcess->next;
|
||||||
|
return currentProcess->rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// void init() {
|
|
||||||
// new(idle, )
|
|
||||||
// }
|
|
||||||
|
|
||||||
void idle() {
|
void idle() {
|
||||||
while (1) {
|
while (1) {
|
||||||
haltcpu();
|
haltcpu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void launchProcess(void (*fn) (int, char **), char priority, char foreground, int argc, char *argv[]) {
|
void initScheduler() {
|
||||||
|
char * argv[] = {"Dummy"};
|
||||||
|
enqueueProcess(idle, 0, 1, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]) {
|
||||||
processADT proc = pvPortMalloc(sizeof(processCDT));
|
processADT proc = pvPortMalloc(sizeof(processCDT));
|
||||||
nodeT * node = pvPortMalloc(sizeof(nodeT));
|
|
||||||
uint64_t * rbp = pvPortMalloc(STACK_SIZE);
|
uint64_t * rbp = pvPortMalloc(STACK_SIZE);
|
||||||
uint64_t * rsp = rbp;
|
uint64_t * rsp = rbp;
|
||||||
|
|
||||||
|
char priority = (foreground == 1) ? DEF_PRIORITY : MAX_PRIORITY/2;
|
||||||
|
|
||||||
newProcess(proc, argv[0], priority, foreground);
|
newProcess(proc, argv[0], priority, foreground, (uint64_t)rsp, (uint64_t)rbp);
|
||||||
|
|
||||||
_initialize_stack_frame(fn, rbp, argc, argv);
|
_initialize_stack_frame(fn, rbp, argc, argv);
|
||||||
|
|
||||||
if (current != NULL && foreground) {
|
if (firstReady == NULL)
|
||||||
block((*current->process)->pid);
|
firstReady = proc;
|
||||||
return;
|
else
|
||||||
}
|
lastReady->next = proc;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void newProcess(processADT process, char * name, char priority, char foreground) {
|
void newProcess(processADT process, char * name, char priority, char foreground, uint64_t rsp, uint64_t rbp) {
|
||||||
|
char aux[MAX_NAME_SIZE];
|
||||||
|
for (int j = 0; j < MAX_NAME_SIZE && name[j] != 0; j++) {
|
||||||
|
aux[j] = name[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
process->name = aux;
|
||||||
process->name = name;
|
|
||||||
process->pid = pids++;
|
process->pid = pids++;
|
||||||
process->ppid = (*current->process)->pid;
|
process->ppid = currentProcess->pid;
|
||||||
process->foreground = foreground;
|
|
||||||
process->priority = priority;
|
process->priority = priority;
|
||||||
|
process->rsp = rsp;
|
||||||
|
process->rbp = rbp;
|
||||||
|
process->executions = 0;
|
||||||
|
process->foreground = foreground;
|
||||||
process->state = READY;
|
process->state = READY;
|
||||||
process->rbp = STACK_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loader(int argc, char * argv[], void (*fn) (int, char **)) {
|
// void loader(int argc, char * argv[], void (*fn) (int, char **)) {
|
||||||
fn(argc, argv);
|
// fn(argc, argv);
|
||||||
exit();
|
// exit();
|
||||||
}
|
// }
|
||||||
|
|
||||||
void exit() {
|
processCDT * search(processCDT ** previous, int pid, processCDT * first) {
|
||||||
kill((*current->process)->pid);
|
processCDT * curr = first;
|
||||||
}
|
|
||||||
|
|
||||||
char block(int pid) {
|
|
||||||
nodeT * prev = NULL;
|
|
||||||
nodeT * del = search(&prev, pid, ready);
|
|
||||||
if (del == NULL)
|
|
||||||
return -1;
|
|
||||||
else {
|
|
||||||
if (prev != NULL)
|
|
||||||
prev->next = del->next;
|
|
||||||
else
|
|
||||||
ready->first = del->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid == (*del->process)->pid)
|
|
||||||
forceTimer();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char unblock(int pid) {
|
|
||||||
nodeT * prev = NULL;
|
|
||||||
nodeT * del = search(&prev, pid, blocked);
|
|
||||||
if (del == NULL)
|
|
||||||
return -1;
|
|
||||||
else {
|
|
||||||
if (prev != NULL)
|
|
||||||
prev->next = del->next;
|
|
||||||
else
|
|
||||||
blocked->first = del->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid == (*del->process)->pid)
|
|
||||||
forceTimer();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char kill(int pid) {
|
|
||||||
nodeT * prev = NULL;
|
|
||||||
nodeT * del = search(&prev, pid, ready);
|
|
||||||
if (del == NULL) {
|
|
||||||
del = search(&prev, pid, blocked);
|
|
||||||
if (del == NULL)
|
|
||||||
return -1;
|
|
||||||
else {
|
|
||||||
if (prev != NULL)
|
|
||||||
prev->next = del->next;
|
|
||||||
else
|
|
||||||
blocked->first = del->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (prev != NULL)
|
|
||||||
prev->next = del->next;
|
|
||||||
else
|
|
||||||
ready->first = del->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid == (*del->process)->pid)
|
|
||||||
forceTimer();
|
|
||||||
|
|
||||||
vPortFree((*del->process)->rsp);
|
|
||||||
vPortFree(del);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeT * search(nodeT ** previous, int pid, listT * list) {
|
|
||||||
nodeT * curr = list->first;
|
|
||||||
* previous = NULL;
|
* previous = NULL;
|
||||||
while (curr != NULL) {
|
while (curr != NULL) {
|
||||||
if ((*curr->process)->pid == pid) {
|
if (curr->pid == pid) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
* previous = curr;
|
* previous = curr;
|
||||||
|
@ -176,20 +105,197 @@ nodeT * search(nodeT ** previous, int pid, listT * list) {
|
||||||
* previous = NULL;
|
* previous = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (curr = list->first) {
|
if (curr == first) {
|
||||||
* previous = NULL;
|
* previous = NULL;
|
||||||
return curr;
|
return curr;
|
||||||
}
|
}
|
||||||
return curr;
|
return curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char block(int pid) {
|
||||||
|
processCDT * prev = NULL;
|
||||||
|
processCDT * del = search(&prev, pid, firstReady);
|
||||||
|
if (del == NULL)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
else {
|
||||||
|
if (prev != NULL)
|
||||||
|
prev->next = del->next;
|
||||||
|
else
|
||||||
|
firstReady = del->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastBlocked->next = del;
|
||||||
|
del->next = NULL;
|
||||||
|
lastBlocked = del;
|
||||||
|
|
||||||
|
forceTimer();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
char unblock(int pid) {
|
||||||
|
processCDT * prev = NULL;
|
||||||
|
processCDT * del = search(&prev, pid, firstBlocked);
|
||||||
|
if (del == NULL)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
else {
|
||||||
|
if (prev != NULL)
|
||||||
|
prev->next = del->next;
|
||||||
|
else
|
||||||
|
firstBlocked = del->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == del->pid)
|
||||||
|
forceTimer();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
char kill(int pid) {
|
||||||
|
processCDT * prev = NULL;
|
||||||
|
processCDT * del = search(&prev, pid, firstReady);
|
||||||
|
if (del == NULL) {
|
||||||
|
del = search(&prev, pid, firstBlocked);
|
||||||
|
if (del == NULL)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
else {
|
||||||
|
if (prev != NULL)
|
||||||
|
prev->next = del->next;
|
||||||
|
else
|
||||||
|
firstBlocked = del->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (prev != NULL)
|
||||||
|
prev->next = del->next;
|
||||||
|
else
|
||||||
|
firstReady = del->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == del->pid)
|
||||||
|
forceTimer();
|
||||||
|
|
||||||
|
vPortFree((void *) del->rsp);
|
||||||
|
vPortFree((void *) del);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exitProcess() {
|
||||||
|
kill(currentProcess->pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
char nice(char offset) {
|
||||||
|
if (currentProcess == NULL)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
currentProcess->priority += offset;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateRSP(uint64_t newRsp) {
|
||||||
|
if (currentProcess == NULL)
|
||||||
|
return;
|
||||||
|
currentProcess->rsp = newRsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getPid() {
|
||||||
|
if (currentProcess == NULL)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
return currentProcess->pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
char quitCPU() {
|
||||||
|
int pid = getPid();
|
||||||
|
if (pid == EXIT_FAILURE)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
// return block(pid);
|
||||||
|
forceTimer();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
char addSpaces(char * str, char qty) {
|
||||||
|
char aux = qty;
|
||||||
|
while (qty-- > 0) {
|
||||||
|
*str++ = ' ';
|
||||||
|
}
|
||||||
|
return aux;
|
||||||
|
}
|
||||||
|
|
||||||
|
char getProcessData(char * out, processCDT * proc) {
|
||||||
|
if (proc == NULL)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
char written = 0;
|
||||||
|
|
||||||
|
char flag = 0;
|
||||||
|
for (int j = 0; j < MAX_ATTR_SIZE; j++) {
|
||||||
|
if (proc->name[j] != 0)
|
||||||
|
flag = 1;
|
||||||
|
if (flag){
|
||||||
|
out += addSpaces(out, 1);
|
||||||
|
} else
|
||||||
|
*out++ = proc->name[j];
|
||||||
|
}
|
||||||
|
written += MAX_ATTR_SIZE;
|
||||||
|
|
||||||
|
out += addSpaces(out, 2);
|
||||||
|
written += 2;
|
||||||
|
|
||||||
|
char buffer[10];
|
||||||
|
written += strcpy(out, itoa(proc->pid, buffer, 10, 10));
|
||||||
|
out += addSpaces(out, 2);
|
||||||
|
|
||||||
|
buffer[0] = 0;
|
||||||
|
written += strcpy(out, itoa(proc->priority, buffer, 10, 2));
|
||||||
|
out += addSpaces(out, 2);
|
||||||
|
|
||||||
|
buffer[0] = 0;
|
||||||
|
written += strcpy(out, itoa(proc->rsp, buffer, 16, 10));
|
||||||
|
out += addSpaces(out, 2);
|
||||||
|
|
||||||
|
buffer[0] = 0;
|
||||||
|
written += strcpy(out, itoa(proc->rbp, buffer, 16, 10));
|
||||||
|
out += addSpaces(out, 2);
|
||||||
|
|
||||||
|
buffer[0] = 0;
|
||||||
|
written += strcpy(out, (proc->foreground == 1) ? "F" : "B");
|
||||||
|
// out += addSpaces(out, 2);
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * processes(){
|
||||||
|
char * ans = pvPortMalloc(pids * PROCESS_DATA_MAX_SIZE);
|
||||||
|
|
||||||
|
int lastPid = getPid();
|
||||||
|
if (lastPid == EXIT_FAILURE)
|
||||||
|
return NULL;
|
||||||
|
processCDT * aux = firstReady;
|
||||||
|
while (aux != NULL){
|
||||||
|
char writtenChars = getProcessData(ans, aux);
|
||||||
|
if (writtenChars == EXIT_FAILURE)
|
||||||
|
return NULL;
|
||||||
|
ans += writtenChars;
|
||||||
|
*ans++ = '\n';
|
||||||
|
|
||||||
|
if (aux == lastBlocked)
|
||||||
|
aux = NULL;
|
||||||
|
else if (aux == lastReady)
|
||||||
|
aux = firstBlocked;
|
||||||
|
else
|
||||||
|
aux = aux->next;
|
||||||
|
}
|
||||||
|
*ans = 0;
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
● Crear un proceso. DEBERÁ soportar el pasaje de parámetros.
|
● Crear un proceso. DEBERÁ soportar el pasaje de parámetros. LISTO
|
||||||
● Obtener el ID del proceso que llama.
|
● 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.
|
||||||
● Matar un proceso arbitrario.
|
● Matar un proceso arbitrario. LISTO
|
||||||
● Modificar la prioridad de un proceso arbitrario.
|
● Modificar la prioridad de un proceso arbitrario. LISTO
|
||||||
● Bloquear y desbloquear un proceso arbitrario.
|
● Bloquear y desbloquear un proceso arbitrario. LISTO
|
||||||
● Renunciar al CPU
|
● Renunciar al CPU. LISTO
|
||||||
*/
|
*/
|
|
@ -147,11 +147,20 @@ sys_loadProcess:
|
||||||
|
|
||||||
push rdi
|
push rdi
|
||||||
push rsi
|
push rsi
|
||||||
|
push rdx
|
||||||
|
push rcx
|
||||||
|
push r8
|
||||||
|
|
||||||
|
mov r8, rcx
|
||||||
|
mov rcx, rdx
|
||||||
|
mov rdx, rsi
|
||||||
mov rsi, rdi
|
mov rsi, rdi
|
||||||
mov rdi, 3
|
mov rdi, 3
|
||||||
int 80h
|
int 80h
|
||||||
|
|
||||||
|
pop r8
|
||||||
|
pop rcx
|
||||||
|
pop rdx
|
||||||
pop rsi
|
pop rsi
|
||||||
pop rdi
|
pop rdi
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef SYSTEM_H
|
#ifndef SYSTEM_H
|
||||||
#define SYSTEM_H
|
#define SYSTEM_H
|
||||||
|
|
||||||
void sys_switchContext();
|
// void sys_switchContext();
|
||||||
void sys_loadProcess();
|
// void sys_loadProcess();
|
||||||
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);
|
||||||
|
|
|
@ -2,16 +2,17 @@
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
#include "shell/include/shell.h"
|
#include "shell/include/shell.h"
|
||||||
|
|
||||||
void sys_loadProcess(void (*fn));
|
void sys_loadProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]);
|
||||||
void sys_switchContext();
|
// void sys_switchContext();
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
winClear();
|
winClear();
|
||||||
|
|
||||||
sys_loadProcess(shell);
|
char * argv[] = {"BottlerSh"};
|
||||||
sys_loadProcess(shell);
|
sys_loadProcess(shell, 1, 1, argv);
|
||||||
|
// sys_loadProcess(shell);
|
||||||
|
|
||||||
sys_switchContext();
|
// sys_switchContext();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
void shell(void);
|
void shell(int argc, char *argv[]);
|
||||||
void printWindow(char * window);
|
void printWindow(char * window);
|
||||||
void addText(char * buffer, char * window, int * offset);
|
void addText(char * buffer, char * window, int * offset);
|
||||||
void incorrect_comm(char * buffer, char * window, int * offset);
|
void incorrect_comm(char * buffer, char * window, int * offset);
|
||||||
|
|
|
@ -50,9 +50,10 @@ void scanfNoPrint(char * buffer, int maxSize, char * window, int * offset) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while ((c = getChar()) != '\n' && i < maxSize - 1) {
|
while ((c = getChar()) != '\n' && i < maxSize - 1) {
|
||||||
if (c != -1) {
|
if (c != -1) {
|
||||||
if (c == '\v')
|
// if (c == '\v')
|
||||||
sys_switchContext();
|
// sys_switchContext();
|
||||||
else if (c == '\b' && i > 0) {
|
// else if (c == '\b' && i > 0) {
|
||||||
|
if (c == '\b' && i > 0) {
|
||||||
buffer[--i] = ' ';
|
buffer[--i] = ' ';
|
||||||
window[--(*offset)] = ' ';
|
window[--(*offset)] = ' ';
|
||||||
printWindow(window);
|
printWindow(window);
|
||||||
|
@ -79,7 +80,7 @@ void clearWindow(char * window, int * offset) {
|
||||||
printWindow(window);
|
printWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shell() {
|
void shell(int argc, char *argv[]) {
|
||||||
char window[ROWS * COLS + 1] = {[0 ... ROWS * COLS - 1] = ' ', 0};
|
char window[ROWS * COLS + 1] = {[0 ... ROWS * COLS - 1] = ' ', 0};
|
||||||
int offset = (ROWS - 1) * COLS;
|
int offset = (ROWS - 1) * COLS;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue