2 * Acess2 libnative (Kernel Simulation Library)
3 * - By John Hodge (thePowersGang)
6 * - Internal threading functions
8 * POSIX Mutex/Semaphore management
14 #include <stdio.h> // printf debugging
15 #include <acess_logging.h>
16 #include <threads_int.h>
17 #include <pthread_weak.h>
18 #include <shortlock.h>
21 struct sThreadIntMutex { int lock; };
22 struct sThreadIntSem { int val; };
27 int Threads_int_ThreadingEnabled(void)
29 return !!pthread_create;
32 tThreadIntMutex *Threads_int_MutexCreate(void)
34 if( Threads_int_ThreadingEnabled() )
36 tThreadIntMutex *ret = malloc(sizeof(pthread_mutex_t));
37 pthread_mutex_init( (void*)ret, NULL );
42 return calloc(sizeof(tThreadIntMutex), 1);
46 void Threads_int_MutexLock(tThreadIntMutex *Mutex)
51 if( Threads_int_ThreadingEnabled() )
53 pthread_mutex_lock( (void*)Mutex );
58 Log_KernelPanic("Threads", "Double mutex lock");
63 void Threads_int_MutexRelease(tThreadIntMutex *Mutex)
69 if( Threads_int_ThreadingEnabled() )
71 pthread_mutex_unlock( (void*)Mutex );
76 Log_Notice("Threads", "Release of non-locked mutex %p", Mutex);
81 tThreadIntSem *Threads_int_SemCreate(void)
83 if( Threads_int_ThreadingEnabled() )
85 tThreadIntSem *ret = malloc(sizeof(sem_t));
86 sem_init( (void*)ret, 0, 0 );
91 return calloc(sizeof(tThreadIntSem), 1);
95 void Threads_int_SemSignal(tThreadIntSem *Sem)
97 if( Threads_int_ThreadingEnabled() )
99 sem_post( (void*)Sem );
107 void Threads_int_SemWaitAll(tThreadIntSem *Sem)
109 if( Threads_int_ThreadingEnabled() )
111 // TODO: Handle multiples
112 sem_wait( (void*)Sem );
113 while( sem_trywait((void*)Sem) )
119 Log_KernelPanic("Threads", "Waiting on empty semaphre %p", Sem);
124 void *Threads_int_ThreadRoot(void *ThreadPtr)
126 tThread *thread = ThreadPtr;
127 lpThreads_This = thread;
128 Log_Debug("Threads", "SpawnFcn: %p, SpawnData: %p", thread->SpawnFcn, thread->SpawnData);
129 thread->SpawnFcn(thread->SpawnData);
133 int Threads_int_CreateThread(tThread *Thread)
135 if( Threads_int_ThreadingEnabled() )
137 pthread_t *pthread = malloc(sizeof(pthread_t));
138 Thread->ThreadHandle = pthread;
139 return pthread_create(pthread, NULL, &Threads_int_ThreadRoot, Thread);
143 Log_KernelPanic("Threads", "Link with pthreads to use threading");
148 void SHORTLOCK(tShortSpinlock *Lock)
150 if( Threads_int_ThreadingEnabled() )
153 *Lock = malloc(sizeof(pthread_mutex_t));
154 pthread_mutex_init(*Lock, NULL);
156 // printf("%p: SHORTLOCK wait\n", lpThreads_This);
157 pthread_mutex_lock(*Lock);
158 // printf("%p: SHORTLOCK held %p\n", lpThreads_This, __builtin_return_address(0));
162 if(*Lock) Log_KernelPanic("---", "Double short lock");
167 void SHORTREL(tShortSpinlock *Lock)
169 if( Threads_int_ThreadingEnabled() )
171 pthread_mutex_unlock(*Lock);
172 // printf("%p: SHORTLOCK rel\n", lpThreads_This);
176 if(!*Lock) Log_Notice("---", "Short release when not held");
181 int CPU_HAS_LOCK(tShortSpinlock *Lock)
183 if( Threads_int_ThreadingEnabled() )
185 Log_KernelPanic("---", "TODO: CPU_HAS_LOCK with threading enabled");