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"); 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() { void bindToKeyboard() {
asm volatile ("mov $12, %%eax; int $0x7f" : : :); asm volatile ("mov $12, %%eax; int $0x7f" : : :);
} }

View File

@ -22,6 +22,7 @@ void bindToKeyboard();
int fopen(char* filename); int fopen(char* filename);
void fclose(uint32_t fh); void fclose(uint32_t fh);
void kill(uint32_t pid); void kill(uint32_t pid);
void sleep(uint32_t time);
int int_to_decimal(unsigned int number, char* string_buffer); int int_to_decimal(unsigned int number, char* string_buffer);
int int_to_hex(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; current->next->prev = current->prev;
if (current == start) if (current == start)
start = 0; start = current->next;
if (current = end) if (current = end)
end = 0; end = current->prev;
return; return;
} }

View File

@ -97,30 +97,32 @@ void context_switch(frame_struct* frame) {
// - Determines if it has 2 or more elements // - 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 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 it has more than two, add the start to the end then set start to the second element
if (Global::currentProc) { do {
if (processes->start->next != 0) { if (Global::currentProc) {
if (processes->end->prev == processes->start) { if (processes->start->next != 0) {
xnoe::linkedlistelem<Process*>* tmp = processes->start; if (processes->end->prev == processes->start) {
processes->start = processes->end; xnoe::linkedlistelem<Process*>* tmp = processes->start;
processes->end = tmp; processes->start = processes->end;
processes->end = tmp;
processes->start->prev = 0; processes->start->prev = 0;
processes->end->next = 0; processes->end->next = 0;
processes->end->prev = processes->start; processes->end->prev = processes->start;
processes->start->next = processes->end; processes->start->next = processes->end;
} else { } else {
processes->end->next = processes->start; processes->end->next = processes->start;
processes->start = processes->start->next; processes->start = processes->start->next;
processes->start->prev = 0; processes->start->prev = 0;
xnoe::linkedlistelem<Process*>* tmp = processes->end; xnoe::linkedlistelem<Process*>* tmp = processes->end;
processes->end = processes->end->next; processes->end = processes->end->next;
processes->end->next = 0; processes->end->next = 0;
processes->end->prev = tmp; 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 // Select the next processes page directory
frame->new_cr3 = Global::currentProc->PD->phys_addr; frame->new_cr3 = Global::currentProc->PD->phys_addr;
@ -134,7 +136,8 @@ void context_switch(frame_struct* frame) {
} }
namespace Timer { 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; xnoe::linkedlist<TimedEvent> timed_events;
void tick(frame_struct* frame) { void tick(frame_struct* frame) {
xnoe::linkedlistelem<TimedEvent>* current = timed_events.start; xnoe::linkedlistelem<TimedEvent>* current = timed_events.start;
@ -144,17 +147,28 @@ namespace Timer {
if (--count == 0) { if (--count == 0) {
xnoe::get<2>(t)(frame, xnoe::get<3>(t)); xnoe::get<2>(t)(frame, xnoe::get<3>(t));
count = xnoe::get<1>(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; current = current->next;
} }
} }
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) {
timed_events.append(TimedEvent(milliseconds, milliseconds, function, auxiliary)); timed_events.append(TimedEvent(milliseconds, milliseconds, function, auxiliary, oneshot));
} }
} }
void awaken(frame_struct* frame, Process* p) {
p->state = Running;
}
void syscall(frame_struct* frame) { void syscall(frame_struct* frame) {
// Syscall ABI: // Syscall ABI:
// 0: X // 0: X
@ -179,6 +193,8 @@ void syscall(frame_struct* frame) {
// 17: kill :: int PID esi -> void // Destroys a process. // 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: // File handlers:
// 0: Stdout // 0: Stdout
// 1: Stdin // 1: Stdin
@ -324,6 +340,13 @@ void syscall(frame_struct* frame) {
break; break;
} }
case 18: {
Global::currentProc->state = Suspended;
Timer::register_event(esi, &awaken, (void*)Global::currentProc, true);
context_switch(frame);
break;
}
default: default:
break; break;
} }

View File

@ -22,6 +22,7 @@ Process::Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageM
this->page_remaining = 0; this->page_remaining = 0;
this->last_page_pointer = virt_alloc_base; this->last_page_pointer = virt_alloc_base;
this->stack = stack; this->stack = stack;
this->state = Running;
} }
Process::Process(uint32_t PID) Process::Process(uint32_t PID)
@ -31,6 +32,7 @@ Process::Process(uint32_t PID)
this->last_page_pointer = 0; this->last_page_pointer = 0;
this->stack = this->allocate(0x8000); this->stack = this->allocate(0x8000);
this->kernelStackPtr = (new uint8_t[0x1000]) + 0x1000; this->kernelStackPtr = (new uint8_t[0x1000]) + 0x1000;
this->state = Running;
} }
Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uint32_t fh) 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->PID = PID;
this->page_remaining = 0; this->page_remaining = 0;
this->last_page_pointer = 0; this->last_page_pointer = 0;
this->state = Running;
for (int index = inheritBase >> 22; index < 1024; index++) for (int index = inheritBase >> 22; index < 1024; index++)
this->PD->page_directory[index] = inherit->page_directory[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); AllocTracker(void* base, uint32_t size, uint32_t count);
}; };
enum ProcessState {
Running,
Suspended
};
class Process : public Allocator { class Process : public Allocator {
private: private:
uint32_t last_page_pointer; uint32_t last_page_pointer;
@ -44,6 +49,8 @@ public:
bool firstRun; 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, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
Process(uint32_t PID); Process(uint32_t PID);
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uint32_t fh); Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uint32_t fh);

View File

@ -14,7 +14,7 @@
struct frame_struct; struct frame_struct;
namespace Timer { 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 { 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 p1out = bindStdout(p1);
uint32_t p1in = bindStdin(p1); uint32_t p1in = bindStdin(p1);
fclose(program); fclose(program);
program = fopen("/hello.bin"); program = fopen("/timer.bin");
uint32_t p2 = fork(program); uint32_t p2 = fork(program);
uint32_t p2out = bindStdout(p2); uint32_t p2out = bindStdout(p2);
uint32_t p2in = bindStdin(p2); uint32_t p2in = bindStdin(p2);