netgen/libsrc/general/parthreads.hpp
2018-01-04 13:00:01 +01:00

145 lines
2.7 KiB
C++

#ifndef FILE_PARTHREADS
#define FILE_PARTHREADS
/**************************************************************************/
/* File: parthreads.hh */
/* Author: Joachim Schoeberl */
/* Date: 22. Nov. 2000 */
/**************************************************************************/
/*
Parallel thread, Mutex,
*/
#include <functional>
namespace netgen
{
#ifdef NO_PARALLEL_THREADS
class NgMutex { };
class NgLock
{
public:
NgLock (NgMutex & mut, bool lock = 0) { ; }
void Lock () { ; }
void UnLock () { ; }
};
#else
typedef std::mutex NgMutex;
class NgLock
{
NgMutex & mut;
bool locked;
public:
NgLock (NgMutex & ngmut, bool lock = false)
: mut (ngmut)
{
if (lock)
mut.lock();
locked = lock;
};
~NgLock()
{
if (locked)
mut.unlock();
}
void Lock ()
{
mut.lock();
locked = true;
}
void UnLock ()
{
mut.unlock();
locked = false;
}
/*
int TryLock ()
{
return mut.try_lock();
}
*/
};
#endif
// Simple ParallelFor function to replace OpenMP
template<typename TFunc>
void ParallelFor( int first, int next, const TFunc & f )
{
int nthreads = thread::hardware_concurrency();
thread * threads = new thread[nthreads];
for (int i=0; i<nthreads; i++)
{
int myfirst = first + (next-first)*i/nthreads;
int mynext = first + (next-first)*(i+1)/nthreads;
threads[i] = std::thread( [myfirst,mynext,&f] ()
{
f(myfirst, mynext);
});
}
for (int i=0; i<nthreads; i++)
threads[i].join();
delete [] threads;
}
template<typename T>
inline atomic<T> & AsAtomic (T & d)
{
return reinterpret_cast<atomic<T>&> (d);
}
typedef void (*TaskManager)(std::function<void(int,int)>);
typedef void (*Tracer)(string, bool); // false .. start, true .. stop
inline void DummyTaskManager (std::function<void(int,int)> func)
{
func(0,2);
func(1,2);
}
inline void DummyTracer (string, bool) { ; }
template <typename FUNC>
inline void ParallelFor (TaskManager tm, size_t n, FUNC func)
{
(*tm) ([n,func] (size_t nr, size_t nums)
{
size_t begin = nr*n / nums;
size_t end = (nr+1)*n / nums;
for (size_t i = begin; i < end; i++)
func(i);
});
}
template <typename FUNC>
inline void ParallelForRange (TaskManager tm, size_t n, FUNC func)
{
(*tm) ([n,func] (size_t nr, size_t nums)
{
size_t begin = nr*n / nums;
size_t end = (nr+1)*n / nums;
func(begin, end);
});
}
}
#endif