#include <threads.h>
#include <threads_int.h>
+// === PROTOTYPES ===
+void Threads_int_Init(void) __attribute__((constructor(101)));
+tThread *Threads_int_CreateTCB(tThread *Parent);
+
// === GLOBALS ===
- int gbThreads_MultithreadingEnabled;
+tThread *gThreads_List;
tThread __thread *lpThreads_This;
+ int giThreads_NextTID = 1;
+tShortSpinlock glThreadListLock;
// === CODE ===
+void Threads_int_Init(void)
+{
+ lpThreads_This = Threads_int_CreateTCB(NULL);
+ Threads_SetName("ThreadZero");
+}
+
tThread *Proc_GetCurThread(void)
{
return lpThreads_This;
void Threads_PostEvent(tThread *Thread, Uint32 Events)
{
- Threads_int_LockMutex(Thread->Protector);
+ if( !Thread ) {
+ // nope.avi
+ return ;
+ }
+ SHORTLOCK( &Thread->IsLocked );
Thread->PendingEvents |= Events;
if( Thread->WaitingEvents & Events )
- Threads_int_SemaphoreSignal(Thread->WaitSemaphore);
- Threads_int_ReleaseMutex(Thread->Protector);
+ Threads_int_SemSignal(Thread->WaitSemaphore);
+ SHORTREL( &Thread->IsLocked );
}
Uint32 Threads_WaitEvents(Uint32 Events)
{
- Thread->WaitingEvents = Events;
- Threads_int_SemaphoreWaitAll(Thread->WaitSemaphore);
- Thread->WaitingEvents = 0;
- Uint32 rv = Thread->PendingEvents;
+ if( !Threads_int_ThreadingEnabled() ) {
+ Log_Notice("Threads", "_WaitEvents: Threading disabled");
+ return 0;
+ }
+ lpThreads_This->WaitingEvents = Events;
+ Threads_int_SemWaitAll(lpThreads_This->WaitSemaphore);
+ lpThreads_This->WaitingEvents = 0;
+ Uint32 rv = lpThreads_This->PendingEvents;
return rv;
}
void Threads_ClearEvent(Uint32 Mask)
{
- Threads_int_LockMutex(Thread->Protector);
+ if( !Threads_int_ThreadingEnabled() ) {
+ Log_Notice("Threads", "_ClearEvent: Threading disabled");
+ return ;
+ }
+ SHORTLOCK(&lpThreads_This->IsLocked);
lpThreads_This->PendingEvents &= ~Mask;
- Threads_int_ReleaseMutex(Thread->Protector);
+ SHORTREL(&lpThreads_This->IsLocked);
}
tUID Threads_GetUID(void) { return 0; }
tGID Threads_GetGID(void) { return 0; }
-tTID Threads_GetTID(void) { return 0; }
+tTID Threads_GetTID(void) { return lpThreads_This ? lpThreads_This->TID : 0; }
-int *Threads_GetMaxFD(void) { static int max_fd=32; return &max_fd; }
-char **Threads_GetCWD(void) { static char *cwd; return &cwd; }
-char **Threads_GetChroot(void) { static char *chroot; return &chroot; }
+int *Threads_GetMaxFD(void) { return &lpThreads_This->Process->MaxFDs; }
+char **Threads_GetCWD(void) { return &lpThreads_This->Process->CWD; }
+char **Threads_GetChroot(void) { return &lpThreads_This->Process->Chroot; }
+void **Threads_GetHandlesPtr(void) { return &lpThreads_This->Process->Handles; }
void Threads_Yield(void)
{
- Log_Warning("Threads", "Threads_Yield DEFINITELY shouldn't be used");
+ Log_KernelPanic("Threads", "Threads_Yield DEFINITELY shouldn't be used (%p)",
+ __builtin_return_address(0));
}
void Threads_Sleep(void)
Log_Warning("Threads", "Threads_Sleep shouldn't be used");
}
+void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
+{
+ while( lpThreads_This->Status != Status )
+ Threads_int_SemWaitAll(lpThreads_This->WaitSemaphore);
+}
+
int Threads_SetName(const char *Name)
{
- Log_Notice("Threads", "TODO: Threads_SetName('%s')", Name);
+ if( !lpThreads_This )
+ return 0;
+
+ if( lpThreads_This->ThreadName )
+ free(lpThreads_This->ThreadName);
+ lpThreads_This->ThreadName = strdup(Name);
+
return 0;
}
int *Threads_GetErrno(void) __attribute__ ((weak));
-int *Threads_GetErrno(void)// __attribute__ ((weak))
+int *Threads_GetErrno(void)
{
static int a_errno;
return &a_errno;
}
+tThread *Threads_RemActive(void)
+{
+ return lpThreads_This;
+}
+
+void Threads_AddActive(tThread *Thread)
+{
+ Thread->Status = THREAD_STAT_ACTIVE;
+ // Increment state-change semaphore
+ Threads_int_SemSignal(Thread->WaitSemaphore);
+}
+
+struct sProcess *Threads_int_CreateProcess(void)
+{
+ struct sProcess *ret = calloc(sizeof(struct sProcess), 1);
+
+ ret->MaxFDs = 32;
+
+ return ret;
+}
+
+tThread *Threads_int_CreateTCB(tThread *Parent)
+{
+ tThread *ret = calloc( sizeof(tThread), 1 );
+ ret->TID = giThreads_NextTID ++;
+ ret->WaitSemaphore = Threads_int_SemCreate();
+ //ret->Protector = Threads_int_MutexCreate();
+
+ if( !Parent )
+ {
+ ret->Process = Threads_int_CreateProcess();
+ }
+ else
+ ret->Process = Parent->Process;
+
+ ret->ProcNext = ret->Process->Threads;
+ ret->Process->Threads = ret;
+
+ ret->Next = gThreads_List;
+ gThreads_List = ret;
+
+ return ret;
+}
+
struct sThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
{
- if( !gbThreads_MultithreadingEnabled )
+ if( !Threads_int_ThreadingEnabled() )
{
Log_Error("Threads", "Multithreading is disabled in this build");
return NULL;
}
else
{
- tThread *ret = malloc( sizeof(tThread) );
+ tThread *ret = Threads_int_CreateTCB(lpThreads_This);
ret->SpawnFcn = Fcn;
ret->SpawnData = Data;
Threads_int_CreateThread(ret);
- Log_Error("Threads", "TODO - Use pthreads to impliment Proc_SpawnWorker");
- return NULL;
+ return ret;
}
}