sdlthread.inc 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // based on "sdl_thread.h"
  2. {* The SDL thread structure, defined in SDL_thread.c *}
  3. { TODO : Update this file }
  4. type
  5. {* The SDL thread ID *}
  6. PPSDL_threadID = ^PSDL_threadID;
  7. PSDL_threadID = ^TSDL_threadID;
  8. TSDL_threadID = culong;
  9. {* Thread local storage ID, 0 is the invalid ID *}
  10. PPSDL_TLSID = ^PSDL_TLSID;
  11. PSDL_TLSID = ^TSDL_TLSID;
  12. TSDL_TLSID = cuint;
  13. {**
  14. * The SDL thread priority.
  15. *
  16. * SDL will make system changes as necessary in order to apply the thread priority.
  17. * Code which attempts to control thread state related to priority should be aware
  18. * that calling SDL_SetThreadPriority may alter such state.
  19. * SDL_HINT_THREAD_PRIORITY_POLICY can be used to control aspects of this behavior.
  20. *
  21. * \note On many systems you require special privileges to set high or time critical priority.
  22. *}
  23. PPSDL_ThreadPriority = ^PSDL_ThreadPriority;
  24. PSDL_ThreadPriority = ^TSDL_ThreadPriority;
  25. TSDL_ThreadPriority = (SDL_THREAD_PRIORITY_LOW,
  26. SDL_THREAD_PRIORITY_NORMAL,
  27. SDL_THREAD_PRIORITY_HIGH,
  28. SDL_THREAD_PRIORITY_TIME_CRITICAL);
  29. {* The function passed to SDL_CreateThread()
  30. It is passed a void* user context parameter and returns an int.
  31. *}
  32. PPSDL_ThreadFunction = ^PSDL_ThreadFunction;
  33. PSDL_ThreadFunction = ^TSDL_ThreadFunction;
  34. TSDL_ThreadFunction = function(data: Pointer): cint; cdecl;
  35. PPSDL_Thread = ^PSDL_Thread;
  36. PSDL_Thread = ^TSDL_Thread;
  37. TSDL_Thread = record
  38. threadid: TSDL_ThreadID;
  39. handle: THandle;
  40. status: cint32;
  41. errbuf: TSDL_Error;
  42. name: PAnsiChar;
  43. data: Pointer;
  44. end;
  45. {$IFDEF WINDOWS}
  46. {**
  47. * SDL_thread.h
  48. *
  49. * We compile SDL into a DLL. This means, that it's the DLL which
  50. * creates a new thread for the calling process with the SDL_CreateThread()
  51. * API. There is a problem with this, that only the RTL of the SDL.DLL will
  52. * be initialized for those threads, and not the RTL of the calling
  53. * application!
  54. *
  55. * To solve this, we make a little hack here.
  56. *
  57. * We'll always use the caller's _beginthread() and _endthread() APIs to
  58. * start a new thread. This way, if it's the SDL.DLL which uses this API,
  59. * then the RTL of SDL.DLL will be used to create the new thread, and if it's
  60. * the application, then the RTL of the application will be used.
  61. *
  62. * So, in short:
  63. * Always use the _beginthread() and _endthread() of the calling runtime
  64. * library!
  65. *}
  66. {$DEFINE SDL_PASSED_BEGINTHREAD_ENDTHREAD}
  67. type
  68. {$IFNDEF DELPHI16UP}
  69. TThreadID = Cardinal;
  70. {$ENDIF}
  71. TpfnSDL_CurrentBeginThread = function(SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: TThreadID): cint;
  72. TpfnSDL_CurrentEndThread = procedure(ExitCode: cint);
  73. {**
  74. * Create a thread.
  75. *}
  76. function SDL_CreateThread(fn: TSDL_ThreadFunction; name: PAnsiChar;
  77. data: Pointer; pfnBeginThread: TpfnSDL_CurrentBeginThread; pfnEndThread: TpfnSDL_CurrentEndThread): PSDL_Thread; cdecl; overload;
  78. external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateThread' {$ENDIF} {$ENDIF};
  79. {**
  80. * Create a thread.
  81. *}
  82. function SDL_CreateThread(fn: TSDL_ThreadFunction; name: PAnsiChar;
  83. data: Pointer): PSDL_Thread; overload;
  84. {$ELSE}
  85. {**
  86. * Create a thread.
  87. *
  88. * Thread naming is a little complicated: Most systems have very small
  89. * limits for the string length (BeOS has 32 bytes, Linux currently has 16,
  90. * Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll
  91. * have to see what happens with your system's debugger. The name should be
  92. * UTF-8 (but using the naming limits of C identifiers is a better bet).
  93. * There are no requirements for thread naming conventions, so long as the
  94. * string is null-terminated UTF-8, but these guidelines are helpful in
  95. * choosing a name:
  96. *
  97. * http://stackoverflow.com/questions/149932/naming-conventions-for-threads
  98. *
  99. * If a system imposes requirements, SDL will try to munge the string for
  100. * it (truncate, etc), but the original string contents will be available
  101. * from SDL_GetThreadName().
  102. *}
  103. function SDL_CreateThread(fn: TSDL_ThreadFunction; name: PAnsiChar;
  104. data: Pointer): PSDL_Thread; cdecl;
  105. external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateThread' {$ENDIF} {$ENDIF};
  106. {$ENDIF}
  107. {**
  108. * Get the thread name, as it was specified in SDL_CreateThread().
  109. * This function returns a pointer to a UTF-8 string that names the
  110. * specified thread, or NULL if it doesn't have a name. This is internal
  111. * memory, not to be free()'d by the caller, and remains valid until the
  112. * specified thread is cleaned up by SDL_WaitThread().
  113. *}
  114. function SDL_GetThreadName(thread: PSDL_Thread): PAnsiChar cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetThreadName' {$ENDIF}{$ENDIF};
  115. {**
  116. * Get the thread identifier for the current thread.
  117. *}
  118. function SDL_ThreadID: TSDL_ThreadID cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ThreadID' {$ENDIF}{$ENDIF};
  119. {**
  120. * Get the thread identifier for the specified thread.
  121. *
  122. * Equivalent to SDL_ThreadID() if the specified thread is NULL.
  123. *}
  124. function SDL_GetThreadID(thread: PSDL_Thread): TSDL_ThreadID cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetThreadID' {$ENDIF}{$ENDIF};
  125. {**
  126. * Set the priority for the current thread
  127. *}
  128. function SDL_SetThreadPriority(priority: TSDL_ThreadPriority): cint32 cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetThreadPriority' {$ENDIF}{$ENDIF};
  129. {**
  130. * Wait for a thread to finish.
  131. *
  132. * The return code for the thread function is placed in the area
  133. * pointed to by status, if status is not NULL.
  134. *}
  135. procedure SDL_WaitThread(thread: PSDL_Thread; status: pcint) cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WaitThread' {$ENDIF}{$ENDIF};
  136. {**
  137. * A thread may be "detached" to signify that it should not remain until
  138. * another thread has called SDL_WaitThread() on it. Detaching a thread
  139. * is useful for long-running threads that nothing needs to synchronize
  140. * with or further manage. When a detached thread is done, it simply
  141. * goes away.
  142. *
  143. * There is no way to recover the return code of a detached thread. If you
  144. * need this, don't detach the thread and instead use SDL_WaitThread().
  145. *
  146. * Once a thread is detached, you should usually assume the SDL_Thread isn't
  147. * safe to reference again, as it will become invalid immediately upon
  148. * the detached thread's exit, instead of remaining until someone has called
  149. * SDL_WaitThread() to finally clean it up. As such, don't detach the same
  150. * thread more than once.
  151. *
  152. * If a thread has already exited when passed to SDL_DetachThread(), it will
  153. * stop waiting for a call to SDL_WaitThread() and clean up immediately.
  154. * It is not safe to detach a thread that might be used with SDL_WaitThread().
  155. *
  156. * You may not call SDL_WaitThread() on a thread that has been detached.
  157. * Use either that function or this one, but not both, or behavior is
  158. * undefined.
  159. *
  160. * It is safe to pass NIL to this function; it is a no-op.
  161. *}
  162. procedure SDL_DetachThread(thread:TSDL_Thread); cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DetachThread' {$ENDIF}{$ENDIF};
  163. {**
  164. * Create an identifier that is globally visible to all threads but refers to data that is thread-specific.
  165. *
  166. * The newly created thread local storage identifier, or 0 on error
  167. *
  168. * var tls_lock: TSDL_SpinLock;
  169. * thread_local_storage: TSDL_TLSID;
  170. *
  171. * procedure SetMyThreadData(value: Pointer)
  172. *
  173. * if not (thread_local_storage) then
  174. * begin
  175. * SDL_AtomicLock(@tls_lock);
  176. * if (!thread_local_storage)
  177. * thread_local_storage = SDL_TLSCreate();
  178. *
  179. * SDL_AtomicUnLock(@tls_lock);
  180. *
  181. * SDL_TLSSet(thread_local_storage, value);
  182. * end;
  183. *
  184. * function GetMyThreadData(): Pointer;
  185. * begin
  186. * Result := SDL_TLSGet(thread_local_storage);
  187. * end;
  188. *
  189. * SDL_TLSGet()
  190. * SDL_TLSSet()
  191. *}
  192. function SDL_TLSCreate: TSDL_TLSID cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TLSCreate' {$ENDIF} {$ENDIF};
  193. {**
  194. * Get the value associated with a thread local storage ID for the current thread.
  195. *
  196. * id The thread local storage ID
  197. *
  198. * The value associated with the ID for the current thread, or NULL if no value has been set.
  199. *
  200. * SDL_TLSCreate()
  201. * SDL_TLSSet()
  202. *}
  203. function SDL_TLSGet(id: TSDL_TLSID): Pointer cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TLSGet' {$ENDIF} {$ENDIF};
  204. {**
  205. * Set the value associated with a thread local storage ID for the current thread.
  206. *
  207. * id The thread local storage ID
  208. * value The value to associate with the ID for the current thread
  209. * destructor_ A function called when the thread exits, to free the value.
  210. *
  211. * 0 on success, -1 on error
  212. *
  213. * SDL_TLSCreate()
  214. * SDL_TLSGet()
  215. *}
  216. function SDL_TLSSet(id: TSDL_TLSID; value: Pointer; destructor_: Pointer): cint32 cdecl; external {$IFDEF DYNAMIC_LINK}SDL_LibName{$ENDIF} {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TLSSet' {$ENDIF} {$ENDIF};