Compare commits

..

No commits in common. "c2fa4f380d53c03d232cbe4ad561a7ec526cb0e1" and "e34045a78cb58f0e4ebc67fcc21d39b583935e6f" have entirely different histories.

5 changed files with 29 additions and 64 deletions

View File

@ -48,16 +48,10 @@ struct Task
AddressSpace address_space; AddressSpace address_space;
int alloc_fd(); int alloc_fd();
};
int alloc_fd_greater_than_or_equal(int base_fd); void set_context_from_task(Task& task, Context* ctx);
void get_context_to_task(Task& task, Context* ctx);
void save_context(Context* context); void task_save_floating(Task& task);
void restore_context(Context* context); void task_restore_floating(Task& task);
void save_floating();
void restore_floating();
void switch_to_address_space();
bool has_died();
};

View File

@ -99,7 +99,7 @@ void sys_exec(Context* context, const char* pathname)
Scheduler::reset_task(task, image); Scheduler::reset_task(task, image);
task->restore_context(context); set_context_from_task(*task, context);
kfree(kpathname); kfree(kpathname);

View File

@ -20,7 +20,7 @@
#define FNCTL_DUPFD 0 #define FNCTL_DUPFD 0
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg) void sys_fcntl(Context* context, int fd, int command, [[maybe_unused]] uintptr_t arg)
{ {
if (fd >= TASK_MAX_FDS || fd < 0) if (fd >= TASK_MAX_FDS || fd < 0)
{ {
@ -34,14 +34,10 @@ void sys_fcntl(Context* context, int fd, int command, uintptr_t arg)
return; return;
} }
Descriptor& file = current_task->files[fd]; Descriptor& file = current_task->files[fd];
if (command == FNCTL_DUPFD) if (command == FNCTL_DUPFD) // FIXME: If arg is greater than 0, return the lowest numbered available file descriptor
// greater than or equal to arg.
{ {
if ((int)arg < 0 || (int)arg >= TASK_MAX_FDS) int dupfd = current_task->alloc_fd();
{
context->rax = -EINVAL;
return;
}
int dupfd = current_task->alloc_fd_greater_than_or_equal((int)arg);
if (dupfd < 0) if (dupfd < 0)
{ {
context->rax = -EMFILE; context->rax = -EMFILE;

View File

@ -320,7 +320,7 @@ void Scheduler::task_yield(Context* context)
{ {
ASSERT(Interrupts::is_in_handler()); ASSERT(Interrupts::is_in_handler());
Interrupts::disable(); Interrupts::disable();
sched_current_task->save_context(context); get_context_to_task(*sched_current_task, context);
bool was_idle = false; bool was_idle = false;
if (sched_current_task->state == sched_current_task->Idle) if (sched_current_task->state == sched_current_task->Idle)
{ {
@ -334,14 +334,15 @@ void Scheduler::task_yield(Context* context)
{ {
if (sched_current_task->id != original_task->id || was_idle) if (sched_current_task->id != original_task->id || was_idle)
{ {
if (!was_idle && original_task->is_user_task() && !original_task->has_died()) if (!was_idle && original_task->is_user_task() && original_task->state != original_task->Exited)
{ {
original_task->save_floating(); task_save_floating(*original_task);
} }
if (sched_current_task->is_user_task()) if (sched_current_task->is_user_task())
{ {
sched_current_task->switch_to_address_space(); VMM::switch_to_user_address_space(sched_current_task->address_space);
sched_current_task->restore_floating(); VMM::apply_address_space();
task_restore_floating(*sched_current_task);
} }
else if (!was_idle && original_task->is_user_task() && !sched_current_task->is_user_task()) else if (!was_idle && original_task->is_user_task() && !sched_current_task->is_user_task())
{ {
@ -350,17 +351,17 @@ void Scheduler::task_yield(Context* context)
} }
} }
sched_current_task->task_time = 20; sched_current_task->task_time = 20;
sched_current_task->restore_context(context); set_context_from_task(*sched_current_task, context);
return; return;
} }
} while (sched_current_task != original_task); } while (sched_current_task != original_task);
if (!was_idle && original_task->is_user_task() && original_task->state != original_task->Exited) if (!was_idle && original_task->is_user_task() && original_task->state != original_task->Exited)
{ {
original_task->save_floating(); task_save_floating(*original_task);
} }
sched_current_task = &idle_task; sched_current_task = &idle_task;
sched_current_task->task_time = frequency; sched_current_task->task_time = frequency;
if (!was_idle) { sched_current_task->restore_context(context); } if (!was_idle) { set_context_from_task(*sched_current_task, context); }
return; return;
} }

View File

@ -1,27 +1,26 @@
#include "thread/Task.h" #include "thread/Task.h"
#include "memory/VMM.h"
#include "std/string.h" #include "std/string.h"
void Task::restore_context(Context* context) void set_context_from_task(Task& task, Context* ctx)
{ {
memcpy(context, &regs, sizeof(Context)); memcpy(ctx, &task.regs, sizeof(Context));
} }
void Task::save_context(Context* context) void get_context_to_task(Task& task, Context* ctx)
{ {
memcpy(&regs, context, sizeof(Context)); memcpy(&task.regs, ctx, sizeof(Context));
} }
void Task::save_floating() void task_save_floating(Task& task)
{ {
floating_saved = true; task.floating_saved = true;
asm volatile("fxsave (%0)" : : "r"((char*)floating_region)); asm volatile("fxsave (%0)" : : "r"(&task.floating_region));
} }
void Task::restore_floating() void task_restore_floating(Task& task)
{ {
if (!floating_saved) return; if (!task.floating_saved) return;
asm volatile("fxrstor (%0)" : : "r"((char*)floating_region)); asm volatile("fxrstor (%0)" : : "r"(&task.floating_region));
} }
bool Task::is_user_task() bool Task::is_user_task()
@ -40,29 +39,4 @@ int Task::alloc_fd()
if (fd == TASK_MAX_FDS) { return -1; } if (fd == TASK_MAX_FDS) { return -1; }
return fd; return fd;
}
int Task::alloc_fd_greater_than_or_equal(int base_fd)
{
int fd;
if (base_fd >= TASK_MAX_FDS) return -1;
for (fd = base_fd; fd < TASK_MAX_FDS; fd++)
{
if (!files[fd].is_open()) break;
}
if (fd == TASK_MAX_FDS) { return -1; }
return fd;
}
void Task::switch_to_address_space()
{
VMM::switch_to_user_address_space(address_space);
VMM::apply_address_space();
}
bool Task::has_died()
{
return state == Exited;
} }