fixed multithreading!

main
Clyne 4 weeks ago
parent 56f5c483ee
commit 35aa65037b
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

@ -9,7 +9,7 @@ static void timer_callback(const Registers& regs)
{ {
ticks = ticks + 1; ticks = ticks + 1;
schedule(const_cast<Registers&>(regs)); schedule(regs);
} }
void pit_initialize(std::uint32_t frequency) void pit_initialize(std::uint32_t frequency)

@ -4,31 +4,56 @@
struct Task struct Task
{ {
Registers regs; enum class State {
bool valid = false; Invalid,
Staging,
Running
};
using enum State;
std::uint32_t esp;
std::uint32_t ebp;
State state = State::Invalid;
}; };
static std::array<Task, 4> tasks; static std::array<Task, 4> tasks;
static int current = -1; static int current = -1;
void schedule(Registers& regs) void schedule(const Registers& regs)
{ {
if (current < 0) if (current < 0)
return; return;
tasks[current].regs = regs; asm volatile(R"(
mov %%esp, %0
mov %%ebp, %1
)" : "=m" (tasks[current].esp), "=m" (tasks[current].ebp));
do { do {
if (++current >= tasks.size()) if (++current >= tasks.size())
current = 0; current = 0;
} while (!tasks[current].valid); } while (tasks[current].state == Task::Invalid);
regs = tasks[current].regs; asm volatile(R"(
mov %0, %%esp
mov %1, %%ebp
)" :: "m" (tasks[current].esp), "m" (tasks[current].ebp));
if (tasks[current].state == Task::Staging) {
tasks[current].state = Task::Running;
asm volatile(R"(
pop %eax
popa
add $0x4, %esp
iret
)");
}
} }
void tasking_initialize() void tasking_initialize()
{ {
tasks[0].valid = true; tasks[0].state = Task::Running;
current = 0; current = 0;
asm volatile("int $0x20"); asm volatile("int $0x20");
} }
@ -37,7 +62,7 @@ bool tasking_spawn(void (*entry)(), unsigned ssize)
{ {
int i = -1; int i = -1;
for (i = 0; i < tasks.size(); ++i) { for (i = 0; i < tasks.size(); ++i) {
if (!tasks[i].valid) if (tasks[i].state == Task::Invalid)
break; break;
} }
@ -46,15 +71,19 @@ bool tasking_spawn(void (*entry)(), unsigned ssize)
tasks[i] = Task(); tasks[i] = Task();
auto& r = tasks[i].regs;
auto stack = reinterpret_cast<std::uint32_t>(new std::uint8_t[ssize]); auto stack = reinterpret_cast<std::uint32_t>(new std::uint8_t[ssize]);
r.ebp = stack + ssize; const auto stackend = stack + ssize;
r.esp = r.ebp; const auto regbase = stackend - sizeof(Registers);
r.eip = reinterpret_cast<std::uint32_t>(entry); auto r = reinterpret_cast<Registers *>(regbase);
r.cs = 0x8; r->ebp = stackend;
r.eflags = tasks[current].regs.eflags; r->esp = stackend;
r->eip = reinterpret_cast<std::uint32_t>(entry);
r->cs = 0x8;
asm volatile("pushfl; pop %%eax" : "=a"(r->eflags));
tasks[i].valid = true; tasks[i].esp = regbase;
tasks[i].ebp = stackend;
tasks[i].state = Task::Staging;
return true; return true;
} }

@ -6,7 +6,7 @@
void tasking_initialize(); void tasking_initialize();
bool tasking_spawn(void (*entry)(), unsigned ssize); bool tasking_spawn(void (*entry)(), unsigned ssize);
void schedule(Registers& regs); void schedule(const Registers& regs);
#endif // TASKING_HPP #endif // TASKING_HPP

Loading…
Cancel
Save