mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Added some support for blocking system calls in the kernel.
This commit is contained in:
parent
cfd7648ca9
commit
851ee78903
6 changed files with 86 additions and 4 deletions
|
@ -130,6 +130,8 @@ namespace Sortix
|
|||
currentthread = nextthread;
|
||||
|
||||
LogEndContextSwitch(currentthread, regs);
|
||||
|
||||
if ( currentthread->scfunc ) { Syscall::Resume(regs); }
|
||||
}
|
||||
|
||||
void ProcessTerminated(CPU::InterruptRegisters* regs)
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace Sortix
|
|||
extern "C"
|
||||
{
|
||||
CPU::SyscallRegisters* syscall_state_ptr;
|
||||
int system_was_incomplete;
|
||||
unsigned system_was_incomplete;
|
||||
size_t SYSCALL_MAX = SYSCALL_MAX_NUM;
|
||||
void* syscall_list[SYSCALL_MAX_NUM];
|
||||
}
|
||||
|
@ -70,11 +70,13 @@ namespace Sortix
|
|||
|
||||
void Incomplete()
|
||||
{
|
||||
Thread* thread = CurrentThread();
|
||||
|
||||
system_was_incomplete = 1;
|
||||
|
||||
CPU::InterruptRegisters* regs = InterruptRegs();
|
||||
CurrentThread()->SaveRegisters(regs);
|
||||
// TODO: Make the thread blocking if not already.
|
||||
thread->SaveRegisters(regs);
|
||||
Scheduler::SetThreadState(thread, Thread::State::BLOCKING);
|
||||
Scheduler::Switch(regs);
|
||||
}
|
||||
|
||||
|
@ -83,6 +85,42 @@ namespace Sortix
|
|||
system_was_incomplete = 1;
|
||||
}
|
||||
|
||||
void ScheduleResumption(Thread* thread)
|
||||
{
|
||||
Scheduler::SetThreadState(thread, Thread::State::RUNNABLE);
|
||||
}
|
||||
|
||||
extern "C" size_t resume_syscall(void* scfunc, size_t scsize, size_t* scstate);
|
||||
|
||||
void Resume(CPU::InterruptRegisters* regs)
|
||||
{
|
||||
Thread* thread = CurrentThread();
|
||||
|
||||
syscall_state_ptr = (CPU::SyscallRegisters*) regs;
|
||||
|
||||
ASSERT(thread->scfunc);
|
||||
|
||||
size_t* scstate = thread->scstate;
|
||||
size_t scsize = thread->scsize;
|
||||
void* scfunc = thread->scfunc;
|
||||
|
||||
system_was_incomplete = 0;
|
||||
|
||||
size_t result = resume_syscall(scfunc, scsize, scstate);
|
||||
|
||||
bool incomplete = (system_was_incomplete);
|
||||
|
||||
system_was_incomplete = 1;
|
||||
|
||||
if ( !incomplete )
|
||||
{
|
||||
syscall_state_ptr->result = result;
|
||||
return;
|
||||
}
|
||||
|
||||
Incomplete();
|
||||
}
|
||||
|
||||
CPU::InterruptRegisters* InterruptRegs()
|
||||
{
|
||||
return (CPU::InterruptRegisters*) syscall_state_ptr;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
namespace Sortix
|
||||
{
|
||||
class Thread;
|
||||
|
||||
namespace Syscall
|
||||
{
|
||||
void Init();
|
||||
|
@ -45,6 +47,14 @@ namespace Sortix
|
|||
// For when you want the syscall exit code not to modify registers.
|
||||
void AsIs();
|
||||
|
||||
// Retries a system call by making the thread runnable and then calling
|
||||
// the system call code whenever the thread is scheduled to run.
|
||||
void ScheduleResumption(Thread* thread);
|
||||
|
||||
// Retries a system call based on the Thread::sc* values of the current
|
||||
// thread and if it succeeds, sets the proper registers.
|
||||
void Resume(CPU::InterruptRegisters* regs);
|
||||
|
||||
CPU::InterruptRegisters* InterruptRegs();
|
||||
CPU::SyscallRegisters* SyscallRegs();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ namespace Sortix
|
|||
schedulerlistnext = NULL;
|
||||
state = NONE;
|
||||
Maxsi::Memory::Set(®isters, 0, sizeof(registers));
|
||||
ready = false;
|
||||
ready = false;
|
||||
scfunc = NULL;
|
||||
}
|
||||
|
||||
Thread::Thread(const Thread* forkfrom)
|
||||
|
@ -62,6 +63,7 @@ namespace Sortix
|
|||
nextsleepingthread = NULL;
|
||||
schedulerlistprev = NULL;
|
||||
schedulerlistnext = NULL;
|
||||
scfunc = NULL;
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
|
|
|
@ -83,6 +83,11 @@ namespace Sortix
|
|||
Thread* Fork();
|
||||
void SaveRegisters(const CPU::InterruptRegisters* src);
|
||||
void LoadRegisters(CPU::InterruptRegisters* dest);
|
||||
|
||||
public:
|
||||
void* scfunc;
|
||||
size_t scsize;
|
||||
size_t scstate[8];
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
.global syscall_handler
|
||||
.global resume_syscall
|
||||
|
||||
.section .text
|
||||
.type syscall_handler, @function
|
||||
|
@ -109,3 +110,27 @@ return_to_userspace:
|
|||
# Return to user-space.
|
||||
iretl
|
||||
|
||||
.type resume_syscall, @function
|
||||
resume_syscall:
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
|
||||
movl 8(%esp), %eax
|
||||
movl 16(%esp), %ecx
|
||||
|
||||
pushl 28(%ecx)
|
||||
pushl 24(%ecx)
|
||||
pushl 20(%ecx)
|
||||
pushl 16(%ecx)
|
||||
pushl 12(%ecx)
|
||||
pushl 8(%ecx)
|
||||
pushl 4(%ecx)
|
||||
pushl 0(%ecx)
|
||||
|
||||
call *%eax
|
||||
|
||||
addl $32, %esp
|
||||
|
||||
leavel
|
||||
retl
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue