summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/thread/windows/SDL_systhread.c
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-05-11 22:54:56 +0800
committerchai <chaifix@163.com>2019-05-11 22:54:56 +0800
commit9645be0af1b1d5cb0ad5892d5464e1b23c51b550 (patch)
tree129c716bed8e93312421c3adb2f8e7c4f811602d /source/3rd-party/SDL2/src/thread/windows/SDL_systhread.c
Diffstat (limited to 'source/3rd-party/SDL2/src/thread/windows/SDL_systhread.c')
-rw-r--r--source/3rd-party/SDL2/src/thread/windows/SDL_systhread.c260
1 files changed, 260 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/thread/windows/SDL_systhread.c b/source/3rd-party/SDL2/src/thread/windows/SDL_systhread.c
new file mode 100644
index 0000000..251510d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/windows/SDL_systhread.c
@@ -0,0 +1,260 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_THREAD_WINDOWS
+
+/* Win32 thread management routines for SDL */
+
+#include "SDL_hints.h"
+#include "SDL_thread.h"
+#include "../SDL_thread_c.h"
+#include "../SDL_systhread.h"
+#include "SDL_systhread_c.h"
+
+#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD
+/* We'll use the C library from this DLL */
+#include <process.h>
+
+#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
+#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
+#endif
+
+/* Cygwin gcc-3 ... MingW64 (even with a i386 host) does this like MSVC. */
+#if (defined(__MINGW32__) && (__GNUC__ < 4))
+typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned,
+ unsigned (__stdcall *func)(void *), void *arg,
+ unsigned, unsigned *threadID);
+typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code);
+
+#elif defined(__WATCOMC__)
+/* This is for Watcom targets except OS2 */
+#if __WATCOMC__ < 1240
+#define __watcall
+#endif
+typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *,
+ unsigned,
+ unsigned
+ (__stdcall *
+ func) (void
+ *),
+ void *arg,
+ unsigned,
+ unsigned
+ *threadID);
+typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code);
+
+#else
+typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
+ unsigned (__stdcall *
+ func) (void
+ *),
+ void *arg, unsigned,
+ unsigned *threadID);
+typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
+#endif
+#endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */
+
+
+typedef struct ThreadStartParms
+{
+ void *args;
+ pfnSDL_CurrentEndThread pfnCurrentEndThread;
+} tThreadStartParms, *pThreadStartParms;
+
+static DWORD
+RunThread(void *data)
+{
+ pThreadStartParms pThreadParms = (pThreadStartParms) data;
+ pfnSDL_CurrentEndThread pfnEndThread = pThreadParms->pfnCurrentEndThread;
+ void *args = pThreadParms->args;
+ SDL_free(pThreadParms);
+ SDL_RunThread(args);
+ if (pfnEndThread != NULL)
+ pfnEndThread(0);
+ return (0);
+}
+
+static DWORD WINAPI
+RunThreadViaCreateThread(LPVOID data)
+{
+ return RunThread(data);
+}
+
+static unsigned __stdcall
+RunThreadViaBeginThreadEx(void *data)
+{
+ return (unsigned) RunThread(data);
+}
+
+#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
+int
+SDL_SYS_CreateThread(SDL_Thread * thread, void *args,
+ pfnSDL_CurrentBeginThread pfnBeginThread,
+ pfnSDL_CurrentEndThread pfnEndThread)
+{
+#elif defined(__CYGWIN__) || defined(__WINRT__)
+int
+SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
+{
+ pfnSDL_CurrentBeginThread pfnBeginThread = NULL;
+ pfnSDL_CurrentEndThread pfnEndThread = NULL;
+#else
+int
+SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
+{
+ pfnSDL_CurrentBeginThread pfnBeginThread = (pfnSDL_CurrentBeginThread)_beginthreadex;
+ pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread)_endthreadex;
+#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
+ pThreadStartParms pThreadParms =
+ (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms));
+ const DWORD flags = thread->stacksize ? STACK_SIZE_PARAM_IS_A_RESERVATION : 0;
+ if (!pThreadParms) {
+ return SDL_OutOfMemory();
+ }
+ /* Save the function which we will have to call to clear the RTL of calling app! */
+ pThreadParms->pfnCurrentEndThread = pfnEndThread;
+ /* Also save the real parameters we have to pass to thread function */
+ pThreadParms->args = args;
+
+ /* thread->stacksize == 0 means "system default", same as win32 expects */
+ if (pfnBeginThread) {
+ unsigned threadid = 0;
+ thread->handle = (SYS_ThreadHandle)
+ ((size_t) pfnBeginThread(NULL, (unsigned int) thread->stacksize,
+ RunThreadViaBeginThreadEx,
+ pThreadParms, flags, &threadid));
+ } else {
+ DWORD threadid = 0;
+ thread->handle = CreateThread(NULL, thread->stacksize,
+ RunThreadViaCreateThread,
+ pThreadParms, flags, &threadid);
+ }
+ if (thread->handle == NULL) {
+ return SDL_SetError("Not enough resources to create thread");
+ }
+ return 0;
+}
+
+#pragma pack(push,8)
+typedef struct tagTHREADNAME_INFO
+{
+ DWORD dwType; /* must be 0x1000 */
+ LPCSTR szName; /* pointer to name (in user addr space) */
+ DWORD dwThreadID; /* thread ID (-1=caller thread) */
+ DWORD dwFlags; /* reserved for future use, must be zero */
+} THREADNAME_INFO;
+#pragma pack(pop)
+
+
+typedef HRESULT (WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR);
+
+void
+SDL_SYS_SetupThread(const char *name)
+{
+ if (name != NULL) {
+ #ifndef __WINRT__ /* !!! FIXME: There's no LoadLibrary() in WinRT; don't know if SetThreadDescription is available there at all at the moment. */
+ static pfnSetThreadDescription pSetThreadDescription = NULL;
+ static HMODULE kernel32 = 0;
+
+ if (!kernel32) {
+ kernel32 = LoadLibraryW(L"kernel32.dll");
+ if (kernel32) {
+ pSetThreadDescription = (pfnSetThreadDescription) GetProcAddress(kernel32, "SetThreadDescription");
+ }
+ }
+
+ if (pSetThreadDescription != NULL) {
+ WCHAR *strw = WIN_UTF8ToString(name);
+ if (strw) {
+ pSetThreadDescription(GetCurrentThread(), strw);
+ SDL_free(strw);
+ }
+ }
+ #endif
+
+ /* Presumably some version of Visual Studio will understand SetThreadDescription(),
+ but we still need to deal with older OSes and debuggers. Set it with the arcane
+ exception magic, too. */
+
+ if (IsDebuggerPresent()) {
+ THREADNAME_INFO inf;
+
+ /* C# and friends will try to catch this Exception, let's avoid it. */
+ if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, SDL_TRUE)) {
+ return;
+ }
+
+ /* This magic tells the debugger to name a thread if it's listening. */
+ SDL_zero(inf);
+ inf.dwType = 0x1000;
+ inf.szName = name;
+ inf.dwThreadID = (DWORD) -1;
+ inf.dwFlags = 0;
+
+ /* The debugger catches this, renames the thread, continues on. */
+ RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf);
+ }
+ }
+}
+
+SDL_threadID
+SDL_ThreadID(void)
+{
+ return ((SDL_threadID) GetCurrentThreadId());
+}
+
+int
+SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
+{
+ int value;
+
+ if (priority == SDL_THREAD_PRIORITY_LOW) {
+ value = THREAD_PRIORITY_LOWEST;
+ } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
+ value = THREAD_PRIORITY_HIGHEST;
+ } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
+ value = THREAD_PRIORITY_TIME_CRITICAL;
+ } else {
+ value = THREAD_PRIORITY_NORMAL;
+ }
+ if (!SetThreadPriority(GetCurrentThread(), value)) {
+ return WIN_SetError("SetThreadPriority()");
+ }
+ return 0;
+}
+
+void
+SDL_SYS_WaitThread(SDL_Thread * thread)
+{
+ WaitForSingleObjectEx(thread->handle, INFINITE, FALSE);
+ CloseHandle(thread->handle);
+}
+
+void
+SDL_SYS_DetachThread(SDL_Thread * thread)
+{
+ CloseHandle(thread->handle);
+}
+
+#endif /* SDL_THREAD_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */