2 * Acess2 libnative (Kernel Simulation Library)
3 * - By John Hodge (thePowersGang)
6 * - Internal threading functions
8 * POSIX Mutex/Semaphore management
15 #include <stdio.h> // printf debugging
16 #include <acess_logging.h>
17 #include <threads_int.h>
18 #include <pthread_weak.h>
19 #include <shortlock.h>
22 struct sThreadIntMutex { int lock; };
23 struct sThreadIntSem { int val; };
28 int Threads_int_ThreadingEnabled(void)
30 return !!pthread_create;
33 tThreadIntMutex *Threads_int_MutexCreate(void)
35 if( Threads_int_ThreadingEnabled() )
37 tThreadIntMutex *ret = malloc(sizeof(pthread_mutex_t));
38 pthread_mutex_init( (void*)ret, NULL );
43 return calloc(sizeof(tThreadIntMutex), 1);
47 void Threads_int_MutexLock(tThreadIntMutex *Mutex)
52 if( Threads_int_ThreadingEnabled() )
54 pthread_mutex_lock( (void*)Mutex );
59 Log_KernelPanic("Threads", "Double mutex lock");
64 void Threads_int_MutexRelease(tThreadIntMutex *Mutex)
70 if( Threads_int_ThreadingEnabled() )
72 pthread_mutex_unlock( (void*)Mutex );
77 Log_Notice("Threads", "Release of non-locked mutex %p", Mutex);
82 tThreadIntSem *Threads_int_SemCreate(void)
84 if( Threads_int_ThreadingEnabled() )
86 tThreadIntSem *ret = malloc(sizeof(sem_t));
87 sem_init( (void*)ret, 0, 0 );
92 return calloc(sizeof(tThreadIntSem), 1);
96 void Threads_int_SemSignal(tThreadIntSem *Sem)
98 if( Threads_int_ThreadingEnabled() )
100 sem_post( (void*)Sem );
108 void Threads_int_SemWaitAll(tThreadIntSem *Sem)
110 if( Threads_int_ThreadingEnabled() )
112 // TODO: Handle multiples
113 LOG("Waiting on %p", Sem);
114 sem_wait( (void*)Sem );
115 LOG("Wait 1 done, cleaning up");
116 while( sem_trywait((void*)Sem) == 0 )
123 Log_KernelPanic("Threads", "Waiting on empty semaphre %p", Sem);
128 void *Threads_int_ThreadRoot(void *ThreadPtr)
130 tThread *thread = ThreadPtr;
131 lpThreads_This = thread;
132 Log_Debug("Threads", "SpawnFcn: %p, SpawnData: %p", thread->SpawnFcn, thread->SpawnData);
133 thread->SpawnFcn(thread->SpawnData);
137 int Threads_int_CreateThread(tThread *Thread)
139 if( Threads_int_ThreadingEnabled() )
141 pthread_t *pthread = malloc(sizeof(pthread_t));
142 Thread->ThreadHandle = pthread;
143 return pthread_create(pthread, NULL, &Threads_int_ThreadRoot, Thread);
147 Log_KernelPanic("Threads", "Link with pthreads to use threading");
152 void SHORTLOCK(tShortSpinlock *Lock)
154 if( Threads_int_ThreadingEnabled() )
157 *Lock = malloc(sizeof(pthread_mutex_t));
158 pthread_mutex_init(*Lock, NULL);
160 // printf("%p: SHORTLOCK wait\n", lpThreads_This);
161 pthread_mutex_lock(*Lock);
162 // printf("%p: SHORTLOCK held %p\n", lpThreads_This, __builtin_return_address(0));
166 if(*Lock) Log_KernelPanic("---", "Double short lock");
171 void SHORTREL(tShortSpinlock *Lock)
173 if( Threads_int_ThreadingEnabled() )
175 pthread_mutex_unlock(*Lock);
176 // printf("%p: SHORTLOCK rel\n", lpThreads_This);
180 if(!*Lock) Log_Notice("---", "Short release when not held");
185 int CPU_HAS_LOCK(tShortSpinlock *Lock)
187 if( Threads_int_ThreadingEnabled() )
189 Log_KernelPanic("---", "TODO: CPU_HAS_LOCK with threading enabled");