ericw-tools/common/threads.cc

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