netgen/libsrc/general/parthreads.hpp

145 lines
2.7 KiB
C++
Raw Normal View History

2009-01-13 04:40:13 +05:00
#ifndef FILE_PARTHREADS
#define FILE_PARTHREADS
/**************************************************************************/
/* File: parthreads.hh */
/* Author: Joachim Schoeberl */
/* Date: 22. Nov. 2000 */
/**************************************************************************/
/*
Parallel thread, Mutex,
*/
#include <functional>
2009-01-13 04:40:13 +05:00
2009-07-20 14:36:36 +06:00
namespace netgen
{
2009-01-13 04:40:13 +05:00
#ifdef NO_PARALLEL_THREADS
class NgMutex { };
class NgLock
{
public:
NgLock (NgMutex & mut, bool lock = 0) { ; }
void Lock () { ; }
void UnLock () { ; }
};
#else
2016-02-24 00:23:48 +05:00
typedef std::mutex NgMutex;
class NgLock
{
2016-02-24 00:23:48 +05:00
NgMutex & mut;
bool locked;
public:
NgLock (NgMutex & ngmut, bool lock = false)
2016-02-24 00:23:48 +05:00
: mut (ngmut)
{
if (lock)
2016-02-24 00:23:48 +05:00
mut.lock();
locked = lock;
};
~NgLock()
{
if (locked)
2016-02-24 00:23:48 +05:00
mut.unlock();
}
void Lock ()
{
2016-02-24 00:23:48 +05:00
mut.lock();
locked = true;
}
void UnLock ()
{
2016-02-24 00:23:48 +05:00
mut.unlock();
locked = false;
}
/*
int TryLock ()
{
2016-02-24 00:23:48 +05:00
return mut.try_lock();
}
*/
};
2009-01-13 04:40:13 +05:00
#endif
2016-02-22 22:43:51 +05:00
// 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] ()
2016-02-22 22:43:51 +05:00
{
f(myfirst, mynext);
});
}
for (int i=0; i<nthreads; i++)
threads[i].join();
delete [] threads;
}
2018-01-04 17:00:01 +05:00
template<typename T>
inline atomic<T> & AsAtomic (T & d)
{
return reinterpret_cast<atomic<T>&> (d);
}
typedef void (*TaskManager)(std::function<void(int,int)>);
2018-01-04 14:43:22 +05:00
typedef void (*Tracer)(string, bool); // false .. start, true .. stop
inline void DummyTaskManager (std::function<void(int,int)> func)
{
func(0,2);
func(1,2);
}
2018-01-04 14:43:22 +05:00
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);
});
}
2009-07-20 14:36:36 +06:00
}
2009-01-13 04:40:13 +05:00
#endif