static int ThreadHelper (void *startInfo) { ThreadFunction func; void *data; SDL_sem *sem; TrueThread thread; int result; func = ((struct ThreadStartInfo *) startInfo)->func; data = ((struct ThreadStartInfo *) startInfo)->data; sem = ((struct ThreadStartInfo *) startInfo)->sem; // Wait until the Thread structure is available. SDL_SemWait (sem); SDL_DestroySemaphore (sem); thread = ((struct ThreadStartInfo *) startInfo)->thread; HFree (startInfo); result = (*func) (data); #ifdef DEBUG_THREADS log_add (log_Debug, "Thread '%s' done (returned %d).", thread->name, result); fflush (stderr); #endif UnQueueThread (thread); DestroyThreadLocal (thread->localData); FinishThread (thread); /* Destroying the thread is the responsibility of ProcessThreadLifecycles() */ return result; }
Thread CreateThread_SDL (ThreadFunction func, void *data, SDWORD stackSize #ifdef NAMED_SYNCHRO , const char *name #endif ) { TrueThread thread; struct ThreadStartInfo *startInfo; thread = (struct _thread *) HMalloc (sizeof *thread); #ifdef NAMED_SYNCHRO thread->name = name; #endif #ifdef PROFILE_THREADS thread->startTime = GetTimeCounter (); #endif thread->localData = CreateThreadLocal (); startInfo = (struct ThreadStartInfo *) HMalloc (sizeof (*startInfo)); startInfo->func = func; startInfo->data = data; startInfo->sem = SDL_CreateSemaphore (0); startInfo->thread = thread; thread->native = SDL_CreateThread (ThreadHelper, (void *) startInfo); if (!(thread->native)) { DestroyThreadLocal (thread->localData); HFree (startInfo); HFree (thread); return NULL; } // The responsibility to free 'startInfo' and 'thread' is now by the new // thread. QueueThread (thread); #ifdef DEBUG_THREADS #if 0 log_add (log_Debug, "Thread '%s' created.", ThreadName (thread)); fflush (stderr); #endif #endif // Signal to the new thread that the thread structure is ready // and it can begin to use it. SDL_SemPost (startInfo->sem); (void) stackSize; /* Satisfying compiler (unused parameter) */ return thread; }
static void * ThreadHelper (void *startInfo) { ThreadFunction func; void *data; sem_t *sem; TrueThread thread; int result; //log_add (log_Debug, "ThreadHelper()"); func = ((struct ThreadStartInfo *) startInfo)->func; data = ((struct ThreadStartInfo *) startInfo)->data; sem = &((struct ThreadStartInfo *) startInfo)->sem; // Wait until the Thread structure is available. if (sem_wait (sem)) { log_add(log_Fatal, "ThreadHelper sem_wait fail"); exit(EXIT_FAILURE); } if (sem_destroy (sem)) { log_add(log_Fatal, "ThreadHelper sem_destroy fail"); exit(EXIT_FAILURE); } thread = ((struct ThreadStartInfo *) startInfo)->thread; HFree (startInfo); result = (*func) (data); #ifdef DEBUG_THREADS log_add (log_Debug, "Thread '%s' done (returned %d).", thread->name, result); fflush (stderr); #endif UnQueueThread (thread); DestroyThreadLocal (thread->localData); FinishThread (thread); /* Destroying the thread is the responsibility of ProcessThreadLifecycles() */ return (void*)result; }
Thread CreateThread_PT (ThreadFunction func, void *data, SDWORD stackSize #ifdef NAMED_SYNCHRO , const char *name #endif ) { TrueThread thread; struct ThreadStartInfo *startInfo; pthread_attr_t attr; //log_add (log_Debug, "CreateThread_PT '%s'", name); thread = (struct _thread *) HMalloc (sizeof *thread); #ifdef NAMED_SYNCHRO thread->name = name; #endif thread->localData = CreateThreadLocal (); startInfo = (struct ThreadStartInfo *) HMalloc (sizeof (*startInfo)); startInfo->func = func; startInfo->data = data; if (sem_init(&startInfo->sem, 0, 0) < 0) { log_add (log_Fatal, "createthread seminit fail"); exit(EXIT_FAILURE); } startInfo->thread = thread; pthread_attr_init(&attr); if (pthread_attr_setstacksize(&attr, 75000)) { log_add (log_Debug, "pthread stacksize fail"); } if (pthread_create(&thread->native, &attr, ThreadHelper, (void *)startInfo)) { log_add (log_Debug, "pthread create fail"); DestroyThreadLocal (thread->localData); HFree (startInfo); HFree (thread); return NULL; } // The responsibility to free 'startInfo' and 'thread' is now by the new // thread. QueueThread (thread); #ifdef DEBUG_THREADS //#if 0 log_add (log_Debug, "Thread '%s' created.", thread->name); fflush (stderr); //#endif #endif // Signal to the new thread that the thread structure is ready // and it can begin to use it. if (sem_post (&startInfo->sem)) { log_add(log_Fatal, "CreateThread sem_post fail"); exit(EXIT_FAILURE); } (void) stackSize; /* Satisfying compiler (unused parameter) */ return thread; }