2 * Acess2 libnative (Kernel Simulation Library)
3 * - By John Hodge (thePowersGang)
10 #include <threads_int.h>
13 void Threads_int_Init(void) __attribute__((constructor(101)));
14 tThread *Threads_int_CreateTCB(tThread *Parent);
17 tThread *gThreads_List;
18 tThread __thread *lpThreads_This;
19 int giThreads_NextTID = 1;
20 tShortSpinlock glThreadListLock;
23 void Threads_int_Init(void)
25 if( !lpThreads_This ) {
26 lpThreads_This = Threads_int_CreateTCB(NULL);
27 Threads_SetName("ThreadZero");
31 tThread *Proc_GetCurThread(void)
33 return lpThreads_This;
36 void Threads_PostEvent(tThread *Thread, Uint32 Events)
42 SHORTLOCK( &Thread->IsLocked );
43 Thread->PendingEvents |= Events;
44 if( Thread->WaitingEvents & Events )
45 Threads_int_SemSignal(Thread->WaitSemaphore);
46 SHORTREL( &Thread->IsLocked );
49 Uint32 Threads_WaitEvents(Uint32 Events)
51 if( !Threads_int_ThreadingEnabled() ) {
52 Log_Notice("Threads", "_WaitEvents: Threading disabled");
55 lpThreads_This->WaitingEvents = Events;
56 Threads_int_SemWaitAll(lpThreads_This->WaitSemaphore);
57 lpThreads_This->WaitingEvents = 0;
58 Uint32 rv = lpThreads_This->PendingEvents;
62 void Threads_ClearEvent(Uint32 Mask)
64 if( !Threads_int_ThreadingEnabled() ) {
65 Log_Notice("Threads", "_ClearEvent: Threading disabled");
68 SHORTLOCK(&lpThreads_This->IsLocked);
69 lpThreads_This->PendingEvents &= ~Mask;
70 SHORTREL(&lpThreads_This->IsLocked);
73 tUID Threads_GetUID(void) { return 0; }
74 tGID Threads_GetGID(void) { return 0; }
76 tTID Threads_GetTID(void) { return lpThreads_This ? lpThreads_This->TID : 0; }
78 int *Threads_GetMaxFD(void) { return &lpThreads_This->Process->MaxFDs; }
79 char **Threads_GetCWD(void) { return &lpThreads_This->Process->CWD; }
80 char **Threads_GetChroot(void) { return &lpThreads_This->Process->Chroot; }
81 void **Threads_GetHandlesPtr(void) { return &lpThreads_This->Process->Handles; }
83 void Threads_Yield(void)
85 Log_KernelPanic("Threads", "Threads_Yield DEFINITELY shouldn't be used (%p)",
86 __builtin_return_address(0));
89 void Threads_Sleep(void)
91 Log_Warning("Threads", "Threads_Sleep shouldn't be used");
94 void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
96 while( lpThreads_This->Status != Status )
97 Threads_int_SemWaitAll(lpThreads_This->WaitSemaphore);
100 int Threads_SetName(const char *Name)
102 if( !lpThreads_This )
105 if( lpThreads_This->ThreadName )
106 free(lpThreads_This->ThreadName);
107 lpThreads_This->ThreadName = strdup(Name);
112 int *Threads_GetErrno(void) __attribute__ ((weak));
114 int *Threads_GetErrno(void)
120 tThread *Threads_RemActive(void)
122 return lpThreads_This;
125 void Threads_AddActive(tThread *Thread)
127 Thread->Status = THREAD_STAT_ACTIVE;
128 // Increment state-change semaphore
129 Threads_int_SemSignal(Thread->WaitSemaphore);
132 struct sProcess *Threads_int_CreateProcess(void)
134 struct sProcess *ret = calloc(sizeof(struct sProcess), 1);
141 tThread *Threads_int_CreateTCB(tThread *Parent)
143 tThread *ret = calloc( sizeof(tThread), 1 );
144 ret->TID = giThreads_NextTID ++;
145 ret->WaitSemaphore = Threads_int_SemCreate();
146 //ret->Protector = Threads_int_MutexCreate();
150 ret->Process = Threads_int_CreateProcess();
153 ret->Process = Parent->Process;
155 ret->ProcNext = ret->Process->Threads;
156 ret->Process->Threads = ret;
158 ret->Next = gThreads_List;
164 struct sThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
166 if( !Threads_int_ThreadingEnabled() )
168 Log_Error("Threads", "Multithreading is disabled in this build");
173 tThread *ret = Threads_int_CreateTCB(lpThreads_This);
175 ret->SpawnData = Data;
176 Threads_int_CreateThread(ret);