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");
|
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" : : :);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,7 @@ 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
|
||||||
|
do {
|
||||||
if (Global::currentProc) {
|
if (Global::currentProc) {
|
||||||
if (processes->start->next != 0) {
|
if (processes->start->next != 0) {
|
||||||
if (processes->end->prev == processes->start) {
|
if (processes->end->prev == processes->start) {
|
||||||
@ -119,8 +120,9 @@ void context_switch(frame_struct* frame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Global::currentProc = processes->start->elem;
|
Global::currentProc = processes->start->elem;
|
||||||
|
} while (Global::currentProc->state == Suspended);
|
||||||
|
|
||||||
|
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
|
@ -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];
|
||||||
|
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
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 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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user