SDL  2.0
SDL_thread.c File Reference
#include "../SDL_internal.h"
#include "SDL_assert.h"
#include "SDL_thread.h"
#include "SDL_thread_c.h"
#include "SDL_systhread.h"
#include "SDL_hints.h"
#include "../SDL_error_c.h"
+ Include dependency graph for SDL_thread.c:

Go to the source code of this file.

Data Structures

struct  SDL_TLSEntry
 
struct  thread_args
 

Macros

#define SDL_CreateThread   SDL_CreateThread_REAL
 
#define SDL_CreateThreadWithStackSize   SDL_CreateThreadWithStackSize_REAL
 

Functions

SDL_TLSID SDL_TLSCreate ()
 Create an identifier that is globally visible to all threads but refers to data that is thread-specific. More...
 
voidSDL_TLSGet (SDL_TLSID id)
 Get the value associated with a thread local storage ID for the current thread. More...
 
int SDL_TLSSet (SDL_TLSID id, const void *value, void(*destructor)(void *))
 Set the value associated with a thread local storage ID for the current thread. More...
 
static void SDL_TLSCleanup ()
 
SDL_TLSDataSDL_Generic_GetTLSData (void)
 
int SDL_Generic_SetTLSData (SDL_TLSData *storage)
 
SDL_errorSDL_GetErrBuf (void)
 
void SDL_RunThread (void *data)
 
SDL_ThreadSDL_CreateThreadWithStackSize (int(*fn)(void *), const char *name, const size_t stacksize, void *data)
 
SDL_ThreadSDL_CreateThread (int(*fn)(void *), const char *name, void *data)
 
SDL_ThreadSDL_CreateThreadInternal (int(*fn)(void *), const char *name, const size_t stacksize, void *data)
 
SDL_threadID SDL_GetThreadID (SDL_Thread *thread)
 
const char * SDL_GetThreadName (SDL_Thread *thread)
 
int SDL_SetThreadPriority (SDL_ThreadPriority priority)
 
void SDL_WaitThread (SDL_Thread *thread, int *status)
 
void SDL_DetachThread (SDL_Thread *thread)
 

Variables

static SDL_mutexSDL_generic_TLS_mutex
 
static SDL_TLSEntrySDL_generic_TLS
 

Macro Definition Documentation

◆ SDL_CreateThread

#define SDL_CreateThread   SDL_CreateThread_REAL

Definition at line 312 of file SDL_thread.c.

◆ SDL_CreateThreadWithStackSize

#define SDL_CreateThreadWithStackSize   SDL_CreateThreadWithStackSize_REAL

Definition at line 313 of file SDL_thread.c.

Function Documentation

◆ SDL_CreateThread()

SDL_Thread* SDL_CreateThread ( int(*)(void *)  fn,
const char *  name,
void data 
)

Definition at line 408 of file SDL_thread.c.

411 {
412  /* !!! FIXME: in 2.1, just make stackhint part of the usual API. */
413  const char *stackhint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE);
414  size_t stacksize = 0;
415 
416  /* If the SDL_HINT_THREAD_STACK_SIZE exists, use it */
417  if (stackhint != NULL) {
418  char *endp = NULL;
419  const Sint64 hintval = SDL_strtoll(stackhint, &endp, 10);
420  if ((*stackhint != '\0') && (*endp == '\0')) { /* a valid number? */
421  if (hintval > 0) { /* reject bogus values. */
422  stacksize = (size_t) hintval;
423  }
424  }
425  }
426 
427 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
428  return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, pfnBeginThread, pfnEndThread);
429 #else
430  return SDL_CreateThreadWithStackSize(fn, name, stacksize, data);
431 #endif
432 }

References NULL, SDL_CreateThreadWithStackSize, SDL_GetHint, SDL_HINT_THREAD_STACK_SIZE, and SDL_strtoll.

◆ SDL_CreateThreadInternal()

SDL_Thread* SDL_CreateThreadInternal ( int(*)(void *)  fn,
const char *  name,
const size_t  stacksize,
void data 
)

Definition at line 435 of file SDL_thread.c.

436  {
437 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
438  return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, NULL, NULL);
439 #else
440  return SDL_CreateThreadWithStackSize(fn, name, stacksize, data);
441 #endif
442 }

References NULL, and SDL_CreateThreadWithStackSize.

Referenced by open_audio_device(), and SDL_TimerInit().

◆ SDL_CreateThreadWithStackSize()

SDL_Thread* SDL_CreateThreadWithStackSize ( int(*)(void *)  fn,
const char *  name,
const size_t  stacksize,
void data 
)

Definition at line 323 of file SDL_thread.c.

326 {
327  SDL_Thread *thread;
328  thread_args *args;
329  int ret;
330 
331  /* Allocate memory for the thread info structure */
332  thread = (SDL_Thread *) SDL_malloc(sizeof(*thread));
333  if (thread == NULL) {
334  SDL_OutOfMemory();
335  return (NULL);
336  }
337  SDL_zerop(thread);
338  thread->status = -1;
340 
341  /* Set up the arguments for the thread */
342  if (name != NULL) {
343  thread->name = SDL_strdup(name);
344  if (thread->name == NULL) {
345  SDL_OutOfMemory();
346  SDL_free(thread);
347  return (NULL);
348  }
349  }
350 
351  /* Set up the arguments for the thread */
352  args = (thread_args *) SDL_malloc(sizeof(*args));
353  if (args == NULL) {
354  SDL_OutOfMemory();
355  if (thread->name) {
356  SDL_free(thread->name);
357  }
358  SDL_free(thread);
359  return (NULL);
360  }
361  args->func = fn;
362  args->data = data;
363  args->info = thread;
364  args->wait = SDL_CreateSemaphore(0);
365  if (args->wait == NULL) {
366  if (thread->name) {
367  SDL_free(thread->name);
368  }
369  SDL_free(thread);
370  SDL_free(args);
371  return (NULL);
372  }
373 
374  thread->stacksize = stacksize;
375 
376  /* Create the thread and go! */
377 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
378  ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread);
379 #else
380  ret = SDL_SYS_CreateThread(thread, args);
381 #endif
382  if (ret >= 0) {
383  /* Wait for the thread function to use arguments */
384  SDL_SemWait(args->wait);
385  } else {
386  /* Oops, failed. Gotta free everything */
387  if (thread->name) {
388  SDL_free(thread->name);
389  }
390  SDL_free(thread);
391  thread = NULL;
392  }
393  SDL_DestroySemaphore(args->wait);
394  SDL_free(args);
395 
396  /* Everything is running now */
397  return (thread);
398 }

References thread_args::data, thread_args::func, thread_args::info, NULL, SDL_AtomicSet, SDL_CreateSemaphore, SDL_DestroySemaphore, SDL_free, SDL_malloc, SDL_OutOfMemory, SDL_SemWait, SDL_strdup, SDL_SYS_CreateThread(), SDL_THREAD_STATE_ALIVE, SDL_zerop, SDL_TLSEntry::thread, and thread_args::wait.

◆ SDL_DetachThread()

void SDL_DetachThread ( SDL_Thread thread)

A thread may be "detached" to signify that it should not remain until another thread has called SDL_WaitThread() on it. Detaching a thread is useful for long-running threads that nothing needs to synchronize with or further manage. When a detached thread is done, it simply goes away.

There is no way to recover the return code of a detached thread. If you need this, don't detach the thread and instead use SDL_WaitThread().

Once a thread is detached, you should usually assume the SDL_Thread isn't safe to reference again, as it will become invalid immediately upon the detached thread's exit, instead of remaining until someone has called SDL_WaitThread() to finally clean it up. As such, don't detach the same thread more than once.

If a thread has already exited when passed to SDL_DetachThread(), it will stop waiting for a call to SDL_WaitThread() and clean up immediately. It is not safe to detach a thread that might be used with SDL_WaitThread().

You may not call SDL_WaitThread() on a thread that has been detached. Use either that function or this one, but not both, or behavior is undefined.

It is safe to pass NULL to this function; it is a no-op.

Definition at line 489 of file SDL_thread.c.

490 {
491  if (!thread) {
492  return;
493  }
494 
495  /* Grab dibs if the state is alive+joinable. */
497  SDL_SYS_DetachThread(thread);
498  } else {
499  /* all other states are pretty final, see where we landed. */
500  const int thread_state = SDL_AtomicGet(&thread->state);
501  if ((thread_state == SDL_THREAD_STATE_DETACHED) || (thread_state == SDL_THREAD_STATE_CLEANED)) {
502  return; /* already detached (you shouldn't call this twice!) */
503  } else if (thread_state == SDL_THREAD_STATE_ZOMBIE) {
504  SDL_WaitThread(thread, NULL); /* already done, clean it up. */
505  } else {
506  SDL_assert(0 && "Unexpected thread state");
507  }
508  }
509 }

References NULL, SDL_assert, SDL_AtomicCAS, SDL_AtomicGet, SDL_SYS_DetachThread(), SDL_THREAD_STATE_ALIVE, SDL_THREAD_STATE_CLEANED, SDL_THREAD_STATE_DETACHED, SDL_THREAD_STATE_ZOMBIE, SDL_WaitThread(), and SDL_TLSEntry::thread.

◆ SDL_Generic_GetTLSData()

SDL_TLSData* SDL_Generic_GetTLSData ( void  )

Definition at line 124 of file SDL_thread.c.

125 {
126  SDL_threadID thread = SDL_ThreadID();
127  SDL_TLSEntry *entry;
128  SDL_TLSData *storage = NULL;
129 
130 #if !SDL_THREADS_DISABLED
131  if (!SDL_generic_TLS_mutex) {
132  static SDL_SpinLock tls_lock;
133  SDL_AtomicLock(&tls_lock);
134  if (!SDL_generic_TLS_mutex) {
138  if (!SDL_generic_TLS_mutex) {
139  SDL_AtomicUnlock(&tls_lock);
140  return NULL;
141  }
142  }
143  SDL_AtomicUnlock(&tls_lock);
144  }
145 #endif /* SDL_THREADS_DISABLED */
146 
149  for (entry = SDL_generic_TLS; entry; entry = entry->next) {
150  if (entry->thread == thread) {
151  storage = entry->storage;
152  break;
153  }
154  }
155 #if !SDL_THREADS_DISABLED
157 #endif
158 
159  return storage;
160 }

References mutex, SDL_TLSEntry::next, NULL, SDL_AtomicLock, SDL_AtomicUnlock, SDL_CreateMutex, SDL_generic_TLS, SDL_generic_TLS_mutex, SDL_LockMutex, SDL_MemoryBarrierAcquire, SDL_MemoryBarrierRelease, SDL_ThreadID, SDL_UnlockMutex, SDL_TLSEntry::storage, and SDL_TLSEntry::thread.

Referenced by SDL_SYS_GetTLSData().

◆ SDL_Generic_SetTLSData()

int SDL_Generic_SetTLSData ( SDL_TLSData storage)

Definition at line 163 of file SDL_thread.c.

164 {
165  SDL_threadID thread = SDL_ThreadID();
166  SDL_TLSEntry *prev, *entry;
167 
168  /* SDL_Generic_GetTLSData() is always called first, so we can assume SDL_generic_TLS_mutex */
170  prev = NULL;
171  for (entry = SDL_generic_TLS; entry; entry = entry->next) {
172  if (entry->thread == thread) {
173  if (storage) {
174  entry->storage = storage;
175  } else {
176  if (prev) {
177  prev->next = entry->next;
178  } else {
179  SDL_generic_TLS = entry->next;
180  }
181  SDL_free(entry);
182  }
183  break;
184  }
185  prev = entry;
186  }
187  if (!entry) {
188  entry = (SDL_TLSEntry *)SDL_malloc(sizeof(*entry));
189  if (entry) {
190  entry->thread = thread;
191  entry->storage = storage;
192  entry->next = SDL_generic_TLS;
193  SDL_generic_TLS = entry;
194  }
195  }
197 
198  if (!entry) {
199  return SDL_OutOfMemory();
200  }
201  return 0;
202 }

References SDL_TLSEntry::next, NULL, SDL_free, SDL_generic_TLS, SDL_generic_TLS_mutex, SDL_LockMutex, SDL_malloc, SDL_OutOfMemory, SDL_ThreadID, SDL_UnlockMutex, SDL_TLSEntry::storage, and SDL_TLSEntry::thread.

Referenced by SDL_SYS_SetTLSData().

◆ SDL_GetErrBuf()

SDL_error* SDL_GetErrBuf ( void  )

Definition at line 206 of file SDL_thread.c.

207 {
208 #if SDL_THREADS_DISABLED
209  /* Non-thread-safe global error variable */
210  static SDL_error SDL_global_error;
211  return &SDL_global_error;
212 #else
213  static SDL_SpinLock tls_lock;
214  static SDL_bool tls_being_created;
215  static SDL_TLSID tls_errbuf;
216  static SDL_error SDL_global_errbuf;
217  const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1;
218  SDL_error *errbuf;
219 
220  /* tls_being_created is there simply to prevent recursion if SDL_TLSCreate() fails.
221  It also means it's possible for another thread to also use SDL_global_errbuf,
222  but that's very unlikely and hopefully won't cause issues.
223  */
224  if (!tls_errbuf && !tls_being_created) {
225  SDL_AtomicLock(&tls_lock);
226  if (!tls_errbuf) {
227  SDL_TLSID slot;
228  tls_being_created = SDL_TRUE;
229  slot = SDL_TLSCreate();
230  tls_being_created = SDL_FALSE;
232  tls_errbuf = slot;
233  }
234  SDL_AtomicUnlock(&tls_lock);
235  }
236  if (!tls_errbuf) {
237  return &SDL_global_errbuf;
238  }
239 
241  errbuf = (SDL_error *)SDL_TLSGet(tls_errbuf);
242  if (errbuf == ALLOCATION_IN_PROGRESS) {
243  return &SDL_global_errbuf;
244  }
245  if (!errbuf) {
246  /* Mark that we're in the middle of allocating our buffer */
247  SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
248  errbuf = (SDL_error *)SDL_malloc(sizeof(*errbuf));
249  if (!errbuf) {
250  SDL_TLSSet(tls_errbuf, NULL, NULL);
251  return &SDL_global_errbuf;
252  }
253  SDL_zerop(errbuf);
254  SDL_TLSSet(tls_errbuf, errbuf, SDL_free);
255  }
256  return errbuf;
257 #endif /* SDL_THREADS_DISABLED */
258 }

References NULL, SDL_AtomicLock, SDL_AtomicUnlock, SDL_FALSE, SDL_free, SDL_malloc, SDL_MemoryBarrierAcquire, SDL_MemoryBarrierRelease, SDL_TLSCreate(), SDL_TLSGet(), SDL_TLSSet(), SDL_TRUE, and SDL_zerop.

Referenced by SDL_ClearError(), SDL_GetErrorMsg(), and SDL_SetError().

◆ SDL_GetThreadID()

SDL_threadID SDL_GetThreadID ( SDL_Thread thread)

Get the thread identifier for the specified thread.

Equivalent to SDL_ThreadID() if the specified thread is NULL.

Definition at line 445 of file SDL_thread.c.

446 {
448 
449  if (thread) {
450  id = thread->threadid;
451  } else {
452  id = SDL_ThreadID();
453  }
454  return id;
455 }

References SDL_ThreadID, and SDL_TLSEntry::thread.

◆ SDL_GetThreadName()

const char* SDL_GetThreadName ( SDL_Thread thread)

Get the thread name, as it was specified in SDL_CreateThread(). This function returns a pointer to a UTF-8 string that names the specified thread, or NULL if it doesn't have a name. This is internal memory, not to be free()'d by the caller, and remains valid until the specified thread is cleaned up by SDL_WaitThread().

Definition at line 458 of file SDL_thread.c.

459 {
460  if (thread) {
461  return thread->name;
462  } else {
463  return NULL;
464  }
465 }

References NULL, and SDL_TLSEntry::thread.

◆ SDL_RunThread()

void SDL_RunThread ( void data)

Definition at line 271 of file SDL_thread.c.

272 {
273  thread_args *args = (thread_args *) data;
274  int (SDLCALL * userfunc) (void *) = args->func;
275  void *userdata = args->data;
276  SDL_Thread *thread = args->info;
277  int *statusloc = &thread->status;
278 
279  /* Perform any system-dependent setup - this function may not fail */
280  SDL_SYS_SetupThread(thread->name);
281 
282  /* Get the thread id */
283  thread->threadid = SDL_ThreadID();
284 
285  /* Wake up the parent thread */
286  SDL_SemPost(args->wait);
287 
288  /* Run the function */
289  *statusloc = userfunc(userdata);
290 
291  /* Clean up thread-local storage */
292  SDL_TLSCleanup();
293 
294  /* Mark us as ready to be joined (or detached) */
296  /* Clean up if something already detached us. */
298  if (thread->name) {
299  SDL_free(thread->name);
300  }
301  SDL_free(thread);
302  }
303  }
304 }

References thread_args::data, thread_args::func, thread_args::info, SDL_AtomicCAS, SDL_free, SDL_SemPost, SDL_SYS_SetupThread(), SDL_THREAD_STATE_ALIVE, SDL_THREAD_STATE_CLEANED, SDL_THREAD_STATE_DETACHED, SDL_THREAD_STATE_ZOMBIE, SDL_ThreadID, SDL_TLSCleanup(), SDLCALL, SDL_TLSEntry::thread, and thread_args::wait.

Referenced by RunThread().

◆ SDL_SetThreadPriority()

int SDL_SetThreadPriority ( SDL_ThreadPriority  priority)

Set the priority for the current thread

Definition at line 468 of file SDL_thread.c.

469 {
470  return SDL_SYS_SetThreadPriority(priority);
471 }

References SDL_SYS_SetThreadPriority().

◆ SDL_TLSCleanup()

static void SDL_TLSCleanup ( )
static

Definition at line 87 of file SDL_thread.c.

88 {
89  SDL_TLSData *storage;
90 
91  storage = SDL_SYS_GetTLSData();
92  if (storage) {
93  unsigned int i;
94  for (i = 0; i < storage->limit; ++i) {
95  if (storage->array[i].destructor) {
96  storage->array[i].destructor(storage->array[i].data);
97  }
98  }
100  SDL_free(storage);
101  }
102 }

References SDL_TLSData::array, SDL_TLSData::data, SDL_TLSData::destructor, i, SDL_TLSData::limit, NULL, SDL_free, SDL_SYS_GetTLSData(), and SDL_SYS_SetTLSData().

Referenced by SDL_RunThread().

◆ SDL_TLSCreate()

SDL_TLSID SDL_TLSCreate ( void  )

Create an identifier that is globally visible to all threads but refers to data that is thread-specific.

Returns
The newly created thread local storage identifier, or 0 on error
static SDL_SpinLock tls_lock;
void SetMyThreadData(void *value)
{
SDL_AtomicLock(&tls_lock);
}
SDL_AtomicUnlock(&tls_lock);
}
}
void *GetMyThreadData(void)
{
}
See also
SDL_TLSGet()
SDL_TLSSet()

Definition at line 34 of file SDL_thread.c.

35 {
36  static SDL_atomic_t SDL_tls_id;
37  return SDL_AtomicIncRef(&SDL_tls_id)+1;
38 }

References SDL_AtomicIncRef.

Referenced by SDL_GetErrBuf().

◆ SDL_TLSGet()

void* SDL_TLSGet ( SDL_TLSID  id)

Get the value associated with a thread local storage ID for the current thread.

Parameters
idThe thread local storage ID
Returns
The value associated with the ID for the current thread, or NULL if no value has been set.
See also
SDL_TLSCreate()
SDL_TLSSet()

Definition at line 41 of file SDL_thread.c.

42 {
43  SDL_TLSData *storage;
44 
45  storage = SDL_SYS_GetTLSData();
46  if (!storage || id == 0 || id > storage->limit) {
47  return NULL;
48  }
49  return storage->array[id-1].data;
50 }

References SDL_TLSData::array, SDL_TLSData::data, SDL_TLSData::limit, NULL, and SDL_SYS_GetTLSData().

Referenced by SDL_GetErrBuf().

◆ SDL_TLSSet()

int SDL_TLSSet ( SDL_TLSID  id,
const void value,
void(*)(void *)  destructor 
)

Set the value associated with a thread local storage ID for the current thread.

Parameters
idThe thread local storage ID
valueThe value to associate with the ID for the current thread
destructorA function called when the thread exits, to free the value.
Returns
0 on success, -1 on error
See also
SDL_TLSCreate()
SDL_TLSGet()

Definition at line 53 of file SDL_thread.c.

54 {
55  SDL_TLSData *storage;
56 
57  if (id == 0) {
58  return SDL_InvalidParamError("id");
59  }
60 
61  storage = SDL_SYS_GetTLSData();
62  if (!storage || (id > storage->limit)) {
63  unsigned int i, oldlimit, newlimit;
64 
65  oldlimit = storage ? storage->limit : 0;
66  newlimit = (id + TLS_ALLOC_CHUNKSIZE);
67  storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage)+(newlimit-1)*sizeof(storage->array[0]));
68  if (!storage) {
69  return SDL_OutOfMemory();
70  }
71  storage->limit = newlimit;
72  for (i = oldlimit; i < newlimit; ++i) {
73  storage->array[i].data = NULL;
74  storage->array[i].destructor = NULL;
75  }
76  if (SDL_SYS_SetTLSData(storage) != 0) {
77  return -1;
78  }
79  }
80 
81  storage->array[id-1].data = SDL_const_cast(void*, value);
82  storage->array[id-1].destructor = destructor;
83  return 0;
84 }

References SDL_TLSData::array, SDL_TLSData::data, SDL_TLSData::destructor, i, SDL_TLSData::limit, NULL, SDL_const_cast, SDL_InvalidParamError, SDL_OutOfMemory, SDL_realloc, SDL_SYS_GetTLSData(), SDL_SYS_SetTLSData(), and TLS_ALLOC_CHUNKSIZE.

Referenced by SDL_GetErrBuf().

◆ SDL_WaitThread()

void SDL_WaitThread ( SDL_Thread thread,
int *  status 
)

Wait for a thread to finish. Threads that haven't been detached will remain (as a "zombie") until this function cleans them up. Not doing so is a resource leak.

Once a thread has been cleaned up through this function, the SDL_Thread that references it becomes invalid and should not be referenced again. As such, only one thread may call SDL_WaitThread() on another.

The return code for the thread function is placed in the area pointed to by status, if status is not NULL.

You may not wait on a thread that has been used in a call to SDL_DetachThread(). Use either that function or this one, but not both, or behavior is undefined.

It is safe to pass NULL to this function; it is a no-op.

Definition at line 474 of file SDL_thread.c.

475 {
476  if (thread) {
477  SDL_SYS_WaitThread(thread);
478  if (status) {
479  *status = thread->status;
480  }
481  if (thread->name) {
482  SDL_free(thread->name);
483  }
484  SDL_free(thread);
485  }
486 }

References SDL_free, SDL_SYS_WaitThread(), and SDL_TLSEntry::thread.

Referenced by SDL_DetachThread().

Variable Documentation

◆ SDL_generic_TLS

SDL_TLSEntry* SDL_generic_TLS
static

Definition at line 120 of file SDL_thread.c.

Referenced by SDL_Generic_GetTLSData(), and SDL_Generic_SetTLSData().

◆ SDL_generic_TLS_mutex

SDL_mutex* SDL_generic_TLS_mutex
static

Definition at line 119 of file SDL_thread.c.

Referenced by SDL_Generic_GetTLSData(), and SDL_Generic_SetTLSData().

SDL_TLSData
Definition: SDL_thread_c.h:70
SDL_HINT_THREAD_STACK_SIZE
#define SDL_HINT_THREAD_STACK_SIZE
A string specifying SDL's threads stack size in bytes or "0" for the backend's default size.
Definition: SDL_hints.h:731
thread_args::func
int(* func)(void *)
Definition: SDL_thread.c:264
SDL_THREAD_STATE_DETACHED
@ SDL_THREAD_STATE_DETACHED
Definition: SDL_thread_c.h:48
SDL_TLSSet
#define SDL_TLSSet
Definition: SDL_dynapi_overrides.h:482
Sint64
int64_t Sint64
Definition: SDL_stdinc.h:210
SDL_THREAD_STATE_ALIVE
@ SDL_THREAD_STATE_ALIVE
Definition: SDL_thread_c.h:47
thread_args::data
void * data
Definition: SDL_thread.c:265
TLS_ALLOC_CHUNKSIZE
#define TLS_ALLOC_CHUNKSIZE
Definition: SDL_thread_c.h:79
SDL_TLSData::destructor
void(* destructor)(void *)
Definition: SDL_thread_c.h:74
SDL_CreateSemaphore
#define SDL_CreateSemaphore
Definition: SDL_dynapi_overrides.h:264
SDL_AtomicCAS
#define SDL_AtomicCAS
Definition: SDL_dynapi_overrides.h:66
SDL_Thread::stacksize
size_t stacksize
Definition: SDL_thread_c.h:62
SDL_LockMutex
#define SDL_LockMutex
Definition: SDL_dynapi_overrides.h:260
NULL
#define NULL
Definition: begin_code.h:167
SDL_MemoryBarrierRelease
#define SDL_MemoryBarrierRelease()
Definition: SDL_atomic.h:207
size_t
unsigned int size_t
Definition: SDL_config_windows.h:68
SDL_zerop
#define SDL_zerop(x)
Definition: SDL_stdinc.h:419
SDL_AtomicLock
#define SDL_AtomicLock
Definition: SDL_dynapi_overrides.h:64
SDL_mutex
Definition: SDL_sysmutex.c:30
SDL_const_cast
#define SDL_const_cast(type, expression)
Definition: SDL_stdinc.h:139
SDL_TLSData::array
struct SDL_TLSData::@32 array[1]
mutex
static SDL_mutex * mutex
Definition: testlock.c:23
SDLCALL
#define SDLCALL
Definition: SDL_internal.h:49
SDL_SYS_SetupThread
void SDL_SYS_SetupThread(const char *name)
Definition: SDL_systhread.c:42
SDL_realloc
#define SDL_realloc
Definition: SDL_dynapi_overrides.h:376
SDL_InvalidParamError
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
SDL_AtomicIncRef
#define SDL_AtomicIncRef(a)
Increment an atomic variable used as a reference count.
Definition: SDL_atomic.h:252
SDL_error
Definition: SDL_error_c.h:34
SDL_CreateMutex
#define SDL_CreateMutex
Definition: SDL_dynapi_overrides.h:259
SDL_SYS_WaitThread
void SDL_SYS_WaitThread(SDL_Thread *thread)
Definition: SDL_systhread.c:60
SDL_Thread::status
int status
Definition: SDL_thread_c.h:58
SDL_Thread
Definition: SDL_thread_c.h:55
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:191
SDL_SYS_CreateThread
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
Definition: SDL_systhread.c:35
SDL_THREAD_STATE_CLEANED
@ SDL_THREAD_STATE_CLEANED
Definition: SDL_thread_c.h:50
thread_local_storage
static pthread_key_t thread_local_storage
Definition: SDL_systls.c:31
SDL_Thread::threadid
SDL_threadID threadid
Definition: SDL_thread_c.h:56
SDL_SemPost
#define SDL_SemPost
Definition: SDL_dynapi_overrides.h:269
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_SYS_SetTLSData
int SDL_SYS_SetTLSData(SDL_TLSData *data)
Definition: SDL_systls.c:33
SDL_Thread::name
char * name
Definition: SDL_thread_c.h:61
SDL_TLSEntry::thread
SDL_threadID thread
Definition: SDL_thread.c:114
SDL_AtomicUnlock
#define SDL_AtomicUnlock
Definition: SDL_dynapi_overrides.h:65
SDL_CreateThreadWithStackSize
#define SDL_CreateThreadWithStackSize
Definition: SDL_thread.c:312
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_TLSID
unsigned int SDL_TLSID
Definition: SDL_thread.h:52
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:663
thread_args::info
SDL_Thread * info
Definition: SDL_thread.c:266
SDL_SYS_DetachThread
void SDL_SYS_DetachThread(SDL_Thread *thread)
Definition: SDL_systhread.c:66
SDL_TLSCreate
SDL_TLSID SDL_TLSCreate()
Create an identifier that is globally visible to all threads but refers to data that is thread-specif...
Definition: SDL_thread.c:34
SDL_SYS_GetTLSData
SDL_TLSData * SDL_SYS_GetTLSData(void)
Definition: SDL_systls.c:27
SDL_SYS_SetThreadPriority
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
Definition: SDL_systhread.c:54
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_TLSGet
#define SDL_TLSGet
Definition: SDL_dynapi_overrides.h:481
SDL_TLSCreate
#define SDL_TLSCreate
Definition: SDL_dynapi_overrides.h:480
SDL_SpinLock
int SDL_SpinLock
Definition: SDL_atomic.h:89
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
id
GLuint id
Definition: SDL_opengl_glext.h:531
SDL_TLSEntry::storage
SDL_TLSData * storage
Definition: SDL_thread.c:115
SDL_threadID
unsigned long SDL_threadID
Definition: SDL_thread.h:49
SDL_SemWait
#define SDL_SemWait
Definition: SDL_dynapi_overrides.h:266
SDL_TLSData::data
void * data
Definition: SDL_thread_c.h:73
thread_args
Definition: SDL_thread.c:263
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:701
SDL_TLSData::limit
unsigned int limit
Definition: SDL_thread_c.h:71
SDL_MemoryBarrierAcquire
#define SDL_MemoryBarrierAcquire()
Definition: SDL_atomic.h:208
SDL_atomic_t
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
Definition: SDL_atomic.h:216
SDL_WaitThread
void SDL_WaitThread(SDL_Thread *thread, int *status)
Definition: SDL_thread.c:474
thread_args::wait
SDL_sem * wait
Definition: SDL_thread.c:267
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
SDL_DestroySemaphore
#define SDL_DestroySemaphore
Definition: SDL_dynapi_overrides.h:265
SDL_TLSGet
void * SDL_TLSGet(SDL_TLSID id)
Get the value associated with a thread local storage ID for the current thread.
Definition: SDL_thread.c:41
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
SDL_TLSEntry::next
struct SDL_TLSEntry * next
Definition: SDL_thread.c:116
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_AtomicSet
#define SDL_AtomicSet
Definition: SDL_dynapi_overrides.h:67
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_TLSCleanup
static void SDL_TLSCleanup()
Definition: SDL_thread.c:87
SDL_AtomicGet
#define SDL_AtomicGet
Definition: SDL_dynapi_overrides.h:68
SDL_UnlockMutex
#define SDL_UnlockMutex
Definition: SDL_dynapi_overrides.h:262
SDL_strtoll
#define SDL_strtoll
Definition: SDL_dynapi_overrides.h:414
SDL_ThreadID
#define SDL_ThreadID
Definition: SDL_dynapi_overrides.h:475
SDL_generic_TLS_mutex
static SDL_mutex * SDL_generic_TLS_mutex
Definition: SDL_thread.c:119
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_TLSSet
int SDL_TLSSet(SDL_TLSID id, const void *value, void(*destructor)(void *))
Set the value associated with a thread local storage ID for the current thread.
Definition: SDL_thread.c:53
SDL_Thread::state
SDL_atomic_t state
Definition: SDL_thread_c.h:59
SDL_THREAD_STATE_ZOMBIE
@ SDL_THREAD_STATE_ZOMBIE
Definition: SDL_thread_c.h:49
SDL_generic_TLS
static SDL_TLSEntry * SDL_generic_TLS
Definition: SDL_thread.c:120
SDL_TLSEntry
Definition: SDL_thread.c:113