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:
Santiago Lo Coco 2021-10-23 19:06:45 -03:00
parent 60764ea9d7
commit 750006abbf
18 changed files with 473 additions and 250 deletions

View File

@ -19,9 +19,11 @@ GLOBAL _exception6Handler
EXTERN irqDispatcher
EXTERN exceptionDispatcher
EXTERN systemCallsDispatcher
EXTERN preserveStack
EXTERN newStack
; EXTERN preserveStack
; EXTERN newStack
EXTERN changeWindow
EXTERN updateRSP
EXTERN nextProcess
GLOBAL switchContext
GLOBAL loadProcess
@ -136,7 +138,26 @@ picSlaveMask:
;8254 Timer (Timer Tick)
_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
_irq01Handler:
@ -208,21 +229,21 @@ haltcpu:
_initialize_stack_frame:
mov r10, rsp
mov rsp, rsi
; mov rsp, rsi
push 0x0 ; ss
push rsi ; sp
push 0x202 ; rflags
push 0x08 ; cs -- offset de la GDT
push rdi ; IP
push rdx
push rcx
push rdx ; argc
push rcx ; argv
pushState
mov rdi, rsp
call newStack
; mov rdi, rsp
; call newStack
mov rax, rsp
; mov rax, rsp
mov rsp, r10
ret
@ -240,16 +261,32 @@ _systemCallsHandler:
iretq
; switch Context (int 81h)
_switchContext:
pushState
call changeWindow
mov rdi, rsp
call preserveStack
; _switchContext:
; pushState
;
; call changeWindow
; mov rdi, rsp
; call preserveStack
;
; mov rsp, rax
; popState
; pop rsi ; argv
; pop rdi ; argc
; iretq
mov rsp, rax
popState
iretq
; _switchContext:
; pushState
; mov rdi, rsp
; call updateRSP
; call nextProcess
; mov rsp, rax
; popState
; pop rsi ; argv
; pop rdi ; argc
; iretq
SECTION .data
align 16

View File

@ -21,5 +21,4 @@
#define ACS_DATA (ACS_PRESENT | ACS_DSEG | ACS_WRITE)
#define ACS_STACK (ACS_PRESENT | ACS_DSEG | ACS_WRITE)
#endif

View File

@ -10,5 +10,7 @@ void swap(char * x, char * y);
char * reverse(char * buffer, int i, int j);
int abs(int value);
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

View File

@ -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);
char isEmpty(queueADT * my_queue);
processADT * dequeue(queueADT * my_queue);
queueADT createQueue();
// void queue(queueADT * my_queue, processADT * process);
// char isEmpty(queueADT * my_queue);
// processADT * dequeue(queueADT * my_queue);
// queueADT createQueue();

View File

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

View File

@ -83,7 +83,7 @@ static void startOver() {
}
clear();
cleanProcesses();
// cleanProcesses();
moveToWindowVideo(1);
//((fn)sampleCodeAddress)();
}

View File

@ -28,12 +28,12 @@ void load_idt() {
setup_IDT_entry (0x06, (uint64_t)&_exception6Handler);
setup_IDT_entry (0x80, (uint64_t)&_systemCallsHandler);
setup_IDT_entry (0x81, (uint64_t)&_switchContext);
// setup_IDT_entry (0x81, (uint64_t)&_switchContext);
picMasterMask(0xFC);
picSlaveMask(0xFF);
_sti();
// _sti();
}
static void setup_IDT_entry (int index, uint64_t offset) {

View File

@ -1,7 +1,7 @@
#include <stdint.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) {
case 0:
return write(rsi, rdx, rcx);
@ -10,7 +10,8 @@ uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_
case 2:
return getTime(rsi, rdx, rcx);
case 3:
createProcess(rsi);
// createProcess(rsi);
enqueueProcess(rsi, rdx, rcx, r8);
break;
default:
return -1;

View File

@ -1,5 +1,5 @@
#include <stdint.h>
#include <string.h>
// #include <string.h>
#include <lib.h>
#include <moduleLoader.h>
#include <naiveConsole.h>
@ -140,7 +140,17 @@ void test_mm(){
// new_line();
}
}
void enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]);
void initScheduler();
void _cli();
void _sti();
void haltcpu();
int main() {
// _cli();
load_idt();
// if (initMemoryManager(memoryModuleAddress, memoryModuleAddress + sizeof(void *)) == -1) {
@ -150,6 +160,7 @@ int main() {
// }
initMemoryManager(memoryModuleAddress);
initScheduler();
#ifndef BUDDY
// SACAR DESPUÉS! ES SOLO PARA TESTEO... CORRER DE A UNO!
@ -159,12 +170,17 @@ int main() {
// return EXIT_FAILURE;
#endif
// test_mm();
saveSampleRSP(getRSP());
// ((EntryPoint)sampleCodeModuleAddress)();
char * argv[] = {"SampleCode"};
enqueueProcess(sampleCodeModuleAddress, 1, 1, argv);
// haltcpu();
_sti();
printBottlerAndWait();
((EntryPoint)sampleCodeModuleAddress)();
return EXIT_SUCCESS;
}
@ -203,7 +219,7 @@ void printBottlerAndWait() {
printStringLen(13, " %%%%%%% ", 80); new_line();
printStringLen(13, " ", 80); new_line();
wait(3);
// wait(3);
clear();
}

View File

@ -97,4 +97,16 @@ char * itoa(int value, char * buffer, int base, int length) {
buffer[i] = '\0';
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;
}

View File

@ -1,36 +1,36 @@
#include "pcb.h"
static const uint8_t * firstProcessAddress = (uint8_t *) 0x18000000;
static const long stackSize = 0x4000000; // 2^26
static const uint8_t * lastProcessAddress = (uint8_t *) 0x10000001; // 2^29 - 1
// static const uint8_t * firstProcessAddress = (uint8_t *) 0x18000000;
// static const long stackSize = 0x4000000; // 2^26
// static const uint8_t * lastProcessAddress = (uint8_t *) 0x10000001; // 2^29 - 1
int activeProcesses = 0, currentProcess = -1;
uint64_t priority0[MAX_PROCESSES];
uint64_t priority1[MAX_PROCESSES];
uint64_t priority2[MAX_PROCESSES];
// int activeProcesses = 0, currentProcess = -1;
// uint64_t priority0[MAX_PROCESSES];
// uint64_t priority1[MAX_PROCESSES];
// uint64_t priority2[MAX_PROCESSES];
void cleanProcesses() {
activeProcesses = 0;
currentProcess = -1;
}
// void cleanProcesses() {
// activeProcesses = 0;
// currentProcess = -1;
// }
void newProcess(void (*fn)) {
if (firstProcessAddress - activeProcesses * stackSize + stackSize <= lastProcessAddress) return;
_initialize_stack_frame(fn, firstProcessAddress - activeProcesses * stackSize);
}
// void newProcess(void (*fn)) {
// if (firstProcessAddress - activeProcesses * stackSize + stackSize <= lastProcessAddress) return;
// _initialize_stack_frame(fn, firstProcessAddress - activeProcesses * stackSize);
// }
void newStack(uint64_t rsp) {
priority0[activeProcesses++] = rsp;
}
// void newStack(uint64_t rsp) {
// priority0[activeProcesses++] = rsp;
// }
uint64_t preserveStack(uint64_t rsp) {
if (currentProcess != -1) {
priority0[currentProcess] = rsp;
}
if (++currentProcess >= activeProcesses) currentProcess = 0;
if (activeProcesses == 0) return 0;
return priority0[currentProcess];
}
// uint64_t preserveStack(uint64_t rsp) {
// if (currentProcess != -1) {
// priority0[currentProcess] = rsp;
// }
// if (++currentProcess >= activeProcesses) currentProcess = 0;
// if (activeProcesses == 0) return 0;
// return priority0[currentProcess];
// }
static uint64_t sampleRSP;

View File

@ -1,51 +1,51 @@
#include "queue.h"
#include "memManager.h"
#include <stdint.h>
// #include "queue.h"
// #include "memManager.h"
// #include <stdint.h>
typedef struct nodeT {
processADT * process;
struct nodeT * next;
} nodeT;
// typedef struct nodeT {
// processADT * process;
// struct nodeT * next;
// } nodeT;
typedef struct queueCDT {
nodeT * first;
nodeT * last;
int length;
} queueCDT;
// typedef struct queueCDT {
// nodeT * first;
// nodeT * last;
// int length;
// } queueCDT;
queueADT createQueue() {
queueADT aux = pvPortMalloc(sizeof(queueCDT));
if (aux == NULL)
return NULL;
aux->first = NULL;
aux->last = NULL;
aux->length = 0;
return aux;
}
// queueADT createQueue() {
// queueADT aux = pvPortMalloc(sizeof(queueCDT));
// if (aux == NULL)
// return NULL;
// aux->first = NULL;
// aux->last = NULL;
// aux->length = 0;
// return aux;
// }
void queue(queueADT * my_queue, processADT * process) {
if (my_queue == NULL)
return;
nodeT * new_node = pvPortMalloc(sizeof(nodeT));
if (new_node == NULL)
return;
new_node->process = process;
new_node->next = NULL;
(*my_queue)->last->next = new_node;
(*my_queue)->last = new_node;
(*my_queue)->length++;
}
// void queue(queueADT * my_queue, processADT * process) {
// if (my_queue == NULL)
// return;
// nodeT * new_node = pvPortMalloc(sizeof(nodeT));
// if (new_node == NULL)
// return;
// new_node->process = process;
// new_node->next = NULL;
// (*my_queue)->last->next = new_node;
// (*my_queue)->last = new_node;
// (*my_queue)->length++;
// }
processADT * dequeue(queueADT * my_queue) {
if (my_queue == NULL || isEmpty(my_queue))
return NULL;
nodeT * aux = (*my_queue)->first;
(*my_queue)->first = (*my_queue)->first->next;
processADT * ans = aux->process;
vPortFree(aux);
return ans;
}
// processADT * dequeue(queueADT * my_queue) {
// if (my_queue == NULL || isEmpty(my_queue))
// return NULL;
// nodeT * aux = (*my_queue)->first;
// (*my_queue)->first = (*my_queue)->first->next;
// processADT * ans = aux->process;
// vPortFree(aux);
// return ans;
// }
char isEmpty(queueADT * my_queue) {
return (*my_queue)->length == 0;
}
// char isEmpty(queueADT * my_queue) {
// return (*my_queue)->length == 0;
// }

View File

@ -1,172 +1,101 @@
#include "scheduler.h"
#include "queue.h"
#include <stdint.h>
#include <stddef.h>
#include "memManager.h"
void forceTimer();
#define STACK_SIZE 1024
void _initialize_stack_frame(void *, void *, int, char**);
enum states {READY = 0, BLOCKED};
typedef struct processCDT {
struct processCDT * next;
char * name;
int pid;
int ppid;
uint64_t rsp;
uint64_t rbp;
char priority;
char executions;
char foreground;
enum states state;
} processCDT;
typedef struct nodeT {
processADT * process;
struct nodeT * next;
struct nodeT * previous;
} nodeT;
processCDT * firstReady = NULL;
processCDT * lastReady = NULL;
processCDT * firstBlocked = NULL;
processCDT * lastBlocked = NULL;
typedef struct listT {
nodeT * first;
nodeT * last;
int length;
} listT;
int readyLen = 0;
int blockedLen = 0;
listT * ready = {NULL, NULL, 0};
listT * blocked = {NULL, NULL, 0};
nodeT * current = NULL;
processCDT * currentProcess = NULL;
int pids = 0;
processADT * next() {
if (ready->first == NULL)
return NULL;
current = current->next;
if (current == NULL)
current = ready->first;
return current->process;
uint64_t nextProcess() {
if (currentProcess == NULL)
return firstReady->rsp;
if (currentProcess->executions < MAX_PRIORITY - currentProcess->priority + 1) {
currentProcess->executions++;
return currentProcess->rsp;
}
currentProcess->executions = 0;
currentProcess = currentProcess->next;
return currentProcess->rsp;
}
// void init() {
// new(idle, )
// }
void idle() {
while (1) {
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));
nodeT * node = pvPortMalloc(sizeof(nodeT));
uint64_t * rbp = pvPortMalloc(STACK_SIZE);
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);
if (current != NULL && foreground) {
block((*current->process)->pid);
return;
}
if (firstReady == NULL)
firstReady = proc;
else
lastReady->next = proc;
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 = name;
process->name = aux;
process->pid = pids++;
process->ppid = (*current->process)->pid;
process->foreground = foreground;
process->ppid = currentProcess->pid;
process->priority = priority;
process->rsp = rsp;
process->rbp = rbp;
process->executions = 0;
process->foreground = foreground;
process->state = READY;
process->rbp = STACK_SIZE;
}
void loader(int argc, char * argv[], void (*fn) (int, char **)) {
fn(argc, argv);
exit();
}
// void loader(int argc, char * argv[], void (*fn) (int, char **)) {
// fn(argc, argv);
// exit();
// }
void exit() {
kill((*current->process)->pid);
}
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;
processCDT * search(processCDT ** previous, int pid, processCDT * first) {
processCDT * curr = first;
* previous = NULL;
while (curr != NULL) {
if ((*curr->process)->pid == pid) {
if (curr->pid == pid) {
break;
}
* previous = curr;
@ -176,20 +105,197 @@ nodeT * search(nodeT ** previous, int pid, listT * list) {
* previous = NULL;
return NULL;
}
if (curr = list->first) {
if (curr == first) {
* previous = NULL;
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.
Obtener el ID del proceso que llama.
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.
Matar un proceso arbitrario.
Modificar la prioridad de un proceso arbitrario.
Bloquear y desbloquear un proceso arbitrario.
Renunciar al CPU
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

@ -147,11 +147,20 @@ sys_loadProcess:
push rdi
push rsi
push rdx
push rcx
push r8
mov r8, rcx
mov rcx, rdx
mov rdx, rsi
mov rsi, rdi
mov rdi, 3
int 80h
pop r8
pop rcx
pop rdx
pop rsi
pop rdi

View File

@ -1,8 +1,8 @@
#ifndef SYSTEM_H
#define SYSTEM_H
void sys_switchContext();
void sys_loadProcess();
// void sys_switchContext();
// void sys_loadProcess();
int sys_time(char);
void sys_write(int, char *, int);
char sys_read(int, char *, int);

View File

@ -2,16 +2,17 @@
#include "libc.h"
#include "shell/include/shell.h"
void sys_loadProcess(void (*fn));
void sys_switchContext();
void sys_loadProcess(void (*fn) (int, char **), char foreground, int argc, char *argv[]);
// void sys_switchContext();
int main() {
winClear();
sys_loadProcess(shell);
sys_loadProcess(shell);
char * argv[] = {"BottlerSh"};
sys_loadProcess(shell, 1, 1, argv);
// sys_loadProcess(shell);
sys_switchContext();
// sys_switchContext();
return 1;
}

View File

@ -3,7 +3,7 @@
#include "system.h"
void shell(void);
void shell(int argc, char *argv[]);
void printWindow(char * window);
void addText(char * buffer, char * window, int * offset);
void incorrect_comm(char * buffer, char * window, int * offset);

View File

@ -50,9 +50,10 @@ void scanfNoPrint(char * buffer, int maxSize, char * window, int * offset) {
int i = 0;
while ((c = getChar()) != '\n' && i < maxSize - 1) {
if (c != -1) {
if (c == '\v')
sys_switchContext();
else if (c == '\b' && i > 0) {
// if (c == '\v')
// sys_switchContext();
// else if (c == '\b' && i > 0) {
if (c == '\b' && i > 0) {
buffer[--i] = ' ';
window[--(*offset)] = ' ';
printWindow(window);
@ -79,7 +80,7 @@ void clearWindow(char * window, int * offset) {
printWindow(window);
}
void shell() {
void shell(int argc, char *argv[]) {
char window[ROWS * COLS + 1] = {[0 ... ROWS * COLS - 1] = ' ', 0};
int offset = (ROWS - 1) * COLS;