diff --git a/sortix/event.cpp b/sortix/event.cpp index a6c01dfd..b1614176 100644 --- a/sortix/event.cpp +++ b/sortix/event.cpp @@ -61,7 +61,24 @@ namespace Sortix waiting->event = NULL; Syscall::ScheduleResumption(waiting); waiting = waiting->eventnextwaiting; - } + } + } + + // TODO: Okay, I realize this is O(N), refactor this to a linked list. + void Event::Unregister(Thread* thread) + { + if ( thread->event != this ) { return; } + thread->event = NULL; + if ( waiting == thread ) { waiting = thread->eventnextwaiting; return; } + for ( Thread* tmp = waiting; tmp; tmp = tmp->eventnextwaiting ) + { + if ( tmp->eventnextwaiting == thread ) + { + tmp->eventnextwaiting = thread->eventnextwaiting; + break; + } + } + thread->eventnextwaiting = NULL; } } diff --git a/sortix/event.h b/sortix/event.h index 612fa01a..6e7a8481 100644 --- a/sortix/event.h +++ b/sortix/event.h @@ -38,6 +38,7 @@ namespace Sortix public: void Register(); void Signal(); + void Unregister(Thread* thread); private: Thread* waiting; diff --git a/sortix/scheduler.cpp b/sortix/scheduler.cpp index 54e93d93..1b620d9b 100644 --- a/sortix/scheduler.cpp +++ b/sortix/scheduler.cpp @@ -134,6 +134,7 @@ namespace Sortix Thread* nextthread = PopNextThread(); if ( !nextthread ) { Panic("had no thread to switch to"); } + if ( nextthread->terminated ) { PanicF("Running a terminated thread 0x%p", nextthread); } LogContextSwitch(currentthread, nextthread); if ( nextthread == currentthread ) { return; } diff --git a/sortix/thread.cpp b/sortix/thread.cpp index 4e8dff82..b1bb7128 100644 --- a/sortix/thread.cpp +++ b/sortix/thread.cpp @@ -25,6 +25,7 @@ #include "platform.h" #include #include +#include "event.h" #include "process.h" #include "thread.h" #include "scheduler.h" @@ -54,6 +55,8 @@ namespace Sortix scfunc = NULL; currentsignal = NULL; sighandler = NULL; + pidbackup = -1; + terminated = false; ResetCallbacks(); } @@ -76,6 +79,8 @@ namespace Sortix schedulerlistnext = NULL; scfunc = NULL; sighandler = forkfrom->sighandler; + pidbackup = -1; + terminated = false; ResetCallbacks(); } @@ -89,6 +94,8 @@ namespace Sortix ASSERT(CurrentProcess() == process); ASSERT(nextsleepingthread == NULL); + if ( event ) { event->Unregister(this); } + // Delete information about signals being processed. while ( currentsignal ) { @@ -98,6 +105,8 @@ namespace Sortix } Memory::UnmapRangeUser(stackpos, stacksize); + + terminated = true; } Thread* Thread::Fork() @@ -180,6 +189,8 @@ namespace Sortix if ( ready ) { return; } ready = true; + this->pidbackup = process->pid; + if ( Time::MicrosecondsSinceBoot() < sleepuntil ) { uintmax_t howlong = sleepuntil - Time::MicrosecondsSinceBoot(); diff --git a/sortix/thread.h b/sortix/thread.h index 2746e149..47e8bc8a 100644 --- a/sortix/thread.h +++ b/sortix/thread.h @@ -60,6 +60,8 @@ namespace Sortix public: size_t id; Process* process; + pid_t pidbackup; + bool terminated; Thread* prevsibling; Thread* nextsibling;