linux: Move SDL_LinuxSetThreadPriority() elsewhere to fix build.
Fixes Bugzilla #4393.
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
22 #include "../../SDL_internal.h"
23 #include "SDL_system.h"
28 #include <pthread_np.h>
35 #include <sys/resource.h>
36 #include <sys/syscall.h>
40 #include "../../core/linux/SDL_dbus.h"
41 #endif /* __LINUX__ */
43 #if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)
46 #define RTLD_DEFAULT NULL
51 #include "SDL_platform.h"
52 #include "SDL_thread.h"
53 #include "SDL_system.h"
54 #include "../SDL_thread_c.h"
55 #include "../SDL_systhread.h"
57 #include "../../core/android/SDL_android.h"
61 #include <kernel/OS.h>
64 #include "SDL_assert.h"
67 /* List of signals to mask in the subthreads */
68 static const int sig_list[] = {
69 SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
78 Android_JNI_SetupThread();
84 #if defined(__MACOSX__) || defined(__IPHONEOS__)
85 static SDL_bool checked_setname = SDL_FALSE;
86 static int (*ppthread_setname_np)(const char*) = NULL;
87 #elif defined(__LINUX__)
88 static SDL_bool checked_setname = SDL_FALSE;
89 static int (*ppthread_setname_np)(pthread_t, const char*) = NULL;
92 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
96 /* do this here before any threads exist, so there's no race condition. */
97 #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
98 if (!checked_setname) {
99 void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np");
100 #if defined(__MACOSX__) || defined(__IPHONEOS__)
101 ppthread_setname_np = (int(*)(const char*)) fn;
102 #elif defined(__LINUX__)
103 ppthread_setname_np = (int(*)(pthread_t, const char*)) fn;
105 checked_setname = SDL_TRUE;
109 /* Set the thread attributes */
110 if (pthread_attr_init(&type) != 0) {
111 return SDL_SetError("Couldn't initialize pthread attributes");
113 pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
115 /* Set caller-requested stack size. Otherwise: use the system default. */
116 if (thread->stacksize) {
117 pthread_attr_setstacksize(&type, (size_t) thread->stacksize);
120 /* Create the thread and go! */
121 if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
122 return SDL_SetError("Not enough resources to create thread");
129 SDL_SYS_SetupThread(const char *name)
131 #if !defined(__NACL__)
134 #endif /* !__NACL__ */
137 #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
138 SDL_assert(checked_setname);
139 if (ppthread_setname_np != NULL) {
140 #if defined(__MACOSX__) || defined(__IPHONEOS__)
141 ppthread_setname_np(name);
142 #elif defined(__LINUX__)
143 ppthread_setname_np(pthread_self(), name);
146 #elif HAVE_PTHREAD_SETNAME_NP
147 #if defined(__NETBSD__)
148 pthread_setname_np(pthread_self(), "%s", name);
150 pthread_setname_np(pthread_self(), name);
152 #elif HAVE_PTHREAD_SET_NAME_NP
153 pthread_set_name_np(pthread_self(), name);
154 #elif defined(__HAIKU__)
155 /* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */
156 char namebuf[B_OS_NAME_LENGTH];
157 SDL_snprintf(namebuf, sizeof (namebuf), "%s", name);
158 namebuf[sizeof (namebuf) - 1] = '\0';
159 rename_thread(find_thread(NULL), namebuf);
163 /* NativeClient does not yet support signals.*/
164 #if !defined(__NACL__)
165 /* Mask asynchronous signals for this thread */
167 for (i = 0; sig_list[i]; ++i) {
168 sigaddset(&mask, sig_list[i]);
170 pthread_sigmask(SIG_BLOCK, &mask, 0);
171 #endif /* !__NACL__ */
174 #ifdef PTHREAD_CANCEL_ASYNCHRONOUS
175 /* Allow ourselves to be asynchronously cancelled */
178 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
186 return ((SDL_threadID) pthread_self());
190 SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
193 /* FIXME: Setting thread priority does not seem to be supported in NACL */
197 pid_t thread = syscall(SYS_gettid);
199 if (priority == SDL_THREAD_PRIORITY_LOW) {
201 } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
203 } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
208 return SDL_LinuxSetThreadPriority(thread, value);
210 struct sched_param sched;
212 pthread_t thread = pthread_self();
214 if (pthread_getschedparam(thread, &policy, &sched) != 0) {
215 return SDL_SetError("pthread_getschedparam() failed");
217 if (priority == SDL_THREAD_PRIORITY_LOW) {
218 sched.sched_priority = sched_get_priority_min(policy);
219 } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
220 sched.sched_priority = sched_get_priority_max(policy);
222 int min_priority = sched_get_priority_min(policy);
223 int max_priority = sched_get_priority_max(policy);
224 sched.sched_priority = (min_priority + (max_priority - min_priority) / 2);
225 if (priority == SDL_THREAD_PRIORITY_HIGH) {
226 sched.sched_priority += ((max_priority - min_priority) / 4);
229 if (pthread_setschedparam(thread, policy, &sched) != 0) {
230 return SDL_SetError("pthread_setschedparam() failed");
237 SDL_SYS_WaitThread(SDL_Thread * thread)
239 pthread_join(thread->handle, 0);
243 SDL_SYS_DetachThread(SDL_Thread * thread)
245 pthread_detach(thread->handle);
248 /* vi: set ts=4 sw=4 expandtab: */