early-access version 1617

This commit is contained in:
pineappleEA
2021-04-20 21:40:33 +02:00
parent 242b6f6b49
commit f46563104f
510 changed files with 141726 additions and 62846 deletions

View File

@@ -33,11 +33,11 @@
on success.
*/
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
extern int SDL_SYS_CreateThread(SDL_Thread * thread, void *args,
extern int SDL_SYS_CreateThread(SDL_Thread * thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread);
#else
extern int SDL_SYS_CreateThread(SDL_Thread * thread, void *args);
extern int SDL_SYS_CreateThread(SDL_Thread * thread);
#endif
/* This function does any necessary setup in the child thread */

View File

@@ -22,7 +22,6 @@
/* System independent thread management routines for SDL */
#include "SDL_assert.h"
#include "SDL_thread.h"
#include "SDL_thread_c.h"
#include "SDL_systhread.h"
@@ -258,22 +257,12 @@ SDL_GetErrBuf(void)
}
/* Arguments and callback to setup and run the user thread function */
typedef struct
{
int (SDLCALL * func) (void *);
void *data;
SDL_Thread *info;
SDL_sem *wait;
} thread_args;
void
SDL_RunThread(void *data)
SDL_RunThread(SDL_Thread *thread)
{
thread_args *args = (thread_args *) data;
int (SDLCALL * userfunc) (void *) = args->func;
void *userdata = args->data;
SDL_Thread *thread = args->info;
void *userdata = thread->userdata;
int (SDLCALL * userfunc) (void *) = thread->userfunc;
int *statusloc = &thread->status;
/* Perform any system-dependent setup - this function may not fail */
@@ -282,9 +271,6 @@ SDL_RunThread(void *data)
/* Get the thread id */
thread->threadid = SDL_ThreadID();
/* Wake up the parent thread */
SDL_SemPost(args->wait);
/* Run the function */
*statusloc = userfunc(userdata);
@@ -325,16 +311,14 @@ SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
#endif
{
SDL_Thread *thread;
thread_args *args;
int ret;
/* Allocate memory for the thread info structure */
thread = (SDL_Thread *) SDL_malloc(sizeof(*thread));
thread = (SDL_Thread *) SDL_calloc(1, sizeof(*thread));
if (thread == NULL) {
SDL_OutOfMemory();
return (NULL);
return NULL;
}
SDL_zerop(thread);
thread->status = -1;
SDL_AtomicSet(&thread->state, SDL_THREAD_STATE_ALIVE);
@@ -344,57 +328,29 @@ SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
if (thread->name == NULL) {
SDL_OutOfMemory();
SDL_free(thread);
return (NULL);
return NULL;
}
}
/* Set up the arguments for the thread */
args = (thread_args *) SDL_malloc(sizeof(*args));
if (args == NULL) {
SDL_OutOfMemory();
if (thread->name) {
SDL_free(thread->name);
}
SDL_free(thread);
return (NULL);
}
args->func = fn;
args->data = data;
args->info = thread;
args->wait = SDL_CreateSemaphore(0);
if (args->wait == NULL) {
if (thread->name) {
SDL_free(thread->name);
}
SDL_free(thread);
SDL_free(args);
return (NULL);
}
thread->userfunc = fn;
thread->userdata = data;
thread->stacksize = stacksize;
/* Create the thread and go! */
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread);
ret = SDL_SYS_CreateThread(thread, pfnBeginThread, pfnEndThread);
#else
ret = SDL_SYS_CreateThread(thread, args);
ret = SDL_SYS_CreateThread(thread);
#endif
if (ret >= 0) {
/* Wait for the thread function to use arguments */
SDL_SemWait(args->wait);
} else {
if (ret < 0) {
/* Oops, failed. Gotta free everything */
if (thread->name) {
SDL_free(thread->name);
}
SDL_free(thread->name);
SDL_free(thread);
thread = NULL;
}
SDL_DestroySemaphore(args->wait);
SDL_free(args);
/* Everything is running now */
return (thread);
return thread;
}
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD

View File

@@ -36,6 +36,8 @@
#include "psp/SDL_systhread_c.h"
#elif SDL_THREAD_STDCPP
#include "stdcpp/SDL_systhread_c.h"
#elif SDL_THREAD_OS2
#include "os2/SDL_systhread_c.h"
#else
#error Need thread implementation for this platform
#include "generic/SDL_systhread_c.h"
@@ -60,11 +62,14 @@ struct SDL_Thread
SDL_error errbuf;
char *name;
size_t stacksize; /* 0 for default, >0 for user-specified stack size. */
int (SDLCALL * userfunc) (void *);
void *userdata;
void *data;
void *endfunc; /* only used on some platforms. */
};
/* This is the function called to run a thread */
extern void SDL_RunThread(void *data);
extern void SDL_RunThread(SDL_Thread *thread);
/* This is the system-independent thread local storage structure */
typedef struct {

View File

@@ -27,12 +27,12 @@
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
int
SDL_SYS_CreateThread(SDL_Thread * thread, void *args,
SDL_SYS_CreateThread(SDL_Thread * thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
#else
int
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
SDL_SYS_CreateThread(SDL_Thread * thread)
#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
{
return SDL_SetError("Threads are not supported on this platform");

129
externals/SDL/src/thread/os2/SDL_sysmutex.c vendored Executable file
View File

@@ -0,0 +1,129 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 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_OS2
/* An implementation of mutexes for OS/2 */
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
#include "../../core/os2/SDL_os2.h"
#define INCL_DOSSEMAPHORES
#define INCL_DOSERRORS
#include <os2.h>
struct SDL_mutex {
HMTX _handle;
};
/* Create a mutex */
SDL_mutex *
SDL_CreateMutex(void)
{
ULONG ulRC;
HMTX hMtx;
ulRC = DosCreateMutexSem(NULL, &hMtx, 0, FALSE);
if (ulRC != NO_ERROR) {
debug_os2("DosCreateMutexSem(), rc = %u", ulRC);
return NULL;
}
return (SDL_mutex *)hMtx;
}
/* Free the mutex */
void
SDL_DestroyMutex(SDL_mutex * mutex)
{
ULONG ulRC;
HMTX hMtx = (HMTX)mutex;
ulRC = DosCloseMutexSem(hMtx);
if (ulRC != NO_ERROR) {
debug_os2("DosCloseMutexSem(), rc = %u", ulRC);
}
}
/* Lock the mutex */
int
SDL_LockMutex(SDL_mutex * mutex)
{
ULONG ulRC;
HMTX hMtx = (HMTX)mutex;
if (hMtx == NULLHANDLE)
return SDL_SetError("Passed a NULL mutex");
ulRC = DosRequestMutexSem(hMtx, SEM_INDEFINITE_WAIT);
if (ulRC != NO_ERROR) {
debug_os2("DosRequestMutexSem(), rc = %u", ulRC);
return -1;
}
return 0;
}
/* try Lock the mutex */
int
SDL_TryLockMutex(SDL_mutex * mutex)
{
ULONG ulRC;
HMTX hMtx = (HMTX)mutex;
if (hMtx == NULLHANDLE)
return SDL_SetError("Passed a NULL mutex");
ulRC = DosRequestMutexSem(hMtx, SEM_IMMEDIATE_RETURN);
if (ulRC == ERROR_TIMEOUT)
return SDL_MUTEX_TIMEDOUT;
if (ulRC != NO_ERROR) {
debug_os2("DosRequestMutexSem(), rc = %u", ulRC);
return -1;
}
return 0;
}
/* Unlock the mutex */
int
SDL_UnlockMutex(SDL_mutex * mutex)
{
ULONG ulRC;
HMTX hMtx = (HMTX)mutex;
if (hMtx == NULLHANDLE)
return SDL_SetError("Passed a NULL mutex");
ulRC = DosReleaseMutexSem(hMtx);
if (ulRC != NO_ERROR)
return SDL_SetError("DosReleaseMutexSem(), rc = %u", ulRC);
return 0;
}
#endif /* SDL_THREAD_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

190
externals/SDL/src/thread/os2/SDL_syssem.c vendored Executable file
View File

@@ -0,0 +1,190 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 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_OS2
/* An implementation of semaphores for OS/2 */
#include "SDL_thread.h"
#include "../../core/os2/SDL_os2.h"
#define INCL_DOSSEMAPHORES
#define INCL_DOSERRORS
#define INCL_DOSMISC
#include <os2.h>
struct SDL_semaphore {
HEV hEv;
HMTX hMtx;
ULONG cPost;
};
SDL_sem *
SDL_CreateSemaphore(Uint32 initial_value)
{
ULONG ulRC;
SDL_sem *pSDLSem = SDL_malloc(sizeof(SDL_sem));
if (pSDLSem == NULL) {
SDL_OutOfMemory();
return NULL;
}
ulRC = DosCreateEventSem(NULL, &pSDLSem->hEv, DCE_AUTORESET, FALSE);
if (ulRC != NO_ERROR) {
debug_os2("DosCreateEventSem(), rc = %u", ulRC);
SDL_free(pSDLSem);
return NULL;
}
ulRC = DosCreateMutexSem(NULL, &pSDLSem->hMtx, 0, FALSE);
if (ulRC != NO_ERROR) {
debug_os2("DosCreateMutexSem(), rc = %u", ulRC);
DosCloseEventSem(pSDLSem->hEv);
SDL_free(pSDLSem);
return NULL;
}
pSDLSem->cPost = initial_value;
return pSDLSem;
}
void
SDL_DestroySemaphore(SDL_sem * sem)
{
if (!sem) return;
DosCloseMutexSem(sem->hMtx);
DosCloseEventSem(sem->hEv);
SDL_free(sem);
}
int
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
{
ULONG ulRC;
ULONG ulStartTime, ulCurTime;
ULONG ulTimeout;
ULONG cPost;
if (sem == NULL)
return SDL_SetError("Passed a NULL sem");
if (timeout != SEM_INDEFINITE_WAIT)
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStartTime, sizeof(ULONG));
while (TRUE) {
ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
if (ulRC != NO_ERROR)
return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
cPost = sem->cPost;
if (sem->cPost != 0)
sem->cPost--;
DosReleaseMutexSem(sem->hMtx);
if (cPost != 0)
break;
if (timeout == SEM_INDEFINITE_WAIT)
ulTimeout = SEM_INDEFINITE_WAIT;
else {
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulCurTime, sizeof(ULONG));
ulTimeout = ulCurTime - ulStartTime;
if (timeout < ulTimeout)
return SDL_MUTEX_TIMEDOUT;
ulTimeout = timeout - ulTimeout;
}
ulRC = DosWaitEventSem(sem->hEv, ulTimeout);
if (ulRC == ERROR_TIMEOUT)
return SDL_MUTEX_TIMEDOUT;
if (ulRC != NO_ERROR)
return SDL_SetError("DosWaitEventSem() failed, rc = %u", ulRC);
}
return 0;
}
int
SDL_SemTryWait(SDL_sem * sem)
{
return SDL_SemWaitTimeout(sem, 0);
}
int
SDL_SemWait(SDL_sem * sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32
SDL_SemValue(SDL_sem * sem)
{
ULONG ulRC;
if (sem == NULL) {
SDL_SetError("Passed a NULL sem");
return 0;
}
ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
if (ulRC != NO_ERROR)
return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
ulRC = sem->cPost;
DosReleaseMutexSem(sem->hMtx);
return ulRC;
}
int
SDL_SemPost(SDL_sem * sem)
{
ULONG ulRC;
if (sem == NULL)
return SDL_SetError("Passed a NULL sem");
ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
if (ulRC != NO_ERROR)
return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
sem->cPost++;
ulRC = DosPostEventSem(sem->hEv);
if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
debug_os2("DosPostEventSem() failed, rc = %u", ulRC);
}
DosReleaseMutexSem(sem->hMtx);
return 0;
}
#endif /* SDL_THREAD_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

133
externals/SDL/src/thread/os2/SDL_systhread.c vendored Executable file
View File

@@ -0,0 +1,133 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 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_OS2
/* Thread management routines for SDL */
#include "SDL_thread.h"
#include "../SDL_systhread.h"
#include "../SDL_thread_c.h"
#include "../SDL_systhread.h"
#include "SDL_systls_c.h"
#include "../../core/os2/SDL_os2.h"
#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD
#error This source only adjusted for SDL_PASSED_BEGINTHREAD_ENDTHREAD
#endif
#define INCL_DOSPROCESS
#define INCL_DOSERRORS
#include <os2.h>
#include <process.h>
static void RunThread(void *data)
{
SDL_Thread *thread = (SDL_Thread *) data;
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc;
if (ppSDLTLSData != NULL)
*ppSDLTLSData = NULL;
SDL_RunThread(thread);
if (pfnEndThread != NULL)
pfnEndThread();
}
int
SDL_SYS_CreateThread(SDL_Thread * thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
{
if (thread->stacksize == 0)
thread->stacksize = 65536;
if (pfnBeginThread) {
/* Save the function which we will have to call to clear the RTL of calling app! */
thread->endfunc = pfnEndThread;
/* Start the thread using the runtime library of calling app! */
thread->handle = (SYS_ThreadHandle)
pfnBeginThread(RunThread, NULL, thread->stacksize, thread);
} else {
thread->endfunc = _endthread;
thread->handle = (SYS_ThreadHandle)
_beginthread(RunThread, NULL, thread->stacksize, thread);
}
if (thread->handle == -1)
return SDL_SetError("Not enough resources to create thread");
return 0;
}
void
SDL_SYS_SetupThread(const char *name)
{
/* nothing. */
}
SDL_threadID
SDL_ThreadID(void)
{
PTIB tib;
PPIB pib;
DosGetInfoBlocks(&tib, &pib);
return tib->tib_ptib2->tib2_ultid;
}
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
ULONG ulRC;
ulRC = DosSetPriority(PRTYS_THREAD,
(priority < SDL_THREAD_PRIORITY_NORMAL)? PRTYC_IDLETIME :
(priority > SDL_THREAD_PRIORITY_NORMAL)? PRTYC_TIMECRITICAL :
PRTYC_REGULAR,
0, 0);
if (ulRC != NO_ERROR)
return SDL_SetError("DosSetPriority() failed, rc = %u", ulRC);
return 0;
}
void
SDL_SYS_WaitThread(SDL_Thread * thread)
{
ULONG ulRC = DosWaitThread((PTID)&thread->handle, DCWW_WAIT);
if (ulRC != NO_ERROR) {
debug_os2("DosWaitThread() failed, rc = %u", ulRC);
}
}
void
SDL_SYS_DetachThread(SDL_Thread * thread)
{
/* nothing. */
}
#endif /* SDL_THREAD_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,25 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 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"
typedef int SYS_ThreadHandle;
/* vi: set ts=4 sw=4 expandtab: */

89
externals/SDL/src/thread/os2/SDL_systls.c vendored Executable file
View File

@@ -0,0 +1,89 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 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_OS2
#include "../../core/os2/SDL_os2.h"
#include "SDL_thread.h"
#include "../SDL_thread_c.h"
#define INCL_DOSPROCESS
#define INCL_DOSERRORS
#include <os2.h>
SDL_TLSData **ppSDLTLSData = NULL;
static ULONG cTLSAlloc = 0;
/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */
void SDL_OS2TLSAlloc(void)
{
ULONG ulRC;
if (cTLSAlloc == 0 || ppSDLTLSData == NULL) {
/* First call - allocate the thread local memory (1 DWORD) */
ulRC = DosAllocThreadLocalMemory(1, (PULONG *)&ppSDLTLSData);
if (ulRC != NO_ERROR) {
debug_os2("DosAllocThreadLocalMemory() failed, rc = %u", ulRC);
}
}
cTLSAlloc++;
}
/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */
void SDL_OS2TLSFree(void)
{
ULONG ulRC;
if (cTLSAlloc != 0)
cTLSAlloc--;
if (cTLSAlloc == 0 && ppSDLTLSData != NULL) {
/* Last call - free the thread local memory */
ulRC = DosFreeThreadLocalMemory((PULONG)ppSDLTLSData);
if (ulRC != NO_ERROR) {
debug_os2("DosFreeThreadLocalMemory() failed, rc = %u", ulRC);
} else {
ppSDLTLSData = NULL;
}
}
}
SDL_TLSData *SDL_SYS_GetTLSData(void)
{
return (ppSDLTLSData == NULL)? NULL : *ppSDLTLSData;
}
int SDL_SYS_SetTLSData(SDL_TLSData *data)
{
if (!ppSDLTLSData)
return -1;
*ppSDLTLSData = data;
return 0;
}
#endif /* SDL_THREAD_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

38
externals/SDL/src/thread/os2/SDL_systls_c.h vendored Executable file
View File

@@ -0,0 +1,38 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 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_OS2
#include "../SDL_thread_c.h"
extern SDL_TLSData **ppSDLTLSData;
/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */
void SDL_OS2TLSAlloc(void);
/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */
void SDL_OS2TLSFree(void);
#endif /* SDL_THREAD_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -37,11 +37,11 @@
static int ThreadEntry(SceSize args, void *argp)
{
SDL_RunThread(*(void **) argp);
SDL_RunThread(*(SDL_Thread **) argp);
return 0;
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
int SDL_SYS_CreateThread(SDL_Thread *thread)
{
SceKernelThreadInfo status;
int priority = 32;
@@ -59,7 +59,7 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
return SDL_SetError("sceKernelCreateThread() failed");
}
sceKernelStartThread(thread->handle, 4, &args);
sceKernelStartThread(thread->handle, 4, &thread);
return 0;
}

View File

@@ -18,9 +18,10 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "SDL_system.h"
#include "SDL_hints.h"
#include <pthread.h>
@@ -47,7 +48,6 @@
#endif
#endif
#include "SDL_log.h"
#include "SDL_platform.h"
#include "SDL_thread.h"
#include "../SDL_thread_c.h"
@@ -60,7 +60,6 @@
#include <kernel/OS.h>
#endif
#include "SDL_assert.h"
#ifndef __NACL__
/* List of signals to mask in the subthreads */
@@ -76,7 +75,7 @@ RunThread(void *data)
#ifdef __ANDROID__
Android_JNI_SetupThread();
#endif
SDL_RunThread(data);
SDL_RunThread((SDL_Thread *) data);
return NULL;
}
@@ -88,7 +87,7 @@ static SDL_bool checked_setname = SDL_FALSE;
static int (*ppthread_setname_np)(pthread_t, const char*) = NULL;
#endif
int
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
SDL_SYS_CreateThread(SDL_Thread * thread)
{
pthread_attr_t type;
@@ -117,7 +116,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
}
/* Create the thread and go! */
if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
if (pthread_create(&thread->handle, &type, RunThread, thread) != 0) {
return SDL_SetError("Not enough resources to create thread");
}
@@ -185,34 +184,84 @@ SDL_ThreadID(void)
return ((SDL_threadID) pthread_self());
}
#if __LINUX__
/**
\brief Sets the SDL priority (not nice level) for a thread, using setpriority() if appropriate, and RealtimeKit if available.
Differs from SDL_LinuxSetThreadPriority in also taking the desired scheduler policy,
such as SCHED_OTHER or SCHED_RR.
\return 0 on success, or -1 on error.
*/
extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy);
#endif
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
#if __NACL__ || __RISCOS__
/* FIXME: Setting thread priority does not seem to be supported in NACL */
return 0;
#elif __LINUX__
int value;
pid_t thread = syscall(SYS_gettid);
if (priority == SDL_THREAD_PRIORITY_LOW) {
value = 19;
} else if (priority == SDL_THREAD_PRIORITY_HIGH) {
value = -10;
} else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
value = -20;
} else {
value = 0;
}
return SDL_LinuxSetThreadPriority(thread, value);
#else
struct sched_param sched;
int policy;
int pri_policy;
pthread_t thread = pthread_self();
const char *policyhint = SDL_GetHint(SDL_HINT_THREAD_PRIORITY_POLICY);
const SDL_bool timecritical_realtime_hint = SDL_GetHintBoolean(SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL, SDL_FALSE);
if (pthread_getschedparam(thread, &policy, &sched) != 0) {
return SDL_SetError("pthread_getschedparam() failed");
}
/* Higher priority levels may require changing the pthread scheduler policy
* for the thread. SDL will make such changes by default but there is
* also a hint allowing that behavior to be overridden. */
switch (priority) {
case SDL_THREAD_PRIORITY_LOW:
case SDL_THREAD_PRIORITY_NORMAL:
pri_policy = SCHED_OTHER;
break;
case SDL_THREAD_PRIORITY_HIGH:
case SDL_THREAD_PRIORITY_TIME_CRITICAL:
#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)
/* Apple requires SCHED_RR for high priority threads */
pri_policy = SCHED_RR;
break;
#else
pri_policy = SCHED_OTHER;
break;
#endif
default:
pri_policy = policy;
break;
}
if (timecritical_realtime_hint && priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
pri_policy = SCHED_RR;
}
if (policyhint) {
if (SDL_strcmp(policyhint, "current") == 0) {
/* Leave current thread scheduler policy unchanged */
} else if (SDL_strcmp(policyhint, "other") == 0) {
policy = SCHED_OTHER;
} else if (SDL_strcmp(policyhint, "rr") == 0) {
policy = SCHED_RR;
} else if (SDL_strcmp(policyhint, "fifo") == 0) {
policy = SCHED_FIFO;
} else {
policy = pri_policy;
}
} else {
policy = pri_policy;
}
#if __LINUX__
{
pid_t linuxTid = syscall(SYS_gettid);
return SDL_LinuxSetThreadPriorityAndPolicy(linuxTid, priority, policy);
}
#else
if (priority == SDL_THREAD_PRIORITY_LOW) {
sched.sched_priority = sched_get_priority_min(policy);
} else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
@@ -220,9 +269,22 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
} else {
int min_priority = sched_get_priority_min(policy);
int max_priority = sched_get_priority_max(policy);
sched.sched_priority = (min_priority + (max_priority - min_priority) / 2);
if (priority == SDL_THREAD_PRIORITY_HIGH) {
sched.sched_priority += ((max_priority - min_priority) / 4);
#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)
if (min_priority == 15 && max_priority == 47) {
/* Apple has a specific set of thread priorities */
if (priority == SDL_THREAD_PRIORITY_HIGH) {
sched.sched_priority = 45;
} else {
sched.sched_priority = 37;
}
} else
#endif /* __MACOSX__ || __IPHONEOS__ || __TVOS__ */
{
sched.sched_priority = (min_priority + (max_priority - min_priority) / 2);
if (priority == SDL_THREAD_PRIORITY_HIGH) {
sched.sched_priority += ((max_priority - min_priority) / 4);
}
}
}
if (pthread_setschedparam(thread, policy, &sched) != 0) {
@@ -230,6 +292,7 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
}
return 0;
#endif /* linux */
#endif /* #if __NACL__ || __RISCOS__ */
}
void

View File

@@ -23,7 +23,6 @@
extern "C" {
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
#include "SDL_log.h"
}
#include <system_error>

View File

@@ -26,7 +26,6 @@ extern "C" {
#include "SDL_thread.h"
#include "../SDL_thread_c.h"
#include "../SDL_systhread.h"
#include "SDL_log.h"
}
#include <mutex>
@@ -40,16 +39,16 @@ extern "C" {
static void
RunThread(void *args)
{
SDL_RunThread(args);
SDL_RunThread((SDL_Thread *) args);
}
extern "C"
int
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
SDL_SYS_CreateThread(SDL_Thread * thread)
{
try {
// !!! FIXME: no way to set a thread stack size here.
std::thread cpp_thread(RunThread, args);
std::thread cpp_thread(RunThread, thread);
thread->handle = (void *) new std::thread(std::move(cpp_thread));
return 0;
} catch (std::system_error & ex) {

View File

@@ -74,23 +74,16 @@ typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
#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)
SDL_Thread *thread = (SDL_Thread *) data;
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc;
SDL_RunThread(thread);
if (pfnEndThread != NULL) {
pfnEndThread(0);
return (0);
}
return 0;
}
static DWORD WINAPI
@@ -107,33 +100,27 @@ RunThreadViaBeginThreadEx(void *data)
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
int
SDL_SYS_CreateThread(SDL_Thread * thread, void *args,
SDL_SYS_CreateThread(SDL_Thread * thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
{
#elif defined(__CYGWIN__) || defined(__WINRT__)
int
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
SDL_SYS_CreateThread(SDL_Thread * thread)
{
pfnSDL_CurrentBeginThread pfnBeginThread = NULL;
pfnSDL_CurrentEndThread pfnEndThread = NULL;
#else
int
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
SDL_SYS_CreateThread(SDL_Thread * thread)
{
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->endfunc = pfnEndThread;
/* thread->stacksize == 0 means "system default", same as win32 expects */
if (pfnBeginThread) {
@@ -141,12 +128,12 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
thread->handle = (SYS_ThreadHandle)
((size_t) pfnBeginThread(NULL, (unsigned int) thread->stacksize,
RunThreadViaBeginThreadEx,
pThreadParms, flags, &threadid));
thread, flags, &threadid));
} else {
DWORD threadid = 0;
thread->handle = CreateThread(NULL, thread->stacksize,
RunThreadViaCreateThread,
pThreadParms, flags, &threadid);
thread, flags, &threadid);
}
if (thread->handle == NULL) {
return SDL_SetError("Not enough resources to create thread");