From 8ceb800defbf13354866cd7c6a4b676cf54aad5d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 27 Oct 2013 08:14:13 -0700 Subject: Rework threading functions --- Alc/alcThread.c | 144 ------------------------------------------ Alc/backends/alsa.c | 10 +-- Alc/backends/dsound.c | 6 +- Alc/backends/mmdevapi.c | 6 +- Alc/backends/null.c | 6 +- Alc/backends/oss.c | 12 ++-- Alc/backends/pulseaudio.c | 10 +-- Alc/backends/qsa.c | 17 +++-- Alc/backends/sndio.c | 6 +- Alc/backends/solaris.c | 9 +-- Alc/backends/wave.c | 6 +- Alc/backends/winmm.c | 1 + Alc/threads.c | 152 +++++++++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 2 +- OpenAL32/Include/alMain.h | 4 -- OpenAL32/Include/threads.h | 14 +++++ 16 files changed, 213 insertions(+), 192 deletions(-) delete mode 100644 Alc/alcThread.c create mode 100644 Alc/threads.c create mode 100644 OpenAL32/Include/threads.h diff --git a/Alc/alcThread.c b/Alc/alcThread.c deleted file mode 100644 index c2f38031..00000000 --- a/Alc/alcThread.c +++ /dev/null @@ -1,144 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include - -#include "alMain.h" -#include "alThunk.h" - -#define THREAD_STACK_SIZE (1*1024*1024) /* 1MB */ - -#ifdef _WIN32 - -typedef struct { - ALuint (*func)(ALvoid*); - ALvoid *ptr; - HANDLE thread; -} ThreadInfo; - -static DWORD CALLBACK StarterFunc(void *ptr) -{ - ThreadInfo *inf = (ThreadInfo*)ptr; - ALint ret; - - ret = inf->func(inf->ptr); - ExitThread((DWORD)ret); - - return (DWORD)ret; -} - -ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr) -{ - DWORD dummy; - ThreadInfo *inf = malloc(sizeof(ThreadInfo)); - if(!inf) return 0; - - inf->func = func; - inf->ptr = ptr; - - inf->thread = CreateThread(NULL, THREAD_STACK_SIZE, StarterFunc, inf, 0, &dummy); - if(!inf->thread) - { - free(inf); - return NULL; - } - - return inf; -} - -ALuint StopThread(ALvoid *thread) -{ - ThreadInfo *inf = thread; - DWORD ret = 0; - - WaitForSingleObject(inf->thread, INFINITE); - GetExitCodeThread(inf->thread, &ret); - CloseHandle(inf->thread); - - free(inf); - - return (ALuint)ret; -} - -#else - -#include - -typedef struct { - ALuint (*func)(ALvoid*); - ALvoid *ptr; - ALuint ret; - pthread_t thread; -} ThreadInfo; - -static void *StarterFunc(void *ptr) -{ - ThreadInfo *inf = (ThreadInfo*)ptr; - inf->ret = inf->func(inf->ptr); - return NULL; -} - -ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr) -{ - pthread_attr_t attr; - ThreadInfo *inf = malloc(sizeof(ThreadInfo)); - if(!inf) return NULL; - - if(pthread_attr_init(&attr) != 0) - { - free(inf); - return NULL; - } - if(pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE) != 0) - { - pthread_attr_destroy(&attr); - free(inf); - return NULL; - } - - inf->func = func; - inf->ptr = ptr; - if(pthread_create(&inf->thread, &attr, StarterFunc, inf) != 0) - { - pthread_attr_destroy(&attr); - free(inf); - return NULL; - } - pthread_attr_destroy(&attr); - - return inf; -} - -ALuint StopThread(ALvoid *thread) -{ - ThreadInfo *inf = thread; - ALuint ret; - - pthread_join(inf->thread, NULL); - ret = inf->ret; - - free(inf); - - return ret; -} - -#endif diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c index bb30dac5..c60187fa 100644 --- a/Alc/backends/alsa.c +++ b/Alc/backends/alsa.c @@ -26,6 +26,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" #include @@ -293,7 +294,7 @@ typedef struct { snd_pcm_sframes_t last_avail; volatile int killNow; - ALvoid *thread; + althread_t thread; } alsa_data; typedef struct { @@ -849,6 +850,7 @@ error: static ALCboolean alsa_start_playback(ALCdevice *device) { alsa_data *data = (alsa_data*)device->ExtraData; + ALuint (*thread_func)(ALvoid*) = NULL; snd_pcm_hw_params_t *hp = NULL; snd_pcm_access_t access; const char *funcerr; @@ -872,7 +874,7 @@ static ALCboolean alsa_start_playback(ALCdevice *device) ERR("buffer malloc failed\n"); return ALC_FALSE; } - data->thread = StartThread(ALSANoMMapProc, device); + thread_func = ALSANoMMapProc; } else { @@ -882,9 +884,9 @@ static ALCboolean alsa_start_playback(ALCdevice *device) ERR("snd_pcm_prepare(data->pcmHandle) failed: %s\n", snd_strerror(err)); return ALC_FALSE; } - data->thread = StartThread(ALSAProc, device); + thread_func = ALSAProc; } - if(data->thread == NULL) + if(!StartThread(&data->thread, thread_func, device)) { ERR("Could not create playback thread\n"); free(data->buffer); diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c index 22af15d8..f09967a0 100644 --- a/Alc/backends/dsound.c +++ b/Alc/backends/dsound.c @@ -34,6 +34,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" #ifndef DSSPEAKER_5POINT1 # define DSSPEAKER_5POINT1 0x00000006 @@ -74,7 +75,7 @@ typedef struct { HANDLE NotifyEvent; volatile int killNow; - ALvoid *thread; + althread_t thread; } DSoundPlaybackData; typedef struct { @@ -632,8 +633,7 @@ static ALCboolean DSoundStartPlayback(ALCdevice *device) { DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData; - data->thread = StartThread(DSoundPlaybackProc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, DSoundPlaybackProc, device)) return ALC_FALSE; return ALC_TRUE; diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c index e6447bef..fb70d609 100644 --- a/Alc/backends/mmdevapi.c +++ b/Alc/backends/mmdevapi.c @@ -40,6 +40,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); @@ -69,7 +70,7 @@ typedef struct { volatile UINT32 Padding; volatile int killNow; - ALvoid *thread; + althread_t thread; } MMDevApiData; @@ -677,8 +678,7 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr) if(SUCCEEDED(hr)) { data->render = ptr; - data->thread = StartThread(MMDevApiProc, device); - if(!data->thread) + if(!StartThread(&data->thread, MMDevApiProc, device)) { if(data->render) IAudioRenderClient_Release(data->render); diff --git a/Alc/backends/null.c b/Alc/backends/null.c index 73e3e8cb..9742424c 100644 --- a/Alc/backends/null.c +++ b/Alc/backends/null.c @@ -27,11 +27,12 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" typedef struct { volatile int killNow; - ALvoid *thread; + althread_t thread; } null_data; @@ -112,8 +113,7 @@ static ALCboolean null_start_playback(ALCdevice *device) { null_data *data = (null_data*)device->ExtraData; - data->thread = StartThread(NullProc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, NullProc, device)) return ALC_FALSE; return ALC_TRUE; diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c index 892e2327..35ae80cc 100644 --- a/Alc/backends/oss.c +++ b/Alc/backends/oss.c @@ -33,6 +33,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" #include @@ -54,14 +55,15 @@ static const char *oss_capture = "/dev/dsp"; typedef struct { int fd; - volatile int killNow; - ALvoid *thread; ALubyte *mix_data; int data_size; RingBuffer *ring; int doCapture; + + volatile int killNow; + althread_t thread; } oss_data; @@ -286,8 +288,7 @@ static ALCboolean oss_start_playback(ALCdevice *device) data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); data->mix_data = calloc(1, data->data_size); - data->thread = StartThread(OSSProc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, OSSProc, device)) { free(data->mix_data); data->mix_data = NULL; @@ -428,8 +429,7 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName) data->mix_data = calloc(1, data->data_size); device->ExtraData = data; - data->thread = StartThread(OSSCaptureProc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, OSSCaptureProc, device)) { device->ExtraData = NULL; free(data->mix_data); diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index 5b6e0fad..4dc016a1 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -25,6 +25,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" #include @@ -205,11 +206,11 @@ typedef struct { pa_threaded_mainloop *loop; - ALvoid *thread; - volatile ALboolean killNow; - pa_stream *stream; pa_context *context; + + volatile ALboolean killNow; + althread_t thread; } pulse_data; typedef struct { @@ -1151,8 +1152,7 @@ static ALCboolean pulse_start_playback(ALCdevice *device) { pulse_data *data = device->ExtraData; - data->thread = StartThread(PulseProc, device); - if(!data->thread) + if(!StartThread(&data->thread, PulseProc, device)) return ALC_FALSE; return ALC_TRUE; diff --git a/Alc/backends/qsa.c b/Alc/backends/qsa.c index 2890a121..d91ffb2c 100644 --- a/Alc/backends/qsa.c +++ b/Alc/backends/qsa.c @@ -31,20 +31,22 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" + typedef struct { snd_pcm_t* pcmHandle; int audio_fd; + snd_pcm_channel_setup_t csetup; + snd_pcm_channel_params_t cparams; + ALvoid* buffer; ALsizei size; volatile int killNow; - ALvoid* thread; - - snd_pcm_channel_setup_t csetup; - snd_pcm_channel_params_t cparams; + althread_t thread; } qsa_data; typedef struct @@ -619,13 +621,10 @@ static ALCboolean qsa_reset_playback(ALCdevice* device) static ALCboolean qsa_start_playback(ALCdevice* device) { - qsa_data* data=(qsa_data*)device->ExtraData; + qsa_data *data = (qsa_data*)device->ExtraData; - data->thread=StartThread(qsa_proc_playback, device); - if (data->thread==NULL) - { + if(!StartThread(&data->thread, qsa_proc_playback, device)) return ALC_FALSE; - } return ALC_TRUE; } diff --git a/Alc/backends/sndio.c b/Alc/backends/sndio.c index 4c3a5de6..d61ab3df 100644 --- a/Alc/backends/sndio.c +++ b/Alc/backends/sndio.c @@ -26,6 +26,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" #include @@ -46,7 +47,7 @@ typedef struct { ALsizei data_size; volatile int killNow; - ALvoid *thread; + althread_t thread; } sndio_data; @@ -223,8 +224,7 @@ static ALCboolean sndio_start_playback(ALCdevice *device) data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); data->mix_data = calloc(1, data->data_size); - data->thread = StartThread(sndio_proc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, sndio_proc, device)) { sio_stop(data->sndHandle); free(data->mix_data); diff --git a/Alc/backends/solaris.c b/Alc/backends/solaris.c index b9288197..c6fd32e9 100644 --- a/Alc/backends/solaris.c +++ b/Alc/backends/solaris.c @@ -33,6 +33,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" #include @@ -43,11 +44,12 @@ static const char *solaris_driver = "/dev/audio"; typedef struct { int fd; - volatile int killNow; - ALvoid *thread; ALubyte *mix_data; int data_size; + + volatile int killNow; + althread_t thread; } solaris_data; @@ -208,8 +210,7 @@ static ALCboolean solaris_start_playback(ALCdevice *device) data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); data->mix_data = calloc(1, data->data_size); - data->thread = StartThread(SolarisProc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, SolarisProc, device)) { free(data->mix_data); data->mix_data = NULL; diff --git a/Alc/backends/wave.c b/Alc/backends/wave.c index ce827fe8..6245ef43 100644 --- a/Alc/backends/wave.c +++ b/Alc/backends/wave.c @@ -29,6 +29,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" typedef struct { @@ -39,7 +40,7 @@ typedef struct { ALuint size; volatile int killNow; - ALvoid *thread; + althread_t thread; } wave_data; @@ -288,8 +289,7 @@ static ALCboolean wave_start_playback(ALCdevice *device) return ALC_FALSE; } - data->thread = StartThread(WaveProc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, WaveProc, device)) { free(data->buffer); data->buffer = NULL; diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c index e003375c..5a64645b 100644 --- a/Alc/backends/winmm.c +++ b/Alc/backends/winmm.c @@ -29,6 +29,7 @@ #include "alMain.h" #include "alu.h" +#include "threads.h" #ifndef WAVE_FORMAT_IEEE_FLOAT #define WAVE_FORMAT_IEEE_FLOAT 0x0003 diff --git a/Alc/threads.c b/Alc/threads.c new file mode 100644 index 00000000..fd08b432 --- /dev/null +++ b/Alc/threads.c @@ -0,0 +1,152 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2007 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include "threads.h" + +#include + +#include "alMain.h" +#include "alThunk.h" + +#define THREAD_STACK_SIZE (1*1024*1024) /* 1MB */ + +#ifdef _WIN32 + +typedef struct althread_info { + ALuint (*func)(ALvoid*); + ALvoid *ptr; + HANDLE hdl; +} althread_info; + +static DWORD CALLBACK StarterFunc(void *ptr) +{ + althread_info *inf = (althread_info*)ptr; + ALuint ret; + + ret = inf->func(inf->ptr); + ExitThread((DWORD)ret); + + return (DWORD)ret; +} + + +ALboolean StartThread(althread_t *thread, ALuint (*func)(ALvoid*), ALvoid *ptr) +{ + althread_info *info; + DWORD dummy; + + info = malloc(sizeof(*info)); + if(!info) return AL_FALSE; + + info->func = func; + info->ptr = ptr; + + info->hdl = CreateThread(NULL, THREAD_STACK_SIZE, StarterFunc, info, 0, &dummy); + if(!info->hdl) + { + free(info); + return AL_FALSE; + } + + *thread = info; + return AL_TRUE; +} + +ALuint StopThread(althread_t thread) +{ + DWORD ret = 0; + + WaitForSingleObject(thread->hdl, INFINITE); + GetExitCodeThread(thread->hdl, &ret); + CloseHandle(thread->hdl); + + free(thread); + + return (ALuint)ret; +} + +#else + +#include + +typedef struct althread_info { + ALuint (*func)(ALvoid*); + ALvoid *ptr; + ALuint ret; + pthread_t hdl; +} althread_info; + +static void *StarterFunc(void *ptr) +{ + althread_info *inf = (althread_info*)ptr; + inf->ret = inf->func(inf->ptr); + return NULL; +} + + +ALboolean StartThread(althread_t *thread, ALuint (*func)(ALvoid*), ALvoid *ptr) +{ + pthread_attr_t attr; + althread_info *info; + + info = malloc(sizeof(*info)); + if(!info) return AL_FALSE; + + if(pthread_attr_init(&attr) != 0) + { + free(info); + return AL_FALSE; + } + if(pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE) != 0) + { + pthread_attr_destroy(&attr); + free(info); + return AL_FALSE; + } + + info->func = func; + info->ptr = ptr; + if(pthread_create(&info->hdl, &attr, StarterFunc, info) != 0) + { + pthread_attr_destroy(&attr); + free(info); + return AL_FALSE; + } + pthread_attr_destroy(&attr); + + *thread = info; + return AL_TRUE; +} + +ALuint StopThread(althread_t thread) +{ + ALuint ret; + + pthread_join(thread->hdl, NULL); + ret = thread->ret; + + free(thread); + + return ret; +} + +#endif diff --git a/CMakeLists.txt b/CMakeLists.txt index f9efda81..3346b0e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -489,7 +489,6 @@ SET(ALC_OBJS Alc/ALc.c Alc/ALu.c Alc/alcConfig.c Alc/alcRing.c - Alc/alcThread.c Alc/bs2b.c Alc/effects/autowah.c Alc/effects/chorus.c @@ -505,6 +504,7 @@ SET(ALC_OBJS Alc/ALc.c Alc/helpers.c Alc/hrtf.c Alc/panning.c + Alc/threads.c Alc/mixer.c Alc/mixer_c.c ) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 95146c1b..bfe575bd 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -815,10 +815,6 @@ typedef struct { void SetMixerFPUMode(FPUCtl *ctl); void RestoreFPUMode(const FPUCtl *ctl); -ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr); -ALuint StopThread(ALvoid *thread); - -void SetThreadName(const char *name); typedef struct RingBuffer RingBuffer; RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length); diff --git a/OpenAL32/Include/threads.h b/OpenAL32/Include/threads.h new file mode 100644 index 00000000..26493101 --- /dev/null +++ b/OpenAL32/Include/threads.h @@ -0,0 +1,14 @@ +#ifndef AL_THREADS_H +#define AL_THREADS_H + +#include "alMain.h" + +struct althread_info; +typedef struct althread_info* althread_t; + +ALboolean StartThread(althread_t *out, ALuint (*func)(ALvoid*), ALvoid *ptr); +ALuint StopThread(althread_t thread); + +void SetThreadName(const char *name); + +#endif /* AL_THREADS_H */ -- cgit v1.2.3