From 7c0051ff8ddf49867072bde9d278bfa1bb2a81ee Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 25 Mar 2011 10:47:49 -0700 Subject: [PATCH] Implemented SDL_SetThreadPriority() --- include/SDL_thread.h | 15 +++++++++++++ src/audio/SDL_audio.c | 1 + src/thread/SDL_systhread.h | 3 +++ src/thread/SDL_thread.c | 36 +++++++++++++++++++----------- src/thread/beos/SDL_systhread.c | 14 ++++++++++++ src/thread/generic/SDL_systhread.c | 6 +++++ src/thread/nds/SDL_syscond.c | 2 ++ src/thread/nds/SDL_sysmutex.c | 2 ++ src/thread/nds/SDL_syssem.c | 2 ++ src/thread/nds/SDL_systhread.c | 8 +++++++ src/thread/pthread/SDL_systhread.c | 27 ++++++++++++++++++++++ src/thread/windows/SDL_systhread.c | 19 ++++++++++++++++ 12 files changed, 122 insertions(+), 13 deletions(-) diff --git a/include/SDL_thread.h b/include/SDL_thread.h index 86e259e87..66a7f8dec 100644 --- a/include/SDL_thread.h +++ b/include/SDL_thread.h @@ -50,6 +50,16 @@ typedef struct SDL_Thread SDL_Thread; /* The SDL thread ID */ typedef unsigned long SDL_threadID; +/* The SDL thread priority + * + * Note: On many systems you require special privileges to set high priority. + */ +typedef enum { + SDL_THREAD_PRIORITY_LOW, + SDL_THREAD_PRIORITY_NORMAL, + SDL_THREAD_PRIORITY_HIGH +} SDL_ThreadPriority; + /* The function passed to SDL_CreateThread() It is passed a void* user context parameter and returns an int. */ @@ -146,6 +156,11 @@ extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void); */ extern DECLSPEC SDL_threadID SDLCALL SDL_GetThreadID(SDL_Thread * thread); +/** + * Set the thread priority + */ +extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_Thread * thread, SDL_ThreadPriority priority); + /** * Wait for a thread to finish. * diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index bb4dfa38c..ad4bc02e8 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -974,6 +974,7 @@ open_audio_device(const char *devname, int iscapture, SDL_SetError("Couldn't create audio thread"); return 0; } + SDL_SetThreadPriority(device->thread, SDL_THREAD_PRIORITY_HIGH); } return id + 1; diff --git a/src/thread/SDL_systhread.h b/src/thread/SDL_systhread.h index 231947a4a..f520ddd79 100644 --- a/src/thread/SDL_systhread.h +++ b/src/thread/SDL_systhread.h @@ -43,6 +43,9 @@ extern int SDL_SYS_CreateThread(SDL_Thread * thread, void *args); /* This function does any necessary setup in the child thread */ extern void SDL_SYS_SetupThread(void); +/* This function sets thread priority */ +extern int SDL_SYS_SetThreadPriority(SDL_Thread * thread, SDL_ThreadPriority priority); + /* This function waits for the thread to finish and frees any data allocated by SDL_SYS_CreateThread() */ diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index b7bfcb09c..349e7b49e 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -281,19 +281,6 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), void *data) return (thread); } -void -SDL_WaitThread(SDL_Thread * thread, int *status) -{ - if (thread) { - SDL_SYS_WaitThread(thread); - if (status) { - *status = thread->status; - } - SDL_DelThread(thread); - SDL_free(thread); - } -} - SDL_threadID SDL_GetThreadID(SDL_Thread * thread) { @@ -307,4 +294,27 @@ SDL_GetThreadID(SDL_Thread * thread) return id; } +int +SDL_SetThreadPriority(SDL_Thread * thread, SDL_ThreadPriority priority) +{ + if (!thread) { + SDL_SetError("SDL_SetThreadPriority() passed NULL thread"); + return -1; + } + return SDL_SYS_SetThreadPriority(thread, priority); +} + +void +SDL_WaitThread(SDL_Thread * thread, int *status) +{ + if (thread) { + SDL_SYS_WaitThread(thread); + if (status) { + *status = thread->status; + } + SDL_DelThread(thread); + SDL_free(thread); + } +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/beos/SDL_systhread.c b/src/thread/beos/SDL_systhread.c index f2400e405..235bcae88 100644 --- a/src/thread/beos/SDL_systhread.c +++ b/src/thread/beos/SDL_systhread.c @@ -90,6 +90,20 @@ SDL_ThreadID(void) return ((SDL_threadID) find_thread(NULL)); } +int +SDL_SYS_SetThreadPriority(SDL_Thread * thread, SDL_ThreadPriority priority) +{ + int32 new_priority = B_NORMAL_PRIORITY; + + if (priority == SDL_THREAD_PRIORITY_LOW) { + new_priority = B_LOW_PRIORITY; + } else if (priority == SDL_THREAD_PRIORITY_HIGH) { + new_priority = B_URGENT_DISPLAY_PRIORITY; + } + set_thread_priority(thread->handle, new_priority); + return 0; +} + void SDL_SYS_WaitThread(SDL_Thread * thread) { diff --git a/src/thread/generic/SDL_systhread.c b/src/thread/generic/SDL_systhread.c index 07c4447d7..e59f3a945 100644 --- a/src/thread/generic/SDL_systhread.c +++ b/src/thread/generic/SDL_systhread.c @@ -45,6 +45,12 @@ SDL_ThreadID(void) return (0); } +int +SDL_SYS_SetThreadPriority(SDL_Thread * thread, SDL_ThreadPriority priority) +{ + return (0); +} + void SDL_SYS_WaitThread(SDL_Thread * thread) { diff --git a/src/thread/nds/SDL_syscond.c b/src/thread/nds/SDL_syscond.c index 9dc26758c..fbbec132e 100644 --- a/src/thread/nds/SDL_syscond.c +++ b/src/thread/nds/SDL_syscond.c @@ -227,3 +227,5 @@ SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) { return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); } + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/nds/SDL_sysmutex.c b/src/thread/nds/SDL_sysmutex.c index e967ce3e1..c826bb2eb 100644 --- a/src/thread/nds/SDL_sysmutex.c +++ b/src/thread/nds/SDL_sysmutex.c @@ -140,3 +140,5 @@ SDL_mutexV(SDL_mutex * mutex) return 0; #endif /* DISABLE_THREADS */ } + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/nds/SDL_syssem.c b/src/thread/nds/SDL_syssem.c index 8f5306177..74972d879 100644 --- a/src/thread/nds/SDL_syssem.c +++ b/src/thread/nds/SDL_syssem.c @@ -226,3 +226,5 @@ SDL_SemPost(SDL_sem * sem) } #endif /* DISABLE_THREADS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/nds/SDL_systhread.c b/src/thread/nds/SDL_systhread.c index 171a6dd75..ad5bf9bed 100644 --- a/src/thread/nds/SDL_systhread.c +++ b/src/thread/nds/SDL_systhread.c @@ -56,8 +56,16 @@ SDL_SYS_WaitThread(SDL_Thread * thread) return; } +int +SDL_SYS_SetThreadPriority(SDL_Thread * thread, SDL_ThreadPriority priority) +{ + return (0); +} + void SDL_SYS_KillThread(SDL_Thread * thread) { return; } + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index 07c9f16a8..42e60f3f0 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -91,6 +91,33 @@ SDL_ThreadID(void) return ((SDL_threadID) pthread_self()); } +int +SDL_SYS_SetThreadPriority(SDL_Thread * thread, SDL_ThreadPriority priority) +{ + struct sched_param sched; + int policy; + + if (pthread_getschedparam(thread->handle, &policy, &sched) < 0) { + SDL_SetError("pthread_getschedparam() failed"); + return -1; + } + if (priority == SDL_THREAD_PRIORITY_LOW) { + sched.sched_priority = sched_get_priority_min(policy); + } else if (priority == SDL_THREAD_PRIORITY_HIGH) { + sched.sched_priority = sched_get_priority_max(policy); + } else { + int min_priority = sched_get_priority_min(policy); + int max_priority = sched_get_priority_max(policy); + int priority = (min_priority + (max_priority - min_priority) / 2); + sched.sched_priority = priority; + } + if (pthread_setschedparam(thread->handle, policy, &sched) < 0) { + SDL_SetError("pthread_setschedparam() failed"); + return -1; + } + return 0; +} + void SDL_SYS_WaitThread(SDL_Thread * thread) { diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index dbd8dc0f2..058ff93f0 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -155,6 +155,25 @@ SDL_ThreadID(void) return ((SDL_threadID) GetCurrentThreadId()); } +int +SDL_SYS_SetThreadPriority(SDL_Thread * thread, SDL_ThreadPriority priority) +{ + BOOL result; + + if (priority == SDL_THREAD_PRIORITY_LOW) { + result = SetThreadPriority(thread->handle, THREAD_PRIORITY_LOWEST); + } else if (priority == SDL_THREAD_PRIORITY_HIGH) { + result = SetThreadPriority(thread->handle, THREAD_PRIORITY_HIGHEST); + } else { + result = SetThreadPriority(thread->handle, THREAD_PRIORITY_NORMAL); + } + if (!result) { + WIN_SetError("SetThreadPriority()"); + return -1; + } + return 0; +} + void SDL_SYS_WaitThread(SDL_Thread * thread) {