Skip to content

Commit

Permalink
Save/restore FPU state only on switches from/to userland; move state …
Browse files Browse the repository at this point in the history
…restoring to end of ISRs
  • Loading branch information
maxdev1 committed Feb 12, 2025
1 parent 9a873b6 commit 56f1504
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 15 deletions.
6 changes: 1 addition & 5 deletions kernel/src/kernel/logger/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,8 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "shared/logger/logger.hpp"
#include "kernel/system/interrupts/interrupts.hpp"
#include "kernel/system/smp.hpp"
#include "shared/system/mutex.hpp"
#include "shared/system/spinlock.hpp"
#include "shared/utils/string.hpp"
#include "shared/video/console_video.hpp"
#include "kernel/system/interrupts/interrupts.hpp"

g_spinlock loggerLock = 0;

Expand Down
2 changes: 2 additions & 0 deletions kernel/src/kernel/system/interrupts/interrupts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ extern "C" volatile g_processor_state* _interruptHandler(volatile g_processor_st
auto newTask = taskingGetCurrentTask();
if(!newTask || !newTask->state)
panic("%! attempted to switch to null task (%x) or state (%x)", "system", newTask, newTask->state);
if(newTask != task)
taskingRestoreState(newTask);
return newTask->state;
}

Expand Down
1 change: 1 addition & 0 deletions kernel/src/kernel/tasking/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct g_task
g_task_status status;
g_task_type type;
g_mutex lock;
int interruptionLevel;

/**
* Flag that is only relevant when this task is spawned from an executable. After the task has
Expand Down
20 changes: 11 additions & 9 deletions kernel/src/kernel/tasking/tasking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,22 +280,25 @@ void taskingSaveState(g_task* task, g_processor_state* state)
// Save latest pointer to interrupt stack top
task->state = state;

// Increase interruption counter
task->interruptionLevel++;

// Save FPU state
if(task->fpu.state)
if(task->interruptionLevel == 0 && task->fpu.state)
{
processorSaveFpuState(task->fpu.state);
task->fpu.stored = true;
}
}


void taskingApplySwitch()
void taskingRestoreState(g_task* task)
{
g_task* task = taskingGetCurrentTask();
if(!task)
{
panic("%! tried to restore without a current task", "tasking");
}

// Decrease interruption counter
task->interruptionLevel--;

// Switch to process address space
if(task->overridePageDirectory)
Expand All @@ -314,17 +317,15 @@ void taskingApplySwitch()
gdtSetTssEsp0(task->interruptStack.end);

// Restore FPU state
if(task->fpu.stored)
if(task->interruptionLevel == 0 && task->fpu.stored)
{
processorRestoreFpuState(task->fpu.state);
}
}

void taskingSchedule()
{
auto local = taskingGetLocal();
schedulerSchedule(local);
taskingApplySwitch();
schedulerSchedule(taskingGetLocal());
}

g_process* taskingCreateProcess(g_security_level securityLevel)
Expand Down Expand Up @@ -461,6 +462,7 @@ void taskingInitializeTask(g_task* task, g_process* process, g_security_level le
task->process = process;
task->securityLevel = level;
task->status = G_TASK_STATUS_RUNNING;
task->interruptionLevel = 1;
waitQueueInitialize(&task->waitersJoin);
mutexInitializeNonInterruptible(&task->lock, __func__);
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/kernel/tasking/tasking.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ void taskingSaveState(g_task* task, g_processor_state* state);
* Applies the context switch to the task which is the current one for this core. This sets
* the correct page directory and TLS variables.
*/
void taskingApplySwitch();
void taskingRestoreState(g_task* task);

/**
* Yields control to the next task. This can only be called while no mutexes
Expand Down

0 comments on commit 56f1504

Please sign in to comment.