zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_systhread.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 #if SDL_THREAD_WINDOWS
24 
25 /* Win32 thread management routines for SDL */
26 
27 #include "SDL_thread.h"
28 #include "../SDL_thread_c.h"
29 #include "../SDL_systhread.h"
30 #include "SDL_systhread_c.h"
31 
32 #ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD
33 /* We'll use the C library from this DLL */
34 #include <process.h>
35 
36 /* Cygwin gcc-3 ... MingW64 (even with a i386 host) does this like MSVC. */
37 #if (defined(__MINGW32__) && (__GNUC__ < 4))
38 typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned,
39  unsigned (__stdcall *func)(void *), void *arg,
40  unsigned, unsigned *threadID);
41 typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code);
42 
43 #elif defined(__WATCOMC__)
44 /* This is for Watcom targets except OS2 */
45 #if __WATCOMC__ < 1240
46 #define __watcall
47 #endif
48 typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *,
49  unsigned,
50  unsigned
51  (__stdcall *
52  func) (void
53  *),
54  void *arg,
55  unsigned,
56  unsigned
57  *threadID);
58 typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code);
59 
60 #else
61 typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
62  unsigned (__stdcall *
63  func) (void
64  *),
65  void *arg, unsigned,
66  unsigned *threadID);
67 typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
68 #endif
69 #endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */
70 
71 
72 typedef struct ThreadStartParms
73 {
74  void *args;
75  pfnSDL_CurrentEndThread pfnCurrentEndThread;
76 } tThreadStartParms, *pThreadStartParms;
77 
78 static DWORD
79 RunThread(void *data)
80 {
81  pThreadStartParms pThreadParms = (pThreadStartParms) data;
82  pfnSDL_CurrentEndThread pfnEndThread = pThreadParms->pfnCurrentEndThread;
83  void *args = pThreadParms->args;
84  SDL_free(pThreadParms);
85  SDL_RunThread(args);
86  if (pfnEndThread != NULL)
87  pfnEndThread(0);
88  return (0);
89 }
90 
91 static DWORD WINAPI
92 RunThreadViaCreateThread(LPVOID data)
93 {
94  return RunThread(data);
95 }
96 
97 static unsigned __stdcall
98 RunThreadViaBeginThreadEx(void *data)
99 {
100  return (unsigned) RunThread(data);
101 }
102 
103 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
104 int
106  pfnSDL_CurrentBeginThread pfnBeginThread,
107  pfnSDL_CurrentEndThread pfnEndThread)
108 {
109 #elif defined(__CYGWIN__)
110 int
111 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
112 {
113  pfnSDL_CurrentBeginThread pfnBeginThread = NULL;
114  pfnSDL_CurrentEndThread pfnEndThread = NULL;
115 #else
116 int
117 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
118 {
119  pfnSDL_CurrentBeginThread pfnBeginThread = _beginthreadex;
120  pfnSDL_CurrentEndThread pfnEndThread = _endthreadex;
121 #endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
122  pThreadStartParms pThreadParms =
123  (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms));
124  if (!pThreadParms) {
125  return SDL_OutOfMemory();
126  }
127  /* Save the function which we will have to call to clear the RTL of calling app! */
128  pThreadParms->pfnCurrentEndThread = pfnEndThread;
129  /* Also save the real parameters we have to pass to thread function */
130  pThreadParms->args = args;
131 
132  if (pfnBeginThread) {
133  unsigned threadid = 0;
134  thread->handle = (SYS_ThreadHandle)
135  ((size_t) pfnBeginThread(NULL, 0, RunThreadViaBeginThreadEx,
136  pThreadParms, 0, &threadid));
137  } else {
138  DWORD threadid = 0;
139  thread->handle = CreateThread(NULL, 0, RunThreadViaCreateThread,
140  pThreadParms, 0, &threadid);
141  }
142  if (thread->handle == NULL) {
143  return SDL_SetError("Not enough resources to create thread");
144  }
145  return 0;
146 }
147 
148 #ifdef _MSC_VER
149 #pragma warning(disable : 4733)
150 #pragma pack(push,8)
151 typedef struct tagTHREADNAME_INFO
152 {
153  DWORD dwType; /* must be 0x1000 */
154  LPCSTR szName; /* pointer to name (in user addr space) */
155  DWORD dwThreadID; /* thread ID (-1=caller thread) */
156  DWORD dwFlags; /* reserved for future use, must be zero */
157 } THREADNAME_INFO;
158 #pragma pack(pop)
159 
160 static EXCEPTION_DISPOSITION
161 ignore_exception(void *a, void *b, void *c, void *d)
162 {
163  return ExceptionContinueExecution;
164 }
165 #endif
166 
167 void
168 SDL_SYS_SetupThread(const char *name)
169 {
170  if (name != NULL) {
171  #if (defined(_MSC_VER) && defined(_M_IX86))
172  /* This magic tells the debugger to name a thread if it's listening.
173  The inline asm sets up SEH (__try/__except) without C runtime
174  support. See Microsoft Systems Journal, January 1997:
175  http://www.microsoft.com/msj/0197/exception/exception.aspx */
176  INT_PTR handler = (INT_PTR) ignore_exception;
177  THREADNAME_INFO inf;
178 
179  inf.dwType = 0x1000;
180  inf.szName = name;
181  inf.dwThreadID = (DWORD) -1;
182  inf.dwFlags = 0;
183 
184  __asm { /* set up SEH */
185  push handler
186  push fs:[0]
187  mov fs:[0],esp
188  }
189 
190  /* The program itself should ignore this bogus exception. */
191  RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf);
192 
193  __asm { /* tear down SEH. */
194  mov eax,[esp]
195  mov fs:[0], eax
196  add esp, 8
197  }
198  #endif
199  }
200 }
201 
203 SDL_ThreadID(void)
204 {
205  return ((SDL_threadID) GetCurrentThreadId());
206 }
207 
208 int
210 {
211  int value;
212 
213  if (priority == SDL_THREAD_PRIORITY_LOW) {
214  value = THREAD_PRIORITY_LOWEST;
215  } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
216  value = THREAD_PRIORITY_HIGHEST;
217  } else {
218  value = THREAD_PRIORITY_NORMAL;
219  }
220  if (!SetThreadPriority(GetCurrentThread(), value)) {
221  return WIN_SetError("SetThreadPriority()");
222  }
223  return 0;
224 }
225 
226 void
228 {
229  WaitForSingleObject(thread->handle, INFINITE);
230  CloseHandle(thread->handle);
231 }
232 
233 #endif /* SDL_THREAD_WINDOWS */
234 
235 /* vi: set ts=4 sw=4 expandtab: */
DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void)
Definition: SDL_systhread.c:48
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
unsigned long SDL_threadID
Definition: SDL_thread.h:49
#define NULL
Definition: ftobjs.h:61
static void * RunThread(void *data)
Definition: SDL_systhread.c:64
DECLSPEC void SDLCALL SDL_free(void *mem)
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
EGLImageKHR EGLint * name
Definition: eglext.h:284
return Display return Display Bool Bool int d
Definition: SDL_x11sym.h:30
GLenum func
Definition: SDL_opengl.h:5654
thread_id SYS_ThreadHandle
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
Definition: SDL_systhread.c:42
void SDL_SYS_WaitThread(SDL_Thread *thread)
Definition: SDL_systhread.c:60
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
const GLfloat * c
Definition: glew.h:14913
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
Definition: SDL_systhread.c:54
DWORD dwFlags
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
unsigned int uintptr_t
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
static SDL_Thread * thread
Definition: inftrees.h:24
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
int WIN_SetError(const char *prefix)
SYS_ThreadHandle handle
Definition: SDL_thread_c.h:51
EGLSurface EGLint void ** value
Definition: eglext.h:301
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
void SDL_RunThread(void *data)
Definition: SDL_thread.c:263
void SDL_SYS_SetupThread(const char *name)
Definition: SDL_systhread.c:42
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
SDL_ThreadPriority
Definition: SDL_thread.h:59