Clean up scheduler.
This commit is contained in:
parent
ae364db284
commit
8c2befc140
|
@ -318,8 +318,8 @@ Process* FindProcess(pid_t least_pid, pid_t max_pid)
|
||||||
if ( least_pid <= current_process->pid && current_process->pid <= max_pid )
|
if ( least_pid <= current_process->pid && current_process->pid <= max_pid )
|
||||||
best = current_process;
|
best = current_process;
|
||||||
Thread* first_thread = current_thread;
|
Thread* first_thread = current_thread;
|
||||||
for ( Thread* iter = first_thread->schedulerlistnext;
|
for ( Thread* iter = first_thread->scheduler_list_next;
|
||||||
iter != first_thread; iter = iter->schedulerlistnext )
|
iter != first_thread; iter = iter->scheduler_list_next )
|
||||||
if ( least_pid <= iter->process->pid && iter->process->pid <= max_pid &&
|
if ( least_pid <= iter->process->pid && iter->process->pid <= max_pid &&
|
||||||
(!best || iter->process->pid < best->pid) )
|
(!best || iter->process->pid < best->pid) )
|
||||||
best = iter->process;
|
best = iter->process;
|
||||||
|
|
|
@ -45,21 +45,24 @@ enum ThreadState { NONE, RUNNABLE, BLOCKING, DEAD };
|
||||||
namespace Sortix {
|
namespace Sortix {
|
||||||
namespace Scheduler {
|
namespace Scheduler {
|
||||||
|
|
||||||
void Init();
|
|
||||||
void Switch(CPU::InterruptRegisters* regs);
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
inline static void Yield() { asm volatile ("int $129"); }
|
static inline void Yield()
|
||||||
|
{
|
||||||
|
asm volatile ("int $129");
|
||||||
|
}
|
||||||
__attribute__ ((noreturn))
|
__attribute__ ((noreturn))
|
||||||
inline static void ExitThread()
|
static inline void ExitThread()
|
||||||
{
|
{
|
||||||
asm volatile ("int $132");
|
asm volatile ("int $132");
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Switch(CPU::InterruptRegisters* regs);
|
||||||
void SetThreadState(Thread* thread, ThreadState state);
|
void SetThreadState(Thread* thread, ThreadState state);
|
||||||
ThreadState GetThreadState(Thread* thread);
|
ThreadState GetThreadState(Thread* thread);
|
||||||
void SetIdleThread(Thread* thread);
|
void SetIdleThread(Thread* thread);
|
||||||
void SetDummyThreadOwner(Process* process);
|
|
||||||
void SetInitProcess(Process* init);
|
void SetInitProcess(Process* init);
|
||||||
Process* GetInitProcess();
|
Process* GetInitProcess();
|
||||||
Process* GetKernelProcess();
|
Process* GetKernelProcess();
|
||||||
|
|
|
@ -92,15 +92,12 @@ public:
|
||||||
public:
|
public:
|
||||||
size_t id;
|
size_t id;
|
||||||
Process* process;
|
Process* process;
|
||||||
bool terminated;
|
|
||||||
Thread* prevsibling;
|
Thread* prevsibling;
|
||||||
Thread* nextsibling;
|
Thread* nextsibling;
|
||||||
|
|
||||||
// These are some things used internally by the scheduler and should not be
|
|
||||||
// touched by anything but it. Consider it private.
|
|
||||||
public:
|
public:
|
||||||
Thread* schedulerlistprev;
|
Thread* scheduler_list_prev;
|
||||||
Thread* schedulerlistnext;
|
Thread* scheduler_list_next;
|
||||||
volatile ThreadState state;
|
volatile ThreadState state;
|
||||||
uint8_t fpuenv[512UL + 16UL];
|
uint8_t fpuenv[512UL + 16UL];
|
||||||
uint8_t* fpuenvaligned;
|
uint8_t* fpuenvaligned;
|
||||||
|
|
|
@ -27,12 +27,12 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <msr.h>
|
#include <msr.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <timespec.h>
|
#include <timespec.h>
|
||||||
|
|
||||||
#include <sortix/clock.h>
|
#include <sortix/clock.h>
|
||||||
#include <sortix/timespec.h>
|
#include <sortix/timespec.h>
|
||||||
|
|
||||||
|
#include <sortix/kernel/decl.h>
|
||||||
#include <sortix/kernel/interrupt.h>
|
#include <sortix/kernel/interrupt.h>
|
||||||
#include <sortix/kernel/kernel.h>
|
#include <sortix/kernel/kernel.h>
|
||||||
#include <sortix/kernel/memorymanagement.h>
|
#include <sortix/kernel/memorymanagement.h>
|
||||||
|
@ -43,116 +43,69 @@
|
||||||
#include <sortix/kernel/thread.h>
|
#include <sortix/kernel/thread.h>
|
||||||
#include <sortix/kernel/time.h>
|
#include <sortix/kernel/time.h>
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
#include "x86-family/gdt.h"
|
#include "x86-family/gdt.h"
|
||||||
#include "x86-family/float.h"
|
#include "x86-family/float.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Sortix {
|
namespace Sortix {
|
||||||
namespace Scheduler {
|
namespace Scheduler {
|
||||||
|
|
||||||
const uint32_t SCHED_MAGIC = 0x1234567;
|
static Thread* current_thread;
|
||||||
|
static Thread* idle_thread;
|
||||||
volatile unsigned long premagic;
|
static Thread* first_runnable_thread;
|
||||||
static Thread* currentthread;
|
static Thread* first_sleeping_thread;
|
||||||
} // namespace Scheduler
|
static Process* init_process;
|
||||||
Thread* CurrentThread() { return Scheduler::currentthread; }
|
|
||||||
Process* CurrentProcess() { return CurrentThread()->process; }
|
|
||||||
namespace Scheduler {
|
|
||||||
|
|
||||||
uint8_t dummythreaddata[sizeof(Thread)] __attribute__ ((aligned (8)));
|
|
||||||
Thread* dummythread;
|
|
||||||
Thread* idlethread;
|
|
||||||
Thread* firstrunnablethread;
|
|
||||||
Thread* firstsleepingthread;
|
|
||||||
Process* initprocess;
|
|
||||||
volatile unsigned long postmagic;
|
|
||||||
|
|
||||||
static inline void SetCurrentThread(Thread* newcurrentthread)
|
|
||||||
{
|
|
||||||
currentthread = newcurrentthread;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogBeginSwitch(Thread* current, const CPU::InterruptRegisters* regs);
|
|
||||||
void LogSwitch(Thread* current, Thread* next);
|
|
||||||
void LogEndSwitch(Thread* current, const CPU::InterruptRegisters* regs);
|
|
||||||
|
|
||||||
static Thread* PopNextThread()
|
static Thread* PopNextThread()
|
||||||
{
|
{
|
||||||
if ( !firstrunnablethread ) { return idlethread; }
|
if ( first_runnable_thread )
|
||||||
Thread* result = firstrunnablethread;
|
{
|
||||||
firstrunnablethread = firstrunnablethread->schedulerlistnext;
|
Thread* result = first_runnable_thread;
|
||||||
return result;
|
first_runnable_thread = first_runnable_thread->scheduler_list_next;
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static Thread* ValidatedPopNextThread()
|
return idle_thread;
|
||||||
{
|
|
||||||
assert(premagic == SCHED_MAGIC);
|
|
||||||
assert(postmagic == SCHED_MAGIC);
|
|
||||||
Thread* nextthread = PopNextThread();
|
|
||||||
if ( !nextthread ) { Panic("Had no thread to switch to."); }
|
|
||||||
if ( nextthread->terminated )
|
|
||||||
{
|
|
||||||
PanicF("Running a terminated thread 0x%p", nextthread);
|
|
||||||
}
|
|
||||||
addr_t newaddrspace = nextthread->process->addrspace;
|
|
||||||
if ( !Page::IsAligned(newaddrspace) )
|
|
||||||
{
|
|
||||||
PanicF("Thread 0x%p, process %ji (0x%p) (backup: %i), had bad "
|
|
||||||
"address space variable: 0x%zx: not page-aligned "
|
|
||||||
"(backup: 0x%zx)\n", nextthread,
|
|
||||||
(intmax_t) nextthread->process->pid, nextthread->process,
|
|
||||||
-1/*nextthread->pidbackup*/, newaddrspace,
|
|
||||||
(addr_t)-1 /*nextthread->addrspacebackup*/);
|
|
||||||
}
|
|
||||||
return nextthread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DoActualSwitch(CPU::InterruptRegisters* regs)
|
static void DoActualSwitch(CPU::InterruptRegisters* regs)
|
||||||
{
|
{
|
||||||
Thread* current = CurrentThread();
|
Thread* prev = CurrentThread();
|
||||||
LogBeginSwitch(current, regs);
|
Thread* next = PopNextThread();
|
||||||
|
|
||||||
Thread* next = ValidatedPopNextThread();
|
if ( prev == next )
|
||||||
LogSwitch(current, next);
|
return;
|
||||||
|
|
||||||
if ( current == next ) { return; }
|
prev->SaveRegisters(regs);
|
||||||
|
|
||||||
current->SaveRegisters(regs);
|
|
||||||
next->LoadRegisters(regs);
|
next->LoadRegisters(regs);
|
||||||
|
|
||||||
|
Memory::SwitchAddressSpace(next->addrspace);
|
||||||
|
current_thread = next;
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
Float::NotityTaskSwitch();
|
Float::NotityTaskSwitch();
|
||||||
|
GDT::SetKernelStack(next->kernelstackpos, next->kernelstacksize,
|
||||||
addr_t newaddrspace = next->addrspace;
|
next->kernelstackpos + next->kernelstacksize);
|
||||||
Memory::SwitchAddressSpace(newaddrspace);
|
|
||||||
SetCurrentThread(next);
|
|
||||||
|
|
||||||
addr_t stacklower = next->kernelstackpos;
|
|
||||||
size_t stacksize = next->kernelstacksize;
|
|
||||||
addr_t stackhigher = stacklower + stacksize;
|
|
||||||
assert(stacklower && stacksize && stackhigher);
|
|
||||||
GDT::SetKernelStack(stacklower, stacksize, stackhigher);
|
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
current->fsbase = (unsigned long) rdmsr(MSRID_FSBASE);
|
|
||||||
current->gsbase = (unsigned long) rdmsr(MSRID_GSBASE);
|
|
||||||
wrmsr(MSRID_FSBASE, (uint64_t) next->fsbase);
|
|
||||||
wrmsr(MSRID_GSBASE, (uint64_t) next->gsbase);
|
|
||||||
#elif defined(__i386__)
|
|
||||||
current->fsbase = (unsigned long) GDT::GetFSBase();
|
|
||||||
current->gsbase = (unsigned long) GDT::GetGSBase();
|
|
||||||
GDT::SetFSBase((uint32_t) next->fsbase);
|
|
||||||
GDT::SetGSBase((uint32_t) next->gsbase);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LogEndSwitch(next, regs);
|
#if defined(__i386__)
|
||||||
|
prev->fsbase = (unsigned long) GDT::GetFSBase();
|
||||||
|
prev->gsbase = (unsigned long) GDT::GetGSBase();
|
||||||
|
GDT::SetFSBase((uint32_t) next->fsbase);
|
||||||
|
GDT::SetGSBase((uint32_t) next->gsbase);
|
||||||
|
#elif defined(__x86_64__)
|
||||||
|
prev->fsbase = (unsigned long) rdmsr(MSRID_FSBASE);
|
||||||
|
prev->gsbase = (unsigned long) rdmsr(MSRID_GSBASE);
|
||||||
|
wrmsr(MSRID_FSBASE, (uint64_t) next->fsbase);
|
||||||
|
wrmsr(MSRID_GSBASE, (uint64_t) next->gsbase);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Switch(CPU::InterruptRegisters* regs)
|
void Switch(CPU::InterruptRegisters* regs)
|
||||||
{
|
{
|
||||||
assert(premagic == SCHED_MAGIC);
|
|
||||||
assert(postmagic == SCHED_MAGIC);
|
|
||||||
DoActualSwitch(regs);
|
DoActualSwitch(regs);
|
||||||
assert(premagic == SCHED_MAGIC);
|
|
||||||
assert(postmagic == SCHED_MAGIC);
|
|
||||||
if ( regs->signal_pending && regs->InUserspace() )
|
if ( regs->signal_pending && regs->InUserspace() )
|
||||||
{
|
{
|
||||||
Interrupt::Enable();
|
Interrupt::Enable();
|
||||||
|
@ -160,49 +113,6 @@ void Switch(CPU::InterruptRegisters* regs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool DEBUG_BEGINCTXSWITCH = false;
|
|
||||||
const bool DEBUG_CTXSWITCH = false;
|
|
||||||
const bool DEBUG_ENDCTXSWITCH = false;
|
|
||||||
|
|
||||||
void LogBeginSwitch(Thread* current, const CPU::InterruptRegisters* regs)
|
|
||||||
{
|
|
||||||
bool alwaysdebug = false;
|
|
||||||
bool isidlethread = current == idlethread;
|
|
||||||
bool dodebug = DEBUG_BEGINCTXSWITCH && !isidlethread;
|
|
||||||
if ( alwaysdebug || dodebug )
|
|
||||||
{
|
|
||||||
Log::PrintF("Switching from 0x%p", current);
|
|
||||||
regs->LogRegisters();
|
|
||||||
Log::Print("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogSwitch(Thread* current, Thread* next)
|
|
||||||
{
|
|
||||||
bool alwaysdebug = false;
|
|
||||||
bool different = current == idlethread;
|
|
||||||
bool dodebug = DEBUG_CTXSWITCH && different;
|
|
||||||
if ( alwaysdebug || dodebug )
|
|
||||||
{
|
|
||||||
Log::PrintF("switching from %ji:%u (0x%p) to %ji:%u (0x%p) \n",
|
|
||||||
(intmax_t) current->process->pid, 0, current,
|
|
||||||
(intmax_t) next->process->pid, 0, next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogEndSwitch(Thread* current, const CPU::InterruptRegisters* regs)
|
|
||||||
{
|
|
||||||
bool alwaysdebug = false;
|
|
||||||
bool isidlethread = current == idlethread;
|
|
||||||
bool dodebug = DEBUG_BEGINCTXSWITCH && !isidlethread;
|
|
||||||
if ( alwaysdebug || dodebug )
|
|
||||||
{
|
|
||||||
Log::PrintF("Switched to 0x%p", current);
|
|
||||||
regs->LogRegisters();
|
|
||||||
Log::Print("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptYieldCPU(CPU::InterruptRegisters* regs, void* /*user*/)
|
void InterruptYieldCPU(CPU::InterruptRegisters* regs, void* /*user*/)
|
||||||
{
|
{
|
||||||
Switch(regs);
|
Switch(regs);
|
||||||
|
@ -210,9 +120,11 @@ void InterruptYieldCPU(CPU::InterruptRegisters* regs, void* /*user*/)
|
||||||
|
|
||||||
void ThreadExitCPU(CPU::InterruptRegisters* regs, void* /*user*/)
|
void ThreadExitCPU(CPU::InterruptRegisters* regs, void* /*user*/)
|
||||||
{
|
{
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
// Can't use floating point instructions from now.
|
// Can't use floating point instructions from now.
|
||||||
Float::NofityTaskExit(currentthread);
|
Float::NofityTaskExit(current_thread);
|
||||||
SetThreadState(currentthread, ThreadState::DEAD);
|
#endif
|
||||||
|
SetThreadState(current_thread, ThreadState::DEAD);
|
||||||
InterruptYieldCPU(regs, NULL);
|
InterruptYieldCPU(regs, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,30 +132,25 @@ void ThreadExitCPU(CPU::InterruptRegisters* regs, void* /*user*/)
|
||||||
// nothing, which is only run when the system has nothing to do.
|
// nothing, which is only run when the system has nothing to do.
|
||||||
void SetIdleThread(Thread* thread)
|
void SetIdleThread(Thread* thread)
|
||||||
{
|
{
|
||||||
assert(!idlethread);
|
assert(!idle_thread);
|
||||||
idlethread = thread;
|
idle_thread = thread;
|
||||||
SetThreadState(thread, ThreadState::NONE);
|
SetThreadState(thread, ThreadState::NONE);
|
||||||
SetCurrentThread(thread);
|
current_thread = thread;
|
||||||
}
|
|
||||||
|
|
||||||
void SetDummyThreadOwner(Process* process)
|
|
||||||
{
|
|
||||||
dummythread->process = process;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetInitProcess(Process* init)
|
void SetInitProcess(Process* init)
|
||||||
{
|
{
|
||||||
initprocess = init;
|
init_process = init;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* GetInitProcess()
|
Process* GetInitProcess()
|
||||||
{
|
{
|
||||||
return initprocess;
|
return init_process;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* GetKernelProcess()
|
Process* GetKernelProcess()
|
||||||
{
|
{
|
||||||
return idlethread->process;
|
return idle_thread->process;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetThreadState(Thread* thread, ThreadState state)
|
void SetThreadState(Thread* thread, ThreadState state)
|
||||||
|
@ -254,31 +161,34 @@ void SetThreadState(Thread* thread, ThreadState state)
|
||||||
if ( thread->state == ThreadState::RUNNABLE &&
|
if ( thread->state == ThreadState::RUNNABLE &&
|
||||||
state != ThreadState::RUNNABLE )
|
state != ThreadState::RUNNABLE )
|
||||||
{
|
{
|
||||||
if ( thread == firstrunnablethread ) { firstrunnablethread = thread->schedulerlistnext; }
|
if ( thread == first_runnable_thread )
|
||||||
if ( thread == firstrunnablethread ) { firstrunnablethread = NULL; }
|
first_runnable_thread = thread->scheduler_list_next;
|
||||||
assert(thread->schedulerlistprev);
|
if ( thread == first_runnable_thread )
|
||||||
assert(thread->schedulerlistnext);
|
first_runnable_thread = NULL;
|
||||||
thread->schedulerlistprev->schedulerlistnext = thread->schedulerlistnext;
|
assert(thread->scheduler_list_prev);
|
||||||
thread->schedulerlistnext->schedulerlistprev = thread->schedulerlistprev;
|
assert(thread->scheduler_list_next);
|
||||||
thread->schedulerlistprev = NULL;
|
thread->scheduler_list_prev->scheduler_list_next = thread->scheduler_list_next;
|
||||||
thread->schedulerlistnext = NULL;
|
thread->scheduler_list_next->scheduler_list_prev = thread->scheduler_list_prev;
|
||||||
|
thread->scheduler_list_prev = NULL;
|
||||||
|
thread->scheduler_list_next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the thread into the scheduler's carousel linked list.
|
// Insert the thread into the scheduler's carousel linked list.
|
||||||
if ( thread->state != ThreadState::RUNNABLE &&
|
if ( thread->state != ThreadState::RUNNABLE &&
|
||||||
state == ThreadState::RUNNABLE )
|
state == ThreadState::RUNNABLE )
|
||||||
{
|
{
|
||||||
if ( firstrunnablethread == NULL ) { firstrunnablethread = thread; }
|
if ( first_runnable_thread == NULL )
|
||||||
thread->schedulerlistprev = firstrunnablethread->schedulerlistprev;
|
first_runnable_thread = thread;
|
||||||
thread->schedulerlistnext = firstrunnablethread;
|
thread->scheduler_list_prev = first_runnable_thread->scheduler_list_prev;
|
||||||
firstrunnablethread->schedulerlistprev = thread;
|
thread->scheduler_list_next = first_runnable_thread;
|
||||||
thread->schedulerlistprev->schedulerlistnext = thread;
|
first_runnable_thread->scheduler_list_prev = thread;
|
||||||
|
thread->scheduler_list_prev->scheduler_list_next = thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->state = state;
|
thread->state = state;
|
||||||
|
|
||||||
assert(thread->state != ThreadState::RUNNABLE || thread->schedulerlistprev);
|
assert(thread->state != ThreadState::RUNNABLE || thread->scheduler_list_prev);
|
||||||
assert(thread->state != ThreadState::RUNNABLE || thread->schedulerlistnext);
|
assert(thread->state != ThreadState::RUNNABLE || thread->scheduler_list_next);
|
||||||
|
|
||||||
Interrupt::SetEnabled(wasenabled);
|
Interrupt::SetEnabled(wasenabled);
|
||||||
}
|
}
|
||||||
|
@ -321,19 +231,9 @@ static int sys_sched_yield(void)
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
premagic = postmagic = SCHED_MAGIC;
|
first_runnable_thread = NULL;
|
||||||
|
first_sleeping_thread = NULL;
|
||||||
// We use a dummy so that the first context switch won't crash when the
|
idle_thread = NULL;
|
||||||
// current thread is accessed. This lets us avoid checking whether it is
|
|
||||||
// NULL (which it only will be once), which gives simpler code.
|
|
||||||
dummythread = (Thread*) &dummythreaddata;
|
|
||||||
memset(dummythread, 0, sizeof(*dummythread));
|
|
||||||
dummythread->schedulerlistprev = dummythread;
|
|
||||||
dummythread->schedulerlistnext = dummythread;
|
|
||||||
currentthread = dummythread;
|
|
||||||
firstrunnablethread = NULL;
|
|
||||||
firstsleepingthread = NULL;
|
|
||||||
idlethread = NULL;
|
|
||||||
|
|
||||||
Syscall::Register(SYSCALL_SLEEP, (void*) sys_sleep);
|
Syscall::Register(SYSCALL_SLEEP, (void*) sys_sleep);
|
||||||
Syscall::Register(SYSCALL_USLEEP, (void*) sys_usleep);
|
Syscall::Register(SYSCALL_USLEEP, (void*) sys_usleep);
|
||||||
|
@ -342,3 +242,17 @@ void Init()
|
||||||
|
|
||||||
} // namespace Scheduler
|
} // namespace Scheduler
|
||||||
} // namespace Sortix
|
} // namespace Sortix
|
||||||
|
|
||||||
|
namespace Sortix {
|
||||||
|
|
||||||
|
Thread* CurrentThread()
|
||||||
|
{
|
||||||
|
return Scheduler::current_thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
Process* CurrentProcess()
|
||||||
|
{
|
||||||
|
return CurrentThread()->process;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Sortix
|
||||||
|
|
|
@ -52,8 +52,8 @@ Thread::Thread()
|
||||||
process = NULL;
|
process = NULL;
|
||||||
prevsibling = NULL;
|
prevsibling = NULL;
|
||||||
nextsibling = NULL;
|
nextsibling = NULL;
|
||||||
schedulerlistprev = NULL;
|
scheduler_list_prev = NULL;
|
||||||
schedulerlistnext = NULL;
|
scheduler_list_next = NULL;
|
||||||
state = NONE;
|
state = NONE;
|
||||||
memset(®isters, 0, sizeof(registers));
|
memset(®isters, 0, sizeof(registers));
|
||||||
fsbase = 0;
|
fsbase = 0;
|
||||||
|
@ -62,7 +62,6 @@ Thread::Thread()
|
||||||
kernelstacksize = 0;
|
kernelstacksize = 0;
|
||||||
kernelstackmalloced = false;
|
kernelstackmalloced = false;
|
||||||
pledged_destruction = false;
|
pledged_destruction = false;
|
||||||
terminated = false;
|
|
||||||
fpuinitialized = false;
|
fpuinitialized = false;
|
||||||
// If malloc isn't 16-byte aligned, then we can't rely on offsets in
|
// If malloc isn't 16-byte aligned, then we can't rely on offsets in
|
||||||
// our own class, so we'll just fix ourselves nicely up.
|
// our own class, so we'll just fix ourselves nicely up.
|
||||||
|
@ -81,7 +80,6 @@ Thread::~Thread()
|
||||||
assert(CurrentThread() != this);
|
assert(CurrentThread() != this);
|
||||||
if ( kernelstackmalloced )
|
if ( kernelstackmalloced )
|
||||||
delete[] (uint8_t*) kernelstackpos;
|
delete[] (uint8_t*) kernelstackpos;
|
||||||
terminated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t Thread::SwitchAddressSpace(addr_t newaddrspace)
|
addr_t Thread::SwitchAddressSpace(addr_t newaddrspace)
|
||||||
|
@ -232,8 +230,6 @@ static int sys_exit_thread(int requested_exit_code,
|
||||||
continue;
|
continue;
|
||||||
if ( iter->pledged_destruction )
|
if ( iter->pledged_destruction )
|
||||||
continue;
|
continue;
|
||||||
if ( iter->terminated )
|
|
||||||
continue;
|
|
||||||
is_others = true;
|
is_others = true;
|
||||||
}
|
}
|
||||||
if ( !(flags & EXIT_THREAD_ONLY_IF_OTHERS) || is_others )
|
if ( !(flags & EXIT_THREAD_ONLY_IF_OTHERS) || is_others )
|
||||||
|
|
Loading…
Reference in New Issue