AcessNative - Bugfixing
[tpg/acess2.git] / AcessNative / acesskernel_src / threads.c
1 /*
2  * Acess2 Native Kernel
3  * - Acess kernel emulation on another OS using SDL and UDP
4  *
5  * threads.c
6  * - Thread and process handling
7  */
8 #define _SIGNAL_H_
9 #undef CLONE_VM // Such a hack
10 #include <acess.h>
11 #include <unistd.h>
12 #include <sys/types.h>
13 #include <stdint.h>
14 #include "/usr/include/signal.h"
15
16 // === STRUCTURES ===
17 #if 0
18 typedef struct sState
19 {
20         void    *CurState;
21         Uint    SP, BP, IP;
22 }       tState;
23 #endif
24
25 typedef struct sThread
26 {
27         struct sThread  *Next;
28
29          int    KernelTID;
30
31         tTID    TID, PID;
32         tUID    UID, GID;
33
34         struct sThread  *Parent;
35
36         char    *ThreadName;
37
38          int    State;  // 0: Dead, 1: Active, 2: Paused, 3: Asleep
39         #if 0
40         tState  CurState;
41         #endif
42
43         // Config?
44         Uint    Config[NUM_CFG_ENTRIES];
45 }       tThread;
46
47 // === GLOBALS ===
48 tThread gThread_Zero = {
49         State: 1,
50         ThreadName: "ThreadZero"
51 };
52 tThread *gpThreads = &gThread_Zero;
53 __thread tThread        *gpCurrentThread = &gThread_Zero;
54
55 // === CODE ===
56 tThread *Threads_GetThread(int TID)
57 {
58         tThread *thread;
59         for( thread = gpThreads; thread; thread = thread->Next )
60         {
61                 if( thread->TID == TID )
62                         return thread;
63         }
64         return NULL;
65 }
66
67 tUID Threads_GetUID() { return gpCurrentThread->UID; }
68 tGID Threads_GetGID() { return gpCurrentThread->GID; }
69 tTID Threads_GetTID() { return gpCurrentThread->TID; }
70 tPID Threads_GetPID() {
71         return SDL_ThreadID();
72         //return gpCurrentThread->PID;
73 }
74
75 Uint *Threads_GetCfgPtr(int Index)
76 {
77         if( Index < 0 || Index >= NUM_CFG_ENTRIES )
78                 return NULL;
79         if( !gpCurrentThread )
80                 return NULL;
81         return &gpCurrentThread->Config[Index];
82 }
83
84 void Threads_Sleep(void)
85 {
86         pause();
87 }
88
89 void Threads_Yield(void)
90 {
91 //      yield();
92 }
93
94 int Threads_WakeTID(tTID TID)
95 {
96         tThread *thread;
97         thread = Threads_GetThread(TID);
98         if( !thread )   return -1;
99         kill( thread->KernelTID, SIGUSR1 );
100         return 0;
101 }
102
103 void Mutex_Acquire(tMutex *Mutex)
104 {
105         if(!Mutex->Protector.IsValid) {
106                 pthread_mutex_init( &Mutex->Protector.Mutex, NULL );
107                 Mutex->Protector.IsValid = 1;
108         }
109         pthread_mutex_lock( &Mutex->Protector.Mutex );
110 }
111
112 void Mutex_Release(tMutex *Mutex)
113 {
114         pthread_mutex_unlock( &Mutex->Protector.Mutex );
115 }
116
117 #if 0
118 void Threads_Sleep()
119 {
120         gpCurrentThread->State = 3;
121         if( setjmp(&gpCurrentThread->CurState) == 0 ) {
122                 // Return to user wait
123                 // Hmm... maybe I should have a "kernel" thread for every "user" thread
124         }
125         else {
126                 // Just woken up, return
127                 return ;
128         }
129 }
130
131 int SaveState(tState *To)
132 {
133         Uint    ip;
134         __asm__ __volatile__(
135                 "call 1f;\n\t"
136                 "1f:\n\t"
137                 "pop %%eax"
138                 : "=a" (ip)
139                 : );
140         // If we just returned
141         if(!ip) return 1;
142
143         To->IP = ip;
144         __asm__ __volatile__ ("mov %%esp, %1" : "=r"(To->SP));
145         __asm__ __volatile__ ("mov %%ebp, %1" : "=r"(To->BP));
146 }
147 #endif
148

UCC git Repository :: git.ucc.asn.au