Added sleep syscall
This commit is contained in:
parent
c2f857fc88
commit
7e5f20ef66
@ -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" : : :);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
8
src/programs/timer/timer.c
Normal file
8
src/programs/timer/timer.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include "common/common.h"
|
||||
|
||||
int main() {
|
||||
while (1) {
|
||||
print("Hello, World!\n");
|
||||
sleep(200);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user