X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=AcessNative%2Facesskernel_src%2Fthreads.c;h=7296a58e25f622b3aef726ed21748341d1d3d457;hb=336ba8b200f6ca1d5d25f09a9d7ddac2e59b26d9;hp=a39fb5e453f6368106903e40f90c8081225a7304;hpb=5240c280222eb76d29c2eaecaaadcbac01af3a9c;p=tpg%2Facess2.git diff --git a/AcessNative/acesskernel_src/threads.c b/AcessNative/acesskernel_src/threads.c index a39fb5e4..7296a58e 100644 --- a/AcessNative/acesskernel_src/threads.c +++ b/AcessNative/acesskernel_src/threads.c @@ -5,76 +5,26 @@ * threads.c * - Thread and process handling */ -#define _SIGNAL_H_ // Stop the acess signal.h being used -#define _HEAP_H_ // Stop heap.h being imported (collides with stdlib heap) -#define _VFS_EXT_H // Stop vfs_ext.h being imported (collides with fd_set) -#undef CLONE_VM // Such a hack + #include -#undef NULL // Remove acess definition #include #include -#include -#include -#include -#include -#include "/usr/include/signal.h" -#include +#include "../../KernelLand/Kernel/include/semaphore.h" +typedef signed long long int time_t; +#include "../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h" +#include +#include +#include +#include +#include "include/threads_glue.h" + +#define THREAD_EVENT_WAKEUP 0x80000000 // === IMPORTS === -void VFS_CloneHandleList(int PID); +extern void VFS_CloneHandleList(int PID); +extern void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[]); // === STRUCTURES === -#if 0 -typedef struct sState -{ - void *CurState; - Uint SP, BP, IP; -} tState; -#endif - -typedef struct sProcess -{ - int nThreads; - int NativePID; - char *CWD; - char *Chroot; - int MaxFD; -} tProcess; - -typedef struct sThread -{ - struct sThread *GlobalNext; - struct sThread *Next; - - int KernelTID; - - tTID TID, PID; - tUID UID, GID; - - struct sThread *Parent; - - char *ThreadName; - - int State; // 0: Dead, 1: Active, 2: Paused, 3: Asleep - int ExitStatus; - int _errno; - - // Threads waiting for this thread to exit. - // Quit logic: - // - Wait for `WaitingThreads` to be non-null (maybe?) - // - Wake first in the queue, wait for it to be removed - // - Repeat - // - Free thread and quit kernel thread - struct sThread *WaitingThreads; - struct sThread *WaitingThreadsEnd; - - tProcess *Process; - - Uint32 Events, WaitMask; - SDL_sem *EventSem; - -} tThread; - // === PROTOTYPES === int Threads_Wake(tThread *Thread); @@ -86,7 +36,7 @@ tProcess gProcessZero = { .MaxFD = 100 }; tThread gThreadZero = { - .State=1, + .Status=THREAD_STAT_ACTIVE, .ThreadName="ThreadZero", .Process = &gProcessZero }; @@ -127,13 +77,14 @@ void Threads_SetThread(int TID) Log_Error("Threads", "_SetThread - Thread %i is not on global list", TID); } -tThread *Threads_GetThread(int TID) +tThread *Threads_GetThread(Uint TID) { tThread *thread; for( thread = gpThreads; thread; thread = thread->GlobalNext ) { - if( thread->TID == TID ) + if( thread->TID == TID ) { return thread; + } } return NULL; } @@ -150,6 +101,7 @@ tThread *Threads_CloneTCB(tThread *TemplateThread) ret->TID = giThreads_NextThreadID ++; ret->ThreadName = strdup(TemplateThread->ThreadName); + Threads_Glue_SemInit( &ret->EventSem, 0 ); ret->WaitingThreads = NULL; ret->WaitingThreadsEnd = NULL; @@ -167,10 +119,10 @@ tGID Threads_GetGID() { return gpCurrentThread->GID; } tTID Threads_GetTID() { return gpCurrentThread->TID; } tPID Threads_GetPID() { return gpCurrentThread->PID; } -int Threads_SetUID(int *Errno, tUID NewUID) +int Threads_SetUID(tUID NewUID) { if(Threads_GetUID() != 0) { - if(Errno) *Errno = -EACCES; + errno = EACCES; return -1; } @@ -178,10 +130,10 @@ int Threads_SetUID(int *Errno, tUID NewUID) return 0; } -int Threads_SetGID(int *Errno, tGID NewGID) +int Threads_SetGID(tGID NewGID) { if(Threads_GetUID() != 0) { - if(Errno) *Errno = -EACCES; + errno = -EACCES; return -1; } @@ -194,7 +146,7 @@ char **Threads_GetCWD(void) { return &gpCurrentThread->Process->CWD; } char **Threads_GetChroot(void) { return &gpCurrentThread->Process->Chroot; } int *Threads_GetMaxFD(void) { return &gpCurrentThread->Process->MaxFD; }; -int Threads_WaitTID(int TID, int *Status) +tTID Threads_WaitTID(int TID, int *Status) { // Any Child if(TID == -1) { @@ -222,7 +174,7 @@ int Threads_WaitTID(int TID, int *Status) if(!thread) return -1; us->Next = NULL; - us->State = 3; + us->Status = THREAD_STAT_WAITING; // TODO: Locking if(thread->WaitingThreadsEnd) { @@ -235,11 +187,7 @@ int Threads_WaitTID(int TID, int *Status) thread->WaitingThreadsEnd = us; } - while(thread->State != 0) - { - pause(); - Log_Debug("Threads", "Huh?... state = %i", thread->State); - } + Threads_WaitEvents( THREAD_EVENT_WAKEUP ); if(Status) *Status = thread->ExitStatus; thread->WaitingThreads = thread->WaitingThreads->Next; @@ -254,7 +202,7 @@ int Threads_WaitTID(int TID, int *Status) void Threads_Sleep(void) { // TODO: Add to a sleeping queue - pause(); + //pause(); } void Threads_Yield(void) @@ -275,7 +223,7 @@ void Threads_Exit(int TID, int Status) { // Wait for the thread to be waited upon while( gpCurrentThread->WaitingThreads == NULL ) - SDL_Delay(10); + Threads_Glue_Yield(); } #endif @@ -286,14 +234,14 @@ void Threads_Exit(int TID, int Status) Threads_Wake(toWake); while(gpCurrentThread->WaitingThreads == toWake) - SDL_Delay(10); + Threads_Glue_Yield(); } } int Threads_Wake(tThread *Thread) { - Thread->State = 0; - kill( Thread->KernelTID, SIGUSR1 ); + Thread->Status = THREAD_STAT_ACTIVE; + Threads_PostEvent(Thread, THREAD_EVENT_WAKEUP); return 0; } @@ -319,66 +267,108 @@ int Threads_Fork(void) { tThread *thread = Threads_CloneTCB(gpCurrentThread); thread->PID = thread->TID; + // Duplicate the VFS handles (and nodes) from vfs_handle.c - VFS_CloneHandleList(thread->PID); return thread->PID; } -int Mutex_Acquire(tMutex *Mutex) +int Threads_Spawn(int nFD, int FDs[], struct s_sys_spawninfo *info) { - if(!Mutex->Protector.IsValid) { - pthread_mutex_init( &Mutex->Protector.Mutex, NULL ); - Mutex->Protector.IsValid = 1; + tThread *thread = Threads_CloneTCB(gpCurrentThread); + thread->PID = thread->TID; + if( info ) + { + // TODO: PGID? + //if( info->flags & SPAWNFLAG_NEWPGID ) + // thread->PGID = thread->PID; + if( info->gid && thread->UID == 0 ) + thread->GID = info->gid; + if( info->uid && thread->UID == 0 ) // last because ->UID is used above + thread->UID = info->uid; } - pthread_mutex_lock( &Mutex->Protector.Mutex ); + + VFS_CloneHandlesFromList(thread->PID, nFD, FDs); + + Log_Debug("Threads", "_spawn: %i", thread->PID); + return thread->PID; +} + +// -------------------------------------------------------------------- +// Mutexes +// -------------------------------------------------------------------- +int Mutex_Acquire(tMutex *Mutex) +{ + Threads_Glue_AcquireMutex(&Mutex->Protector.Mutex); return 0; } void Mutex_Release(tMutex *Mutex) { - pthread_mutex_unlock( &Mutex->Protector.Mutex ); + Threads_Glue_ReleaseMutex(&Mutex->Protector.Mutex); } +// -------------------------------------------------------------------- +// Semaphores +// -------------------------------------------------------------------- void Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const char *Module, const char *Name) { memset(Sem, 0, sizeof(tSemaphore)); // HACK: Use `Sem->Protector` as space for the semaphore pointer - *(void**)(&Sem->Protector) = SDL_CreateSemaphore(InitValue); + Threads_Glue_SemInit( &Sem->Protector.Mutex, InitValue ); } int Semaphore_Wait(tSemaphore *Sem, int MaxToTake) { - SDL_SemWait( *(void**)(&Sem->Protector) ); - return 1; + return Threads_Glue_SemWait( Sem->Protector.Mutex, MaxToTake ); } int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd) { - int i; - for( i = 0; i < AmmountToAdd; i ++ ) - SDL_SemPost( *(void**)(&Sem->Protector) ); - return AmmountToAdd; + return Threads_Glue_SemSignal( Sem->Protector.Mutex, AmmountToAdd ); } +// -------------------------------------------------------------------- +// Event handling +// -------------------------------------------------------------------- Uint32 Threads_WaitEvents(Uint32 Mask) { Uint32 rv; + + //Log_Debug("Threads", "Mask = %x, ->Events = %x", Mask, gpCurrentThread->Events); + gpCurrentThread->WaitMask = Mask; - if( !(gpCurrentThread->Events & Mask) ) - SDL_SemWait( gpCurrentThread->EventSem ); - rv = gpCurrentThread->Events & Mask; - gpCurrentThread->Events &= ~Mask; + if( !(gpCurrentThread->EventState & Mask) ) + { + if( Threads_Glue_SemWait(gpCurrentThread->EventSem, INT_MAX) == -1 ) { + Log_Warning("Threads", "Wait on eventsem of %p, %p failed", + gpCurrentThread, gpCurrentThread->EventSem); + } + //Log_Debug("Threads", "Woken from nap (%i here)", SDL_SemValue(gpCurrentThread->EventSem)); + } + rv = gpCurrentThread->EventState & Mask; + gpCurrentThread->EventState &= ~Mask; gpCurrentThread->WaitMask = -1; + + //Log_Debug("Threads", "- rv = %x", rv); + return rv; } void Threads_PostEvent(tThread *Thread, Uint32 Events) { - Thread->Events |= Events; - - if( Thread->WaitMask & Events ) - SDL_SemPost( gpCurrentThread->EventSem ); + Thread->EventState |= Events; +// Log_Debug("Threads", "Trigger event %x (->Events = %p) on %p", Events, Thread->Events, Thread); + + if( Events == 0 || Thread->WaitMask & Events ) { + Threads_Glue_SemSignal( Thread->EventSem, 1 ); +// Log_Debug("Threads", "Waking %p(%i %s)", Thread, Thread->TID, Thread->ThreadName); + } +} + +void Threads_ClearEvent(Uint32 EventMask) +{ + gpCurrentThread->EventState &= ~EventMask; }