SDL 2.0
SDL_systhread.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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
22#include "../../SDL_internal.h"
23#include "SDL_system.h"
24
25#include <pthread.h>
26
27#if HAVE_PTHREAD_NP_H
28#include <pthread_np.h>
29#endif
30
31#include <signal.h>
32
33#ifdef __LINUX__
34#include <sys/time.h>
35#include <sys/resource.h>
36#include <sys/syscall.h>
37#include <unistd.h>
38#include <errno.h>
39
40#include "../../core/linux/SDL_dbus.h"
41#endif /* __LINUX__ */
42
43#if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)
44#include <dlfcn.h>
45#ifndef RTLD_DEFAULT
46#define RTLD_DEFAULT NULL
47#endif
48#endif
49
50#include "SDL_log.h"
51#include "SDL_platform.h"
52#include "SDL_thread.h"
53#include "../SDL_thread_c.h"
54#include "../SDL_systhread.h"
55#ifdef __ANDROID__
56#include "../../core/android/SDL_android.h"
57#endif
58
59#ifdef __HAIKU__
60#include <kernel/OS.h>
61#endif
62
63#include "SDL_assert.h"
64
65#ifndef __NACL__
66/* List of signals to mask in the subthreads */
67static const int sig_list[] = {
68 SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
69 SIGVTALRM, SIGPROF, 0
70};
71#endif
72
73static void *
75{
76#ifdef __ANDROID__
78#endif
80 return NULL;
81}
82
83#if defined(__MACOSX__) || defined(__IPHONEOS__)
84static SDL_bool checked_setname = SDL_FALSE;
85static int (*ppthread_setname_np)(const char*) = NULL;
86#elif defined(__LINUX__)
87static SDL_bool checked_setname = SDL_FALSE;
88static int (*ppthread_setname_np)(pthread_t, const char*) = NULL;
89#endif
90int
91SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
92{
93 pthread_attr_t type;
94
95 /* do this here before any threads exist, so there's no race condition. */
96 #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
97 if (!checked_setname) {
98 void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np");
99 #if defined(__MACOSX__) || defined(__IPHONEOS__)
100 ppthread_setname_np = (int(*)(const char*)) fn;
101 #elif defined(__LINUX__)
102 ppthread_setname_np = (int(*)(pthread_t, const char*)) fn;
103 #endif
104 checked_setname = SDL_TRUE;
105 }
106 #endif
107
108 /* Set the thread attributes */
109 if (pthread_attr_init(&type) != 0) {
110 return SDL_SetError("Couldn't initialize pthread attributes");
111 }
112 pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
113
114 /* Set caller-requested stack size. Otherwise: use the system default. */
115 if (thread->stacksize) {
116 pthread_attr_setstacksize(&type, (size_t) thread->stacksize);
117 }
118
119 /* Create the thread and go! */
120 if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
121 return SDL_SetError("Not enough resources to create thread");
122 }
123
124 return 0;
125}
126
127void
129{
130#if !defined(__NACL__)
131 int i;
132 sigset_t mask;
133#endif /* !__NACL__ */
134
135 if (name != NULL) {
136 #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
137 SDL_assert(checked_setname);
138 if (ppthread_setname_np != NULL) {
139 #if defined(__MACOSX__) || defined(__IPHONEOS__)
140 ppthread_setname_np(name);
141 #elif defined(__LINUX__)
142 ppthread_setname_np(pthread_self(), name);
143 #endif
144 }
145 #elif HAVE_PTHREAD_SETNAME_NP
146 #if defined(__NETBSD__)
147 pthread_setname_np(pthread_self(), "%s", name);
148 #else
149 pthread_setname_np(pthread_self(), name);
150 #endif
151 #elif HAVE_PTHREAD_SET_NAME_NP
152 pthread_set_name_np(pthread_self(), name);
153 #elif defined(__HAIKU__)
154 /* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */
155 char namebuf[B_OS_NAME_LENGTH];
156 SDL_snprintf(namebuf, sizeof (namebuf), "%s", name);
157 namebuf[sizeof (namebuf) - 1] = '\0';
158 rename_thread(find_thread(NULL), namebuf);
159 #endif
160 }
161
162 /* NativeClient does not yet support signals.*/
163#if !defined(__NACL__)
164 /* Mask asynchronous signals for this thread */
165 sigemptyset(&mask);
166 for (i = 0; sig_list[i]; ++i) {
167 sigaddset(&mask, sig_list[i]);
168 }
169 pthread_sigmask(SIG_BLOCK, &mask, 0);
170#endif /* !__NACL__ */
171
172
173#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
174 /* Allow ourselves to be asynchronously cancelled */
175 {
176 int oldstate;
177 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
178 }
179#endif
180}
181
184{
185 return ((SDL_threadID) pthread_self());
186}
187
188int
190{
191#if __NACL__
192 /* FIXME: Setting thread priority does not seem to be supported in NACL */
193 return 0;
194#elif __LINUX__
195 int value;
196 pid_t thread = syscall(SYS_gettid);
197
198 if (priority == SDL_THREAD_PRIORITY_LOW) {
199 value = 19;
200 } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
201 value = -10;
202 } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
203 value = -20;
204 } else {
205 value = 0;
206 }
207 return SDL_LinuxSetThreadPriority(thread, value);
208#else
209 struct sched_param sched;
210 int policy;
211 pthread_t thread = pthread_self();
212
213 if (pthread_getschedparam(thread, &policy, &sched) != 0) {
214 return SDL_SetError("pthread_getschedparam() failed");
215 }
216 if (priority == SDL_THREAD_PRIORITY_LOW) {
217 sched.sched_priority = sched_get_priority_min(policy);
218 } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
219 sched.sched_priority = sched_get_priority_max(policy);
220 } else {
221 int min_priority = sched_get_priority_min(policy);
222 int max_priority = sched_get_priority_max(policy);
223 sched.sched_priority = (min_priority + (max_priority - min_priority) / 2);
224 if (priority == SDL_THREAD_PRIORITY_HIGH) {
225 sched.sched_priority += ((max_priority - min_priority) / 4);
226 }
227 }
228 if (pthread_setschedparam(thread, policy, &sched) != 0) {
229 return SDL_SetError("pthread_setschedparam() failed");
230 }
231 return 0;
232#endif /* linux */
233}
234
235void
237{
238 pthread_join(thread->handle, 0);
239}
240
241void
243{
244 pthread_detach(thread->handle);
245}
246
247/* vi: set ts=4 sw=4 expandtab: */
int Android_JNI_SetupThread(void)
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define SDL_SetError
#define SDL_LinuxSetThreadPriority
#define SDL_snprintf
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
GLuint const GLchar * name
GLsizei const GLfloat * value
GLenum GLint GLuint mask
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
void SDL_RunThread(void *data)
Definition: SDL_thread.c:265
unsigned long SDL_threadID
Definition: SDL_thread.h:49
SDL_ThreadPriority
Definition: SDL_thread.h:59
@ SDL_THREAD_PRIORITY_TIME_CRITICAL
Definition: SDL_thread.h:63
@ SDL_THREAD_PRIORITY_LOW
Definition: SDL_thread.h:60
@ SDL_THREAD_PRIORITY_HIGH
Definition: SDL_thread.h:62
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
#define NULL
Definition: begin_code.h:167
EGLint policy
Definition: eglext.h:593
void SDL_SYS_SetupThread(const char *name)
Definition: SDL_systhread.c:42
void SDL_SYS_DetachThread(SDL_Thread *thread)
Definition: SDL_systhread.c:66
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
Definition: SDL_systhread.c:54
void SDL_SYS_WaitThread(SDL_Thread *thread)
Definition: SDL_systhread.c:60
SDL_threadID SDL_ThreadID(void)
Definition: SDL_systhread.c:48
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
Definition: SDL_systhread.c:35
static const int sig_list[]
Definition: SDL_systhread.c:67
static void * RunThread(void *data)
Definition: SDL_systhread.c:74
SYS_ThreadHandle handle
Definition: SDL_thread_c.h:57
size_t stacksize
Definition: SDL_thread_c.h:62