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

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