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
This commit is contained in:
TimeServ 2011-07-03 16:24:53 +00:00
parent fbec99ff9f
commit 4a59ea5993
12 changed files with 62 additions and 145 deletions

View file

@ -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.h>
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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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