Added some support for blocking system calls in the kernel.
This commit is contained in:
parent
cfd7648ca9
commit
851ee78903
|
@ -130,6 +130,8 @@ namespace Sortix
|
||||||
currentthread = nextthread;
|
currentthread = nextthread;
|
||||||
|
|
||||||
LogEndContextSwitch(currentthread, regs);
|
LogEndContextSwitch(currentthread, regs);
|
||||||
|
|
||||||
|
if ( currentthread->scfunc ) { Syscall::Resume(regs); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessTerminated(CPU::InterruptRegisters* regs)
|
void ProcessTerminated(CPU::InterruptRegisters* regs)
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace Sortix
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
CPU::SyscallRegisters* syscall_state_ptr;
|
CPU::SyscallRegisters* syscall_state_ptr;
|
||||||
int system_was_incomplete;
|
unsigned system_was_incomplete;
|
||||||
size_t SYSCALL_MAX = SYSCALL_MAX_NUM;
|
size_t SYSCALL_MAX = SYSCALL_MAX_NUM;
|
||||||
void* syscall_list[SYSCALL_MAX_NUM];
|
void* syscall_list[SYSCALL_MAX_NUM];
|
||||||
}
|
}
|
||||||
|
@ -70,11 +70,13 @@ namespace Sortix
|
||||||
|
|
||||||
void Incomplete()
|
void Incomplete()
|
||||||
{
|
{
|
||||||
|
Thread* thread = CurrentThread();
|
||||||
|
|
||||||
system_was_incomplete = 1;
|
system_was_incomplete = 1;
|
||||||
|
|
||||||
CPU::InterruptRegisters* regs = InterruptRegs();
|
CPU::InterruptRegisters* regs = InterruptRegs();
|
||||||
CurrentThread()->SaveRegisters(regs);
|
thread->SaveRegisters(regs);
|
||||||
// TODO: Make the thread blocking if not already.
|
Scheduler::SetThreadState(thread, Thread::State::BLOCKING);
|
||||||
Scheduler::Switch(regs);
|
Scheduler::Switch(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +85,42 @@ namespace Sortix
|
||||||
system_was_incomplete = 1;
|
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()
|
CPU::InterruptRegisters* InterruptRegs()
|
||||||
{
|
{
|
||||||
return (CPU::InterruptRegisters*) syscall_state_ptr;
|
return (CPU::InterruptRegisters*) syscall_state_ptr;
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
|
class Thread;
|
||||||
|
|
||||||
namespace Syscall
|
namespace Syscall
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
|
@ -45,6 +47,14 @@ namespace Sortix
|
||||||
// For when you want the syscall exit code not to modify registers.
|
// For when you want the syscall exit code not to modify registers.
|
||||||
void AsIs();
|
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::InterruptRegisters* InterruptRegs();
|
||||||
CPU::SyscallRegisters* SyscallRegs();
|
CPU::SyscallRegisters* SyscallRegs();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ namespace Sortix
|
||||||
state = NONE;
|
state = NONE;
|
||||||
Maxsi::Memory::Set(®isters, 0, sizeof(registers));
|
Maxsi::Memory::Set(®isters, 0, sizeof(registers));
|
||||||
ready = false;
|
ready = false;
|
||||||
|
scfunc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread(const Thread* forkfrom)
|
Thread::Thread(const Thread* forkfrom)
|
||||||
|
@ -62,6 +63,7 @@ namespace Sortix
|
||||||
nextsleepingthread = NULL;
|
nextsleepingthread = NULL;
|
||||||
schedulerlistprev = NULL;
|
schedulerlistprev = NULL;
|
||||||
schedulerlistnext = NULL;
|
schedulerlistnext = NULL;
|
||||||
|
scfunc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::~Thread()
|
Thread::~Thread()
|
||||||
|
|
|
@ -84,6 +84,11 @@ namespace Sortix
|
||||||
void SaveRegisters(const CPU::InterruptRegisters* src);
|
void SaveRegisters(const CPU::InterruptRegisters* src);
|
||||||
void LoadRegisters(CPU::InterruptRegisters* dest);
|
void LoadRegisters(CPU::InterruptRegisters* dest);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void* scfunc;
|
||||||
|
size_t scsize;
|
||||||
|
size_t scstate[8];
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
.global syscall_handler
|
.global syscall_handler
|
||||||
|
.global resume_syscall
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
.type syscall_handler, @function
|
.type syscall_handler, @function
|
||||||
|
@ -109,3 +110,27 @@ return_to_userspace:
|
||||||
# Return to user-space.
|
# Return to user-space.
|
||||||
iretl
|
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…
Reference in New Issue