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.
This commit is contained in:
Volker Ruppert 2015-01-17 19:53:03 +00:00
parent dd56a4d1d3
commit 3dca0bd8cf
4 changed files with 52 additions and 76 deletions

View File

@ -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 */

View File

@ -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)

View File

@ -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,

View File

@ -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;