172 lines
2.9 KiB
C++
172 lines
2.9 KiB
C++
/* common/threads.c */
|
|
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <thread>
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
#include <common/log.hh>
|
|
#include <common/threads.hh>
|
|
|
|
/* Make the locks no-ops if we aren't running threads */
|
|
static bool threads_active = false;
|
|
|
|
static int dispatch;
|
|
static int workcount;
|
|
static int oldpercent = -1;
|
|
|
|
/*
|
|
* =============
|
|
* GetThreadWork
|
|
* =============
|
|
*/
|
|
int GetThreadWork_Locked__(void)
|
|
{
|
|
int ret;
|
|
int percent;
|
|
|
|
if (dispatch == workcount)
|
|
return -1;
|
|
|
|
percent = 50 * dispatch / workcount;
|
|
while (oldpercent < percent) {
|
|
oldpercent++;
|
|
LogPrintLocked("{:c}", (oldpercent % 5) ? '.' : '0' + (oldpercent / 5));
|
|
}
|
|
|
|
ret = dispatch;
|
|
dispatch++;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int GetThreadWork(void)
|
|
{
|
|
int ret;
|
|
|
|
ThreadLock();
|
|
ret = GetThreadWork_Locked__();
|
|
ThreadUnlock();
|
|
|
|
return ret;
|
|
}
|
|
|
|
void InterruptThreadProgress__(void)
|
|
{
|
|
if (oldpercent != -1) {
|
|
LogPrintLocked("\\\n");
|
|
oldpercent = -1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ===================================================================
|
|
* WIN32
|
|
* ===================================================================
|
|
*/
|
|
|
|
#ifdef USE_WIN32THREADS
|
|
|
|
#include <windows.h>
|
|
#define HAVE_THREADS
|
|
|
|
void LowerProcessPriority()
|
|
{
|
|
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
|
|
}
|
|
|
|
#elif USE_PTHREADS
|
|
|
|
#define HAVE_THREADS
|
|
|
|
/* not implemented for now */
|
|
void LowerProcessPriority() { }
|
|
|
|
#else
|
|
|
|
void LowerProcessPriority(void) { }
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
int numthreads = 1;
|
|
std::mutex crit;
|
|
|
|
int GetDefaultThreads()
|
|
{
|
|
return std::thread::hardware_concurrency();
|
|
}
|
|
|
|
void ThreadLock()
|
|
{
|
|
if (threads_active)
|
|
crit.lock();
|
|
}
|
|
|
|
void ThreadUnlock()
|
|
{
|
|
if (threads_active)
|
|
crit.unlock();
|
|
}
|
|
|
|
/*
|
|
* =============
|
|
* RunThreadsOn
|
|
* =============
|
|
*/
|
|
void RunThreadsOn(int start, int workcnt, void *(func)(void *), void *arg)
|
|
{
|
|
std::vector<std::thread> threadhandle;
|
|
|
|
dispatch = start;
|
|
workcount = workcnt;
|
|
oldpercent = -1;
|
|
|
|
/* run threads in parallel */
|
|
threads_active = true;
|
|
|
|
for (int32_t i = 0; i < numthreads; i++)
|
|
threadhandle.emplace_back(func, arg);
|
|
|
|
for (int32_t i = 0; i < numthreads; i++)
|
|
threadhandle[i].join();
|
|
|
|
threads_active = false;
|
|
oldpercent = -1;
|
|
|
|
LogPrint("\n");
|
|
}
|
|
|
|
/*
|
|
* =======================================================================
|
|
* SINGLE THREAD
|
|
* =======================================================================
|
|
*/
|
|
|
|
#else
|
|
|
|
int numthreads = 1;
|
|
|
|
void ThreadLock(void) { }
|
|
void ThreadUnlock(void) { }
|
|
|
|
/*
|
|
* =============
|
|
* RunThreadsOn
|
|
* =============
|
|
*/
|
|
void RunThreadsOn(int start, int workcnt, void *(func)(void *), void *arg)
|
|
{
|
|
dispatch = start;
|
|
workcount = workcnt;
|
|
oldpercent = -1;
|
|
|
|
func(arg);
|
|
|
|
LogPrint("\n");
|
|
}
|
|
|
|
#endif /* HAVE_THREADS */
|