From 3dca0bd8cf3acd46699a62a194f66ec480dd3a6c Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sat, 17 Jan 2015 19:53:03 +0000 Subject: [PATCH] Some work in the soundmod beep code and multithreading improvements. - Beep thread now only started one per simulation. - Added some more multithreading macros and use them in rfb, vncsrv and soundmod. - TODO: implement mixer thread and remove beep thread. --- bochs/bochs.h | 11 +++++ bochs/gui/rfb.cc | 24 +++-------- bochs/gui/vncsrv.cc | 13 +++--- bochs/iodev/sound/soundmod.cc | 80 +++++++++++++---------------------- 4 files changed, 52 insertions(+), 76 deletions(-) diff --git a/bochs/bochs.h b/bochs/bochs.h index c5a44cdf0..a62859643 100644 --- a/bochs/bochs.h +++ b/bochs/bochs.h @@ -602,17 +602,28 @@ BX_CPP_INLINE Bit64u bx_bswap64(Bit64u val64) // multithreading support #ifdef WIN32 +#define BX_THREAD_ID(id) DWORD (id) +#define BX_THREAD_FUNC(name,arg) DWORD WINAPI name(LPVOID arg) +#define BX_THREAD_EXIT return 0 +#define BX_THREAD_CREATE(name,arg,id) CreateThread(NULL, 0, name, arg, 0, &(id)) #define BX_LOCK(mutex) EnterCriticalSection(&(mutex)) #define BX_UNLOCK(mutex) LeaveCriticalSection(&(mutex)) #define BX_MUTEX(mutex) CRITICAL_SECTION (mutex) #define BX_INIT_MUTEX(mutex) InitializeCriticalSection(&(mutex)) #define BX_FINI_MUTEX(mutex) DeleteCriticalSection(&(mutex)) +#define BX_MSLEEP(val) msleep(val) #else +#define BX_THREAD_ID(id) pthread_t (id) +#define BX_THREAD_FUNC(name,arg) void name(void* arg) +#define BX_THREAD_EXIT pthread_exit(NULL) +#define BX_THREAD_CREATE(name,arg,id) \ + pthread_create(&(id), NULL, (void *(*)(void *))&(name), arg) #define BX_LOCK(mutex) pthread_mutex_lock(&(mutex)); #define BX_UNLOCK(mutex) pthread_mutex_unlock(&(mutex)); #define BX_MUTEX(mutex) pthread_mutex_t (mutex) #define BX_INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL) #define BX_FINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex)) +#define BX_MSLEEP(val) usleep(val*1000) #endif #endif /* BX_BOCHS_H */ diff --git a/bochs/gui/rfb.cc b/bochs/gui/rfb.cc index 36663a833..75fc9d842 100644 --- a/bochs/gui/rfb.cc +++ b/bochs/gui/rfb.cc @@ -7,7 +7,7 @@ // Donald Becker // http://www.psyon.org // -// Copyright (C) 2001-2014 The Bochs Project +// Copyright (C) 2001-2015 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -884,11 +884,7 @@ bool StopWinsock() } #endif -#ifdef WIN32 -DWORD WINAPI rfbServerThreadInit(LPVOID) -#else -void CDECL rfbServerThreadInit(void *indata) -#endif +BX_THREAD_FUNC(rfbServerThreadInit, indata) { SOCKET sServer; SOCKET sClient; @@ -957,22 +953,14 @@ end_of_thread: #ifdef BX_RFB_WIN32 StopWinsock(); #endif -#ifdef WIN32 - return 0; -#else - return; -#endif + BX_THREAD_EXIT; } void rfbStartThread() { -#ifdef WIN32 - DWORD threadID; - CreateThread(NULL, 0, rfbServerThreadInit, NULL, 0, &threadID); -#else - pthread_t thread; - pthread_create(&thread, NULL, (void *(*)(void *))&rfbServerThreadInit, NULL); -#endif + BX_THREAD_ID(threadID); + + BX_THREAD_CREATE(rfbServerThreadInit, NULL, threadID); } void HandleRfbClient(SOCKET sClient) diff --git a/bochs/gui/vncsrv.cc b/bochs/gui/vncsrv.cc index 27900119d..fad47f583 100644 --- a/bochs/gui/vncsrv.cc +++ b/bochs/gui/vncsrv.cc @@ -893,7 +893,7 @@ void bx_vncsrv_gui_c::show_ips(Bit32u ips_count) // VNCSRV specific functions -void CDECL vncServerThreadInit(void *indata) +BX_THREAD_FUNC(vncServerThreadInit, indata) { /* this is the blocking event loop, i.e. it never returns */ /* 40000 are the microseconds to wait on select(), i.e. 0.04 seconds*/ @@ -904,17 +904,14 @@ void CDECL vncServerThreadInit(void *indata) rfbServerDown = true; - return; + BX_THREAD_EXIT; } void vncStartThread() { -#ifdef WIN32 - _beginthread(vncServerThreadInit, 0, NULL); -#else - pthread_t thread; - pthread_create(&thread, NULL, (void *(*)(void *))&vncServerThreadInit, NULL); -#endif + BX_THREAD_ID(threadID); + + BX_THREAD_CREATE(vncServerThreadInit, NULL, threadID); } void DrawBitmap(int x, int y, int width, int height, char *bmap, diff --git a/bochs/iodev/sound/soundmod.cc b/bochs/iodev/sound/soundmod.cc index 74292cf08..6875e8ddf 100644 --- a/bochs/iodev/sound/soundmod.cc +++ b/bochs/iodev/sound/soundmod.cc @@ -48,12 +48,15 @@ bx_soundmod_ctl_c* theSoundModCtl = NULL; +BX_THREAD_ID(threadID); +BX_MUTEX(beep_mutex); +static int beep_control; Bit8u *beep_buffer; unsigned int beep_bufsize; -BX_MUTEX(beep_mutex); bx_pcm_param_t beep_param; Bit32u beep_callback(void *dev, Bit16u rate, Bit8u *buffer, Bit32u len); +BX_THREAD_FUNC(beep_thread, indata); int CDECL libsoundmod_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[]) { @@ -79,7 +82,15 @@ bx_soundmod_ctl_c::bx_soundmod_ctl_c() bx_soundmod_ctl_c::~bx_soundmod_ctl_c() { - soundmod->unregister_wave_callback(beep_callback_id); + beep_active = 0; + if (beep_callback_id < 0) { + beep_control = 0; + while (beep_control >= 0) { + BX_MSLEEP(1); + } + } else { + soundmod->unregister_wave_callback(beep_callback_id); + } free(beep_buffer); if (soundmod != NULL) { soundmod->closewaveoutput(); @@ -142,6 +153,7 @@ void bx_soundmod_ctl_c::init() beep_param.bits = 16; beep_param.channels = 2; beep_param.format = 1; + BX_THREAD_CREATE(beep_thread, soundmod, threadID); } soundmod->startwaveplayback(44100, 16, 1, 1); } @@ -185,39 +197,27 @@ Bit32u beep_callback(void *dev, Bit16u rate, Bit8u *buffer, Bit32u len) return ((bx_soundmod_ctl_c*)dev)->beep_generator(rate, buffer, len); } -#ifdef WIN32 -DWORD threadID; -#else -pthread_t threadID; -#endif -Bit8u beep_control = 0; - -#ifdef WIN32 -DWORD WINAPI beep_thread(LPVOID indata) -#else -void beep_thread(void *indata) -#endif +BX_THREAD_FUNC(beep_thread, indata) { - int ret; + Bit32u len = 0; bx_sound_lowlevel_c *soundmod = (bx_sound_lowlevel_c*)indata; - while (beep_control == 2) { - theSoundModCtl->beep_generator(44100, beep_buffer, beep_bufsize); - ret = soundmod->sendwavepacket(beep_bufsize, beep_buffer, &beep_param); - if (ret == BX_SOUNDLOW_ERR) break; - if (soundmod->get_type() == BX_SOUNDLOW_WIN) { -#ifdef WIN32 - Sleep(25); -#endif + beep_control = 1; + while (beep_control > 0) { + len = theSoundModCtl->beep_generator(44100, beep_buffer, beep_bufsize); + if (len > 0) { + soundmod->sendwavepacket(beep_bufsize, beep_buffer, &beep_param); + if (soundmod->get_type() == BX_SOUNDLOW_WIN) { + BX_MSLEEP(25); + } else { + BX_MSLEEP(1); + } + } else { + BX_MSLEEP(25); } } - soundmod->stopwaveplayback(); - beep_control = 0; -#ifdef WIN32 - return 0; -#else - pthread_exit(NULL); -#endif + beep_control = -1; + BX_THREAD_EXIT; } bx_bool bx_soundmod_ctl_c::beep_on(float frequency) @@ -230,16 +230,6 @@ bx_bool bx_soundmod_ctl_c::beep_on(float frequency) beep_active = 1; BX_UNLOCK(beep_mutex); } - if (beep_callback_id < 0) { - if (beep_control != 2) { - beep_control = 2; -#ifdef WIN32 - CreateThread(NULL, 0, beep_thread, soundmod, 0, &threadID); -#else - pthread_create(&threadID, NULL, (void *(*)(void *))&beep_thread, soundmod); -#endif - } - } return 1; } return 0; @@ -253,16 +243,6 @@ bx_bool bx_soundmod_ctl_c::beep_off() beep_active = 0; beep_cur_freq = 0.0; BX_UNLOCK(beep_mutex); - if (beep_callback_id < 0) { - if (beep_control > 0) { - beep_control = 1; -#ifdef WIN32 - while (beep_control > 0) Sleep(1); -#else - pthread_join(threadID, NULL); -#endif - } - } return 1; } return 0;