📄 l_threads.c
字号:
if (enter)
Error("Recursive ThreadLock\n");
enter = 1;
} //end of the function ThreadLock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadUnlock(void)
{
if (!threaded)
{
Error("ThreadUnlock: !threaded");
return;
} //end if
if (!enter)
Error("ThreadUnlock without lock\n");
enter = 0;
if (my_mutex)
{
pthread_mutex_unlock(my_mutex);
} //end if
} //end of the function ThreadUnlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadSetupLock(void)
{
pthread_mutexattr_t mattrib;
Log_Print("pthread multi-threading\n");
if (!my_mutex)
{
my_mutex = GetMemory(sizeof(*my_mutex));
if (pthread_mutexattr_create (&mattrib) == -1)
Error ("pthread_mutex_attr_create failed");
if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
Error ("pthread_mutexattr_setkind_np failed");
if (pthread_mutex_init (my_mutex, mattrib) == -1)
Error ("pthread_mutex_init failed");
}
if (pthread_attr_create (&attrib) == -1)
Error ("pthread_attr_create failed");
if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
Error ("pthread_attr_setstacksize failed");
threaded = true;
currentnumthreads = 0;
currentthreadid = 0;
} //end of the function ThreadInitLock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadShutdownLock(void)
{
threaded = false;
} //end of the function ThreadShutdownLock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void RunThreadsOn(int workcnt, qboolean showpacifier, void(*func)(int))
{
int i;
pthread_t work_threads[MAX_THREADS];
pthread_addr_t status;
pthread_attr_t attrib;
pthread_mutexattr_t mattrib;
int start, end;
Log_Print("pthread multi-threading\n");
start = I_FloatTime ();
dispatch = 0;
workcount = workcnt;
oldf = -1;
pacifier = showpacifier;
threaded = true;
if (numthreads < 1 || numthreads > MAX_THREADS) numthreads = 1;
if (pacifier)
setbuf (stdout, NULL);
if (!my_mutex)
{
my_mutex = GetMemory(sizeof(*my_mutex));
if (pthread_mutexattr_create (&mattrib) == -1)
Error ("pthread_mutex_attr_create failed");
if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
Error ("pthread_mutexattr_setkind_np failed");
if (pthread_mutex_init (my_mutex, mattrib) == -1)
Error ("pthread_mutex_init failed");
}
if (pthread_attr_create (&attrib) == -1)
Error ("pthread_attr_create failed");
if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
Error ("pthread_attr_setstacksize failed");
for (i=0 ; i<numthreads ; i++)
{
if (pthread_create(&work_threads[i], attrib
, (pthread_startroutine_t)func, (pthread_addr_t)i) == -1)
Error ("pthread_create failed");
}
for (i=0 ; i<numthreads ; i++)
{
if (pthread_join (work_threads[i], &status) == -1)
Error ("pthread_join failed");
}
threaded = false;
end = I_FloatTime ();
if (pacifier)
printf (" (%i)\n", end-start);
} //end of the function RunThreadsOn
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AddThread(void (*func)(int))
{
thread_t *thread;
if (numthreads == 1)
{
if (currentnumthreads >= numthreads) return;
currentnumthreads++;
func(-1);
currentnumthreads--;
} //end if
else
{
ThreadLock();
if (currentnumthreads >= numthreads)
{
ThreadUnlock();
return;
} //end if
//allocate new thread
thread = GetMemory(sizeof(thread_t));
if (!thread) Error("can't allocate memory for thread\n");
//
thread->threadid = currentthreadid;
if (pthread_create(&thread->thread, attrib, (pthread_startroutine_t)func, (pthread_addr_t)thread->threadid) == -1)
Error ("pthread_create failed");
//add the thread to the end of the list
thread->next = NULL;
if (lastthread) lastthread->next = thread;
else firstthread = thread;
lastthread = thread;
//
#ifdef THREAD_DEBUG
qprintf("added thread with id %d\n", thread->threadid);
#endif //THREAD_DEBUG
//
currentnumthreads++;
currentthreadid++;
//
ThreadUnlock();
} //end else
} //end of the function AddThread
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void RemoveThread(int threadid)
{
thread_t *thread, *last;
//if a single thread
if (threadid == -1) return;
//
ThreadLock();
last = NULL;
for (thread = firstthread; thread; thread = thread->next)
{
if (thread->threadid == threadid)
{
if (last) last->next = thread->next;
else firstthread = thread->next;
if (!thread->next) lastthread = last;
//
FreeMemory(thread);
currentnumthreads--;
#ifdef THREAD_DEBUG
qprintf("removed thread with id %d\n", threadid);
#endif //THREAD_DEBUG
break;
} //end if
last = thread;
} //end if
if (!thread) Error("couldn't find thread with id %d", threadid);
ThreadUnlock();
} //end of the function RemoveThread
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void WaitForAllThreadsFinished(void)
{
pthread_t *thread;
pthread_addr_t status;
ThreadLock();
while(firstthread)
{
thread = &firstthread->thread;
ThreadUnlock();
if (pthread_join(*thread, &status) == -1)
Error("pthread_join failed");
ThreadLock();
} //end while
ThreadUnlock();
} //end of the function WaitForAllThreadsFinished
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int GetNumThreads(void)
{
return currentnumthreads;
} //end of the function GetNumThreads
#endif
//===================================================================
//
// LINUX
//
//===================================================================
#if defined(LINUX)
#define USED
#include <pthread.h>
#include <semaphore.h>
typedef struct thread_s
{
pthread_t thread;
int threadid;
int id;
struct thread_s *next;
} thread_t;
thread_t *firstthread;
thread_t *lastthread;
int currentnumthreads;
int currentthreadid;
int numthreads = 1;
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_attr_t attrib;
sem_t semaphore;
static int enter;
static int numwaitingthreads = 0;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadSetDefault(void)
{
if (numthreads == -1) // not set manually
{
numthreads = 1;
} //end if
qprintf("%i threads\n", numthreads);
} //end of the function ThreadSetDefault
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadLock(void)
{
if (!threaded)
{
Error("ThreadLock: !threaded");
return;
} //end if
pthread_mutex_lock(&my_mutex);
if (enter)
Error("Recursive ThreadLock\n");
enter = 1;
} //end of the function ThreadLock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadUnlock(void)
{
if (!threaded)
{
Error("ThreadUnlock: !threaded");
return;
} //end if
if (!enter)
Error("ThreadUnlock without lock\n");
enter = 0;
pthread_mutex_unlock(&my_mutex);
} //end of the function ThreadUnlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadSetupLock(void)
{
pthread_mutexattr_t mattrib;
Log_Print("pthread multi-threading\n");
threaded = true;
currentnumthreads = 0;
currentthreadid = 0;
} //end of the function ThreadInitLock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadShutdownLock(void)
{
threaded = false;
} //end of the function ThreadShutdownLock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadSetupSemaphore(void)
{
sem_init(&semaphore, 0, 0);
} //end of the function ThreadSetupSemaphore
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadShutdownSemaphore(void)
{
sem_destroy(&semaphore);
} //end of the function ThreadShutdownSemaphore
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadSemaphoreWait(void)
{
sem_wait(&semaphore);
} //end of the function ThreadSemaphoreWait
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ThreadSemaphoreIncrease(int count)
{
int i;
for (i = 0; i < count; i++)
{
sem_post(&semaphore);
} //end for
} //end of the function ThreadSemaphoreIncrease
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void RunThreadsOn(int workcnt, qboolean showpacifier, void(*func)(int))
{
int i;
pthread_t work_threads[MAX_THREADS];
void *pthread_return;
pthread_attr_t attrib;
pthread_mutexattr_t mattrib;
int start, end;
Log_Print("pthread multi-threading\n");
start = I_FloatTime ();
dispatch = 0;
workcount = workcnt;
oldf = -1;
pacifier = showpacifier;
threaded = true;
if (numthreads < 1 || numthreads > MAX_THREADS) numthreads = 1;
if (pacifier)
setbuf (stdout, NULL);
for (i=0 ; i<numthreads ; i++)
{
if (pthread_create(&work_threads[i], NULL, (void *)func, (void *)i) == -1)
Error ("pthread_create failed");
}
for (i=0 ; i<numthreads ; i++)
{
if (pthread_join(work_threads[i], &pthread_return) == -1)
Error ("pthread_join failed");
}
threaded = false;
end = I_FloatTime ();
if (pacifier)
printf (" (%i)\n", end-start);
} //end of the function RunThreadsOn
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AddThread(void (*func)(int))
{
thread_t *thread;
if (numthreads == 1)
{
if (currentnumthreads >= numthreads) return;
currentnumthreads++;
func(-1);
currentnumthreads--;
} //end if
else
{
ThreadLock();
if (currentnumthreads >= numthreads)
{
ThreadUnlock();
return;
} //end if
//allocate new thread
thread = GetMemory(sizeof(thread_t));
if (!thread) Error("can't allocate memory for thread\n");
//
thread->threadid = currentthreadid;
if (pthread_create(&thread->thread, NULL, (void *)func, (void *)thread->threadid) == -1)
Error ("pthread_create failed");
//add the thread to the end of the list
thread->next = NULL;
if (lastthread) lastthread->next = thread;
else firstthread = thread;
lastthread = thread;
//
#ifdef THREAD_DEBUG
qprintf("added thread with id %d\n", thread->threadid);
#endif //THREAD_DEBUG
//
currentnumthreads++;
currentthreadid++;
//
ThreadUnlock();
} //end else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -