Added sleep syscall

This commit is contained in:
Xnoe 2022-04-08 02:01:25 +01:00
parent c2f857fc88
commit 7e5f20ef66
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
9 changed files with 75 additions and 29 deletions

View File

@ -52,6 +52,10 @@ void kill(uint32_t pid) {
asm volatile("mov $17, %%eax; mov %0, %%esi; int $0x7f" : : "m" (pid) : "esi");
}
void sleep(uint32_t time) {
asm volatile("mov $18, %%eax; mov %0, %%esi; int $0x7f" : : "m" (time) : "esi");
}
void bindToKeyboard() {
asm volatile ("mov $12, %%eax; int $0x7f" : : :);
}

View File

@ -22,6 +22,7 @@ void bindToKeyboard();
int fopen(char* filename);
void fclose(uint32_t fh);
void kill(uint32_t pid);
void sleep(uint32_t time);
int int_to_decimal(unsigned int number, char* string_buffer);
int int_to_hex(unsigned int number, char* string_buffer);

View File

@ -105,10 +105,10 @@ namespace xnoe {
current->next->prev = current->prev;
if (current == start)
start = 0;
start = current->next;
if (current = end)
end = 0;
end = current->prev;
return;
}

View File

@ -97,30 +97,32 @@ void context_switch(frame_struct* frame) {
// - Determines if it has 2 or more elements
// - If it has two, swap the first and last, update prev and next of each to be null or the other item
// - If it has more than two, add the start to the end then set start to the second element
if (Global::currentProc) {
if (processes->start->next != 0) {
if (processes->end->prev == processes->start) {
xnoe::linkedlistelem<Process*>* tmp = processes->start;
processes->start = processes->end;
processes->end = tmp;
do {
if (Global::currentProc) {
if (processes->start->next != 0) {
if (processes->end->prev == processes->start) {
xnoe::linkedlistelem<Process*>* tmp = processes->start;
processes->start = processes->end;
processes->end = tmp;
processes->start->prev = 0;
processes->end->next = 0;
processes->end->prev = processes->start;
processes->start->next = processes->end;
} else {
processes->end->next = processes->start;
processes->start = processes->start->next;
processes->start->prev = 0;
xnoe::linkedlistelem<Process*>* tmp = processes->end;
processes->end = processes->end->next;
processes->end->next = 0;
processes->end->prev = tmp;
processes->start->prev = 0;
processes->end->next = 0;
processes->end->prev = processes->start;
processes->start->next = processes->end;
} else {
processes->end->next = processes->start;
processes->start = processes->start->next;
processes->start->prev = 0;
xnoe::linkedlistelem<Process*>* tmp = processes->end;
processes->end = processes->end->next;
processes->end->next = 0;
processes->end->prev = tmp;
}
}
}
}
Global::currentProc = processes->start->elem;
} while (Global::currentProc->state == Suspended);
Global::currentProc = processes->start->elem;
// Select the next processes page directory
frame->new_cr3 = Global::currentProc->PD->phys_addr;
@ -134,7 +136,8 @@ void context_switch(frame_struct* frame) {
}
namespace Timer {
using TimedEvent = xnoe::tuple<uint32_t, uint32_t, void(*)(frame_struct*, void*), void*>;
// counter, default count, function, argument, oneshot
using TimedEvent = xnoe::tuple<uint32_t, uint32_t, void(*)(frame_struct*, void*), void*, bool>;
xnoe::linkedlist<TimedEvent> timed_events;
void tick(frame_struct* frame) {
xnoe::linkedlistelem<TimedEvent>* current = timed_events.start;
@ -144,17 +147,28 @@ namespace Timer {
if (--count == 0) {
xnoe::get<2>(t)(frame, xnoe::get<3>(t));
count = xnoe::get<1>(t);
if (xnoe::get<4>(t)) {
xnoe::linkedlistelem<TimedEvent>* prev = current;
current = current->next;
timed_events.remove(prev);
delete prev;
}
}
current->elem = TimedEvent(count, xnoe::get<1>(t), xnoe::get<2>(t), xnoe::get<3>(t));
current->elem = TimedEvent(count, xnoe::get<1>(t), xnoe::get<2>(t), xnoe::get<3>(t), xnoe::get<4>(t));
current = current->next;
}
}
void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary) {
timed_events.append(TimedEvent(milliseconds, milliseconds, function, auxiliary));
void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary, bool oneshot=false) {
timed_events.append(TimedEvent(milliseconds, milliseconds, function, auxiliary, oneshot));
}
}
void awaken(frame_struct* frame, Process* p) {
p->state = Running;
}
void syscall(frame_struct* frame) {
// Syscall ABI:
// 0: X
@ -179,6 +193,8 @@ void syscall(frame_struct* frame) {
// 17: kill :: int PID esi -> void // Destroys a process.
// 18: sleep :: int time ms esi -> void // Sleeps the current process for esi milliseconds.
// File handlers:
// 0: Stdout
// 1: Stdin
@ -324,6 +340,13 @@ void syscall(frame_struct* frame) {
break;
}
case 18: {
Global::currentProc->state = Suspended;
Timer::register_event(esi, &awaken, (void*)Global::currentProc, true);
context_switch(frame);
break;
}
default:
break;
}

View File

@ -22,6 +22,7 @@ Process::Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageM
this->page_remaining = 0;
this->last_page_pointer = virt_alloc_base;
this->stack = stack;
this->state = Running;
}
Process::Process(uint32_t PID)
@ -31,6 +32,7 @@ Process::Process(uint32_t PID)
this->last_page_pointer = 0;
this->stack = this->allocate(0x8000);
this->kernelStackPtr = (new uint8_t[0x1000]) + 0x1000;
this->state = Running;
}
Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uint32_t fh)
@ -43,6 +45,7 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uin
this->PID = PID;
this->page_remaining = 0;
this->last_page_pointer = 0;
this->state = Running;
for (int index = inheritBase >> 22; index < 1024; index++)
this->PD->page_directory[index] = inherit->page_directory[index];

View File

@ -20,6 +20,11 @@ struct AllocTracker {
AllocTracker(void* base, uint32_t size, uint32_t count);
};
enum ProcessState {
Running,
Suspended
};
class Process : public Allocator {
private:
uint32_t last_page_pointer;
@ -44,6 +49,8 @@ public:
bool firstRun;
ProcessState state;
Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
Process(uint32_t PID);
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uint32_t fh);

View File

@ -14,7 +14,7 @@
struct frame_struct;
namespace Timer {
void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary);
void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary, bool oneshot=false);
}
class Terminal: public ReadWriter {

View File

@ -0,0 +1,8 @@
#include "common/common.h"
int main() {
while (1) {
print("Hello, World!\n");
sleep(200);
}
}

View File

@ -187,7 +187,7 @@ int main() {
uint32_t p1out = bindStdout(p1);
uint32_t p1in = bindStdin(p1);
fclose(program);
program = fopen("/hello.bin");
program = fopen("/timer.bin");
uint32_t p2 = fork(program);
uint32_t p2out = bindStdout(p2);
uint32_t p2in = bindStdin(p2);