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 
22 #include "SDL_config.h"
23 
24 #include <pthread.h>
25 
26 #if HAVE_PTHREAD_NP_H
27 #include <pthread_np.h>
28 #endif
29 
30 #include <signal.h>
31 
32 #ifdef __LINUX__
33 #include <sys/time.h>
34 #include <sys/resource.h>
35 #include <sys/syscall.h>
36 #include <unistd.h>
37 #endif /* __LINUX__ */
38 
39 #if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)
40 #include <dlfcn.h>
41 #ifndef RTLD_DEFAULT
42 #define RTLD_DEFAULT NULL
43 #endif
44 #endif
45 
46 #include "SDL_platform.h"
47 #include "SDL_thread.h"
48 #include "../SDL_thread_c.h"
49 #include "../SDL_systhread.h"
50 #ifdef __ANDROID__
51 #include "../../core/android/SDL_android.h"
52 #endif
53 
54 #include "SDL_assert.h"
55 
56 /* List of signals to mask in the subthreads */
57 static const int sig_list[] = {
58  SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
59  SIGVTALRM, SIGPROF, 0
60 };
61 
62 
63 static void *
65 {
66 #ifdef __ANDROID__
68 #endif
69  SDL_RunThread(data);
70  return NULL;
71 }
72 
73 #if defined(__MACOSX__) || defined(__IPHONEOS__)
74 static SDL_bool checked_setname = SDL_FALSE;
75 static int (*ppthread_setname_np)(const char*) = NULL;
76 #elif defined(__LINUX__)
77 static SDL_bool checked_setname = SDL_FALSE;
78 static int (*ppthread_setname_np)(pthread_t, const char*) = NULL;
79 #endif
80 int
82 {
83  pthread_attr_t type;
84 
85  /* do this here before any threads exist, so there's no race condition. */
86  #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
87  if (!checked_setname) {
88  void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np");
89  #if defined(__MACOSX__) || defined(__IPHONEOS__)
90  ppthread_setname_np = (int(*)(const char*)) fn;
91  #elif defined(__LINUX__)
92  ppthread_setname_np = (int(*)(pthread_t, const char*)) fn;
93  #endif
94  checked_setname = SDL_TRUE;
95  }
96  #endif
97 
98  /* Set the thread attributes */
99  if (pthread_attr_init(&type) != 0) {
100  return SDL_SetError("Couldn't initialize pthread attributes");
101  }
102  pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
103 
104  /* Create the thread and go! */
105  if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
106  return SDL_SetError("Not enough resources to create thread");
107  }
108 
109  return 0;
110 }
111 
112 void
114 {
115  int i;
116  sigset_t mask;
117 
118  if (name != NULL) {
119  #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
120  SDL_assert(checked_setname);
121  if (ppthread_setname_np != NULL) {
122  #if defined(__MACOSX__) || defined(__IPHONEOS__)
123  ppthread_setname_np(name);
124  #elif defined(__LINUX__)
125  ppthread_setname_np(pthread_self(), name);
126  #endif
127  }
128  #elif HAVE_PTHREAD_SETNAME_NP
129  pthread_setname_np(pthread_self(), name);
130  #elif HAVE_PTHREAD_SET_NAME_NP
131  pthread_set_name_np(pthread_self(), name);
132  #endif
133  }
134 
135  /* Mask asynchronous signals for this thread */
136  sigemptyset(&mask);
137  for (i = 0; sig_list[i]; ++i) {
138  sigaddset(&mask, sig_list[i]);
139  }
140  pthread_sigmask(SIG_BLOCK, &mask, 0);
141 
142 #ifdef PTHREAD_CANCEL_ASYNCHRONOUS
143  /* Allow ourselves to be asynchronously cancelled */
144  {
145  int oldstate;
146  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
147  }
148 #endif
149 }
150 
153 {
154  return ((SDL_threadID) pthread_self());
155 }
156 
157 int
159 {
160 #ifdef __LINUX__
161  int value;
162 
163  if (priority == SDL_THREAD_PRIORITY_LOW) {
164  value = 19;
165  } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
166  value = -20;
167  } else {
168  value = 0;
169  }
170  if (setpriority(PRIO_PROCESS, syscall(SYS_gettid), value) < 0) {
171  /* Note that this fails if you're trying to set high priority
172  and you don't have root permission. BUT DON'T RUN AS ROOT!
173  */
174  return SDL_SetError("setpriority() failed");
175  }
176  return 0;
177 #else
178  struct sched_param sched;
179  int policy;
180  pthread_t thread = pthread_self();
181 
182  if (pthread_getschedparam(thread, &policy, &sched) < 0) {
183  return SDL_SetError("pthread_getschedparam() failed");
184  }
185  if (priority == SDL_THREAD_PRIORITY_LOW) {
186  sched.sched_priority = sched_get_priority_min(policy);
187  } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
188  sched.sched_priority = sched_get_priority_max(policy);
189  } else {
190  int min_priority = sched_get_priority_min(policy);
191  int max_priority = sched_get_priority_max(policy);
192  sched.sched_priority = (min_priority + (max_priority - min_priority) / 2);
193  }
194  if (pthread_setschedparam(thread, policy, &sched) < 0) {
195  return SDL_SetError("pthread_setschedparam() failed");
196  }
197  return 0;
198 #endif /* linux */
199 }
200 
201 void
203 {
204  pthread_join(thread->handle, 0);
205 }
206 
207 /* vi: set ts=4 sw=4 expandtab: */
DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void)
Definition: SDL_systhread.c:48
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
unsigned long SDL_threadID
Definition: SDL_thread.h:49
#define NULL
Definition: ftobjs.h:61
SDL_bool
Definition: SDL_stdinc.h:116
static void * RunThread(void *data)
Definition: SDL_systhread.c:64
EGLImageKHR EGLint * name
Definition: eglext.h:284
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
Definition: SDL_systhread.c:42
int Android_JNI_SetupThread(void)
void SDL_SYS_WaitThread(SDL_Thread *thread)
Definition: SDL_systhread.c:60
int
Definition: SDL_systhread.c:37
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
Definition: SDL_systhread.c:54
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
static const int sig_list[]
Definition: SDL_systhread.c:57
#define SDL_assert(condition)
Definition: SDL_assert.h:159
static SDL_Thread * thread
SYS_ThreadHandle handle
Definition: SDL_thread_c.h:51
EGLSurface EGLint void ** value
Definition: eglext.h:301
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: gl2ext.h:961
void SDL_RunThread(void *data)
Definition: SDL_thread.c:263
void SDL_SYS_SetupThread(const char *name)
Definition: SDL_systhread.c:42
SDL_ThreadPriority
Definition: SDL_thread.h:59
int i
Definition: pngrutil.c:1377