From 4a59ea59930ecb24d80574818d58bacd3c05b6ba Mon Sep 17 00:00:00 2001 From: TimeServ Date: Sun, 3 Jul 2011 16:24:53 +0000 Subject: [PATCH] make threaded physics/input/whatever use generic mutex calls, fix up multithread calls and add sleep func git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3844 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_input.c | 144 +++++------------------------------- engine/client/sys_linux.c | 7 +- engine/client/sys_morphos.c | 4 +- engine/client/sys_plugfte.c | 2 +- engine/client/sys_sdl.c | 7 +- engine/client/sys_win.c | 11 +-- engine/common/sys.h | 12 +-- engine/gl/gl_model.c | 2 +- engine/http/httpclient.c | 2 +- engine/server/sv_sql.c | 2 +- engine/server/sv_sys_unix.c | 7 +- engine/server/sv_sys_win.c | 7 +- 12 files changed, 62 insertions(+), 145 deletions(-) diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 712e4a167..456f3c478 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -1008,108 +1008,9 @@ void CL_FlushClientCommands(void) } qboolean runningindepphys; -#ifdef _WIN32 -CRITICAL_SECTION indepcriticialsection; -HANDLE indepphysicsthread; -void CL_AllowIndependantSendCmd(qboolean allow) -{ - if (!runningindepphys) - return; - - if (allowindepphys != allow && runningindepphys) - { - if (allow) - LeaveCriticalSection(&indepcriticialsection); - else - EnterCriticalSection(&indepcriticialsection); - allowindepphys = allow; - } -} - -unsigned long _stdcall CL_IndepPhysicsThread(void *param) -{ - int sleeptime; - float fps; - unsigned int time, lasttime; - float spare; - lasttime = Sys_Milliseconds(); - while(1) - { - time = Sys_Milliseconds(); - spare = CL_FilterTime((time - lasttime), cl_netfps.value, false); - if (spare) - { - //don't let them bank too much and get sudden bursts - if (spare > 15) - spare = 15; - - time -= spare; - EnterCriticalSection(&indepcriticialsection); - if (cls.state) - { - Sys_SendKeyEvents(); - CL_SendCmd(time - lasttime, false); - } - lasttime = time; - LeaveCriticalSection(&indepcriticialsection); - } - - fps = cl_netfps.value; - if (fps < 4) - fps = 4; - while (fps < 100) - fps*=2; - - sleeptime = 1000/fps; - - if (sleeptime) - Sleep(sleeptime); - else - Sleep(1); - } -} - -void CL_UseIndepPhysics(qboolean allow) -{ - if (runningindepphys == allow) - return; - - if (allow) - { //enable it - DWORD tid; //*sigh*... - -// TIMECAPS tc; -// timeGetDevCaps(&tc, sizeof(TIMECAPS)); -// Con_Printf("Timer has a resolution of %i millisecond%s\n", tc.wPeriodMin, tc.wPeriodMin!=1?"s":""); - - InitializeCriticalSection(&indepcriticialsection); - runningindepphys = true; - - indepphysicsthread = CreateThread(NULL, 8192, CL_IndepPhysicsThread, NULL, 0, &tid); - allowindepphys = 1; - - SetThreadPriority(independantphysics, HIGH_PRIORITY_CLASS); - } - else - { - //shut it down. - - EnterCriticalSection(&indepcriticialsection); - TerminateThread(indepphysicsthread, 0); - CloseHandle(indepphysicsthread); - LeaveCriticalSection(&indepcriticialsection); - DeleteCriticalSection(&indepcriticialsection); - - runningindepphys = false; - } -} - -#elif defined(__linux__) - -#include - -pthread_mutex_t indepcriticalsection; -pthread_t indepphysicsthread; +#ifdef MULTITHREAD +void *indeplock; +void *indepthread; void CL_AllowIndependantSendCmd(qboolean allow) { @@ -1119,16 +1020,16 @@ void CL_AllowIndependantSendCmd(qboolean allow) if (allowindepphys != allow && runningindepphys) { if (allow) - pthread_mutex_unlock(&indepcriticalsection); + Sys_UnlockMutex(&indeplock); else - pthread_mutex_lock(&indepcriticalsection); + Sys_LockMutex(&indeplock); allowindepphys = allow; } } -void *CL_IndepPhysicsThread(void *param) +int CL_IndepPhysicsThread(void *param) { - int sleeptime; + unsigned int sleeptime; double fps; double time, lasttime; double spare; @@ -1144,11 +1045,11 @@ void *CL_IndepPhysicsThread(void *param) spare = 15; time -= spare/1000.0f; - pthread_mutex_lock(&indepcriticalsection); + Sys_LockMutex(&indeplock); if (cls.state) CL_SendCmd(time - lasttime, false); lasttime = time; - pthread_mutex_unlock(&indepcriticalsection); + Sys_UnlockMutex(&indeplock); } fps = cl_netfps.value; @@ -1159,12 +1060,9 @@ void *CL_IndepPhysicsThread(void *param) sleeptime = (1000*1000)/fps; - if (sleeptime) - usleep(sleeptime); - else - usleep(1); + Sys_Sleep(sleeptime); } - return NULL; + return 0; } void CL_UseIndepPhysics(qboolean allow) @@ -1174,26 +1072,20 @@ void CL_UseIndepPhysics(qboolean allow) if (allow) { //enable it - pthread_mutex_init(&indepcriticalsection, NULL); + indeplock = Sys_CreateMutex(); runningindepphys = true; - pthread_create(&indepphysicsthread, NULL, CL_IndepPhysicsThread, NULL); - allowindepphys = 1; - - //now this would be awesome, but would require root permissions... which is plain wrong! - //however, lack of this line means its really duel-core only. - //pthread_setschedparam(indepthread, SCHED_*, ?); - //is there anything to weight the thread up a bit against the main thread? (considering that most of the time we'll be idling) + indepthread = Sys_CreateThread(CL_IndepPhysicsThread, NULL, THREADP_HIGHEST, 8192); + allowindepphys = true; } else { //shut it down. runningindepphys = false; //tell thread to exit gracefully - - pthread_mutex_lock(&indepcriticalsection); - pthread_join(indepphysicsthread, 0); - pthread_mutex_unlock(&indepcriticalsection); - pthread_mutex_destroy(&indepcriticalsection); + Sys_LockMutex(indeplock); + Sys_WaitOnThread(indepthread); + Sys_UnlockMutex(indeplock); + Sys_DestroyMutex(indeplock); } } #else diff --git a/engine/client/sys_linux.c b/engine/client/sys_linux.c index 212b8c3f9..6df598f9a 100644 --- a/engine/client/sys_linux.c +++ b/engine/client/sys_linux.c @@ -738,7 +738,7 @@ void Sys_SaveClipboard(char *text) { /* Thread creation calls */ typedef void *(*pfunction_t)(void *); -void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize) { pthread_t *thread; pthread_attr_t attr; @@ -878,4 +878,9 @@ void Sys_DestroyConditional(void *condv) free(cv->mutex); free(cv); } + +void Sys_Sleep (unsigned int microseconds) +{ + usleep(microseconds); +} #endif diff --git a/engine/client/sys_morphos.c b/engine/client/sys_morphos.c index 876a1cd63..89e846b60 100755 --- a/engine/client/sys_morphos.c +++ b/engine/client/sys_morphos.c @@ -480,7 +480,7 @@ void Sys_LowFPPrecision (void) #ifdef MULTITHREAD /* Everything here is stubbed because I don't know MorphOS */ /* Thread creation calls */ -void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) { return NULL; } +void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize) { return NULL; } void Sys_WaitOnThread(void *thread) {} /* Mutex calls */ void *Sys_CreateMutex(void) { return NULL; } @@ -496,4 +496,6 @@ qboolean Sys_ConditionWait(void *condv) { return false; } qboolean Sys_ConditionSignal(void *condv) { return false; } qboolean Sys_ConditionBroadcast(void *condv) { return false; } void Sys_DestroyConditional(void *condv) {} + +void Sys_Sleep(int microseconds) {} #endif diff --git a/engine/client/sys_plugfte.c b/engine/client/sys_plugfte.c index dfc7f5de2..06fa72928 100644 --- a/engine/client/sys_plugfte.c +++ b/engine/client/sys_plugfte.c @@ -439,7 +439,7 @@ qboolean Plug_StartContext(struct context *ctx) ctx->pub.running = true; activecontext = ctx; ctx->mutex = Sys_CreateMutex(); - ctx->thread = Sys_CreateThread(Plug_PluginThread, ctx, 0); + ctx->thread = Sys_CreateThread(Plug_PluginThread, ctx, THREADP_NORMAL, 0); return true; } diff --git a/engine/client/sys_sdl.c b/engine/client/sys_sdl.c index bbb02f87f..577d85d87 100644 --- a/engine/client/sys_sdl.c +++ b/engine/client/sys_sdl.c @@ -584,7 +584,7 @@ void Sys_SaveClipboard(char *text) #ifdef MULTITHREAD /* Thread creation calls */ -void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize) { // SDL threads do not support setting thread stack size return (void *)SDL_CreateThread(func, args); @@ -693,5 +693,10 @@ void Sys_DestroyConditional(void *condv) SDL_DestroyMutex(cv->mutex); free(cv); } + +void Sys_Sleep (unsigned int microseconds) +{ + SDL_Delay(microseconds / 1000000); +} #endif diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 808b06408..6fd0826fb 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -1087,10 +1087,6 @@ void Sys_CloseTerminal (void) // //////////////////////////// -void Sys_Sleep (void) -{ -} - void Sys_SendKeyEvents (void) { MSG msg; @@ -1834,7 +1830,7 @@ DWORD WINAPI threadwrapper(void *args) return 0; } -void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize) { threadwrap_t *tw = (threadwrap_t *)malloc(sizeof(threadwrap_t)); HANDLE handle; @@ -2054,4 +2050,9 @@ void Sys_DestroyConditional(void *condv) DeleteCriticalSection(&cv->mainlock); free(cv); } + +void Sys_Sleep (unsigned int microseconds) +{ + Sleep(microseconds / 1000000); +} #endif diff --git a/engine/common/sys.h b/engine/common/sys.h index f814c9ae6..63b4260b2 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -75,10 +75,6 @@ void Sys_CloseTerminal (void); qboolean Sys_InitTerminal (void); void Con_PrintToSys(void); -void Sys_Sleep (void); -// called to yield for a little bit so as -// not to hog cpu when paused or debugging - void Sys_ServerActivity(void); //make window flash on the taskbar - someone said something/connected @@ -90,9 +86,13 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate); #ifdef MULTITHREAD -void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize); +void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize); void Sys_WaitOnThread(void *thread); +#define THREADP_IDLE -5 +#define THREADP_NORMAL 0 +#define THREADP_HIGHEST 5 + void *Sys_CreateMutex(void); qboolean Sys_TryLockMutex(void *mutex); qboolean Sys_LockMutex(void *mutex); @@ -107,6 +107,8 @@ qboolean Sys_ConditionWait(void *condv); qboolean Sys_ConditionSignal(void *condv); qboolean Sys_ConditionBroadcast(void *condv); void Sys_DestroyConditional(void *condv); + +void Sys_Sleep(unsigned int microseconds); #endif #ifdef NPQTV diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 7bc27e366..76dd1b827 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -240,7 +240,7 @@ void RMod_Think (void) relightthreads = sizeof(relightthread)/sizeof(relightthread[0]); wantrelight = true; for (i = 0; i < relightthreads; i++) - relightthread[i] = Sys_CreateThread(RelightThread, lightmodel, 0); + relightthread[i] = Sys_CreateThread(RelightThread, lightmodel, THREADP_NORMAL, 0); } #else LightFace(relitsurface); diff --git a/engine/http/httpclient.c b/engine/http/httpclient.c index 2a83c54bb..ec87ff572 100644 --- a/engine/http/httpclient.c +++ b/engine/http/httpclient.c @@ -503,7 +503,7 @@ qboolean DL_CreateThread(struct dl_download *dl, vfsfile_t *file, void (*NotifyF dl->file = file; dl->notify = NotifyFunction; - dl->threadctx = Sys_CreateThread(DL_Thread_Work, dl, 0); + dl->threadctx = Sys_CreateThread(DL_Thread_Work, dl, THREADP_NORMAL, 0); if (!dl->threadctx) return false; diff --git a/engine/server/sv_sql.c b/engine/server/sv_sql.c index fec42845d..d99835d04 100644 --- a/engine/server/sv_sql.c +++ b/engine/server/sv_sql.c @@ -476,7 +476,7 @@ int SQL_NewServer(char *driver, char **paramstr) return -1; } - server->thread = Sys_CreateThread(sql_serverworker, (void *)server, 1024); + server->thread = Sys_CreateThread(sql_serverworker, (void *)server, THREADP_NORMAL, 1024); if (!server->thread) { diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c index 99cae017f..93f3a8170 100644 --- a/engine/server/sv_sys_unix.c +++ b/engine/server/sv_sys_unix.c @@ -909,7 +909,7 @@ void Sys_ServerActivity(void) /* Thread creation calls */ typedef void *(*pfunction_t)(void *); -void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize) { pthread_t *thread; pthread_attr_t attr; @@ -1049,5 +1049,10 @@ void Sys_DestroyConditional(void *condv) free(cv->mutex); free(cv); } + +void Sys_Sleep (unsigned int microseconds) +{ + usleep(microseconds); +} #endif diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index a43e961d3..281e942ec 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -1428,7 +1428,7 @@ DWORD WINAPI threadwrapper(void *args) return 0; } -void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize) { threadwrap_t *tw = (threadwrap_t *)malloc(sizeof(threadwrap_t)); HANDLE handle; @@ -1634,6 +1634,11 @@ void Sys_DestroyConditional(void *condv) DeleteCriticalSection(&cv->mainlock); free(cv); } + +void Sys_Sleep (unsigned int microseconds) +{ + Sleep(microseconds / 1000000); +} #endif #endif