Compare commits
3 Commits
e34045a78c
...
c2fa4f380d
Author | SHA1 | Date | |
---|---|---|---|
c2fa4f380d | |||
ce10fb5743 | |||
891651f2d6 |
@ -48,10 +48,16 @@ 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 save_context(Context* context);
|
||||||
|
void restore_context(Context* context);
|
||||||
|
|
||||||
|
void save_floating();
|
||||||
|
void restore_floating();
|
||||||
|
|
||||||
|
void switch_to_address_space();
|
||||||
|
|
||||||
|
bool has_died();
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_context_from_task(Task& task, Context* ctx);
|
|
||||||
void get_context_to_task(Task& task, Context* ctx);
|
|
||||||
|
|
||||||
void task_save_floating(Task& task);
|
|
||||||
void task_restore_floating(Task& task);
|
|
@ -99,7 +99,7 @@ void sys_exec(Context* context, const char* pathname)
|
|||||||
|
|
||||||
Scheduler::reset_task(task, image);
|
Scheduler::reset_task(task, image);
|
||||||
|
|
||||||
set_context_from_task(*task, context);
|
task->restore_context(context);
|
||||||
|
|
||||||
kfree(kpathname);
|
kfree(kpathname);
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#define FNCTL_DUPFD 0
|
#define FNCTL_DUPFD 0
|
||||||
|
|
||||||
void sys_fcntl(Context* context, int fd, int command, [[maybe_unused]] uintptr_t arg)
|
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg)
|
||||||
{
|
{
|
||||||
if (fd >= TASK_MAX_FDS || fd < 0)
|
if (fd >= TASK_MAX_FDS || fd < 0)
|
||||||
{
|
{
|
||||||
@ -34,10 +34,14 @@ void sys_fcntl(Context* context, int fd, int command, [[maybe_unused]] uintptr_t
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Descriptor& file = current_task->files[fd];
|
Descriptor& file = current_task->files[fd];
|
||||||
if (command == FNCTL_DUPFD) // FIXME: If arg is greater than 0, return the lowest numbered available file descriptor
|
if (command == FNCTL_DUPFD)
|
||||||
// greater than or equal to arg.
|
|
||||||
{
|
{
|
||||||
int dupfd = current_task->alloc_fd();
|
if ((int)arg < 0 || (int)arg >= TASK_MAX_FDS)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
@ -320,7 +320,7 @@ void Scheduler::task_yield(Context* context)
|
|||||||
{
|
{
|
||||||
ASSERT(Interrupts::is_in_handler());
|
ASSERT(Interrupts::is_in_handler());
|
||||||
Interrupts::disable();
|
Interrupts::disable();
|
||||||
get_context_to_task(*sched_current_task, context);
|
sched_current_task->save_context(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,15 +334,14 @@ 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->state != original_task->Exited)
|
if (!was_idle && original_task->is_user_task() && !original_task->has_died())
|
||||||
{
|
{
|
||||||
task_save_floating(*original_task);
|
original_task->save_floating();
|
||||||
}
|
}
|
||||||
if (sched_current_task->is_user_task())
|
if (sched_current_task->is_user_task())
|
||||||
{
|
{
|
||||||
VMM::switch_to_user_address_space(sched_current_task->address_space);
|
sched_current_task->switch_to_address_space();
|
||||||
VMM::apply_address_space();
|
sched_current_task->restore_floating();
|
||||||
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())
|
||||||
{
|
{
|
||||||
@ -351,17 +350,17 @@ void Scheduler::task_yield(Context* context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sched_current_task->task_time = 20;
|
sched_current_task->task_time = 20;
|
||||||
set_context_from_task(*sched_current_task, context);
|
sched_current_task->restore_context(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)
|
||||||
{
|
{
|
||||||
task_save_floating(*original_task);
|
original_task->save_floating();
|
||||||
}
|
}
|
||||||
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) { set_context_from_task(*sched_current_task, context); }
|
if (!was_idle) { sched_current_task->restore_context(context); }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,26 +1,27 @@
|
|||||||
#include "thread/Task.h"
|
#include "thread/Task.h"
|
||||||
|
#include "memory/VMM.h"
|
||||||
#include "std/string.h"
|
#include "std/string.h"
|
||||||
|
|
||||||
void set_context_from_task(Task& task, Context* ctx)
|
void Task::restore_context(Context* context)
|
||||||
{
|
{
|
||||||
memcpy(ctx, &task.regs, sizeof(Context));
|
memcpy(context, ®s, sizeof(Context));
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_context_to_task(Task& task, Context* ctx)
|
void Task::save_context(Context* context)
|
||||||
{
|
{
|
||||||
memcpy(&task.regs, ctx, sizeof(Context));
|
memcpy(®s, context, sizeof(Context));
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_save_floating(Task& task)
|
void Task::save_floating()
|
||||||
{
|
{
|
||||||
task.floating_saved = true;
|
floating_saved = true;
|
||||||
asm volatile("fxsave (%0)" : : "r"(&task.floating_region));
|
asm volatile("fxsave (%0)" : : "r"((char*)floating_region));
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_restore_floating(Task& task)
|
void Task::restore_floating()
|
||||||
{
|
{
|
||||||
if (!task.floating_saved) return;
|
if (!floating_saved) return;
|
||||||
asm volatile("fxrstor (%0)" : : "r"(&task.floating_region));
|
asm volatile("fxrstor (%0)" : : "r"((char*)floating_region));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Task::is_user_task()
|
bool Task::is_user_task()
|
||||||
@ -40,3 +41,28 @@ int Task::alloc_fd()
|
|||||||
|
|
||||||
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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user