Assignments
Assignments
threads.h
Go to the documentation of this file.
1/*
2Copyright (c) 2017, Michael Kazhdan
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without modification,
6are permitted provided that the following conditions are met:
7
8Redistributions of source code must retain the above copyright notice, this list of
9conditions and the following disclaimer. Redistributions in binary form must reproduce
10the above copyright notice, this list of conditions and the following disclaimer
11in the documentation and/or other materials provided with the distribution.
12
13Neither the name of the Johns Hopkins University nor the names of its contributors
14may be used to endorse or promote products derived from this software without specific
15prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
18EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES
19OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
20SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE.
27*/
28
29#ifndef THREADS_INCLUDED
30#define THREADS_INCLUDED
31
32#include <thread>
33#include <mutex>
34#include <vector>
35#include <atomic>
36#include <condition_variable>
37#include <functional>
38#include <chrono>
39#include <future>
40#ifdef _OPENMP
41#include <omp.h>
42#endif // _OPENMP
43#include "exceptions.h"
44
45#define OLD_ATOMICS
46
48#ifdef OLD_ATOMICS
49#if defined( _WIN32 ) || defined( _WIN64 )
50#include <windows.h>
51#endif // _WIN32 || _WIN64
52template< typename Value >
53bool SetAtomic32( volatile Value *value , Value newValue , Value oldValue )
54{
55#if defined( _WIN32 ) || defined( _WIN64 )
56 long &_oldValue = *(long *)&oldValue;
57 long &_newValue = *(long *)&newValue;
58 return InterlockedCompareExchange( (long*)value , _newValue , _oldValue )==_oldValue;
59#else // !_WIN32 && !_WIN64
60 uint32_t &_oldValue = *(uint32_t *)&oldValue;
61 uint32_t &_newValue = *(uint32_t *)&newValue;
62 // return __sync_bool_compare_and_swap( (uint32_t *)value , _oldValue , _newValue );
63 return __atomic_compare_exchange_n( (uint32_t *)value , (uint32_t *)&oldValue , _newValue , false , __ATOMIC_SEQ_CST , __ATOMIC_SEQ_CST );
64#endif // _WIN32 || _WIN64
65}
66template< typename Value >
67bool SetAtomic64( volatile Value *value , Value newValue , Value oldValue )
68{
69#if defined( _WIN32 ) || defined( _WIN64 )
70 __int64 &_oldValue = *(__int64 *)&oldValue;
71 __int64 &_newValue = *(__int64 *)&newValue;
72 return InterlockedCompareExchange64( (__int64*)value , _newValue , _oldValue )==_oldValue;
73#else // !_WIN32 && !_WIN64
74 uint64_t &_oldValue = *(uint64_t *)&oldValue;
75 uint64_t &_newValue = *(uint64_t *)&newValue;
76 // return __sync_bool_compare_and_swap ( (uint64_t *)&value , _oldValue , _newValue );
77 return __atomic_compare_exchange_n( (uint64_t *)value , (uint64_t *)&oldValue , _newValue , false , __ATOMIC_SEQ_CST , __ATOMIC_SEQ_CST );
78#endif // _WIN32 || _WIN64
79}
80
81template< typename Value >
82bool SetAtomic( volatile Value *value , Value newValue , Value oldValue )
83{
84 switch( sizeof(Value) )
85 {
86 case 4: return SetAtomic32( value , newValue , oldValue );
87 case 8: return SetAtomic64( value , newValue , oldValue );
88 default:
89 WARN_ONCE( "should not use this function: " , sizeof(Value) );
90 static std::mutex setAtomicMutex;
91 std::lock_guard< std::mutex > lock( setAtomicMutex );
92 if( *value==oldValue ){ *value = newValue ; return true; }
93 else return false;
94 }
95}
96#endif // OLD_ATOMICS
98{
100 {
102#ifdef _OPENMP
103 OPEN_MP ,
104#endif // _OPENMP
106 ASYNC
107 };
108 static const std::vector< std::string > ParallelNames;
109
115 static const std::vector< std::string > ScheduleNames;
116
117 static size_t DefaultChunkSize;
119
120 template< typename ... Functions >
121 static void ParallelSections( const Functions & ... functions )
122 {
123 std::vector< std::future< void > > futures( sizeof...(Functions) );
124 _ParallelSections( &futures[0] , functions ... );
125 for( size_t t=0 ; t<futures.size() ; t++ ) futures[t].get();
126 }
127
128 static void Parallel_for( size_t begin , size_t end , const std::function< void ( unsigned int , size_t ) > &iterationFunction , ScheduleType schedule=DefaultSchedule , size_t chunkSize=DefaultChunkSize );
129
130 static unsigned int NumThreads( void );
131
132 static void Init( ParallelType parallelType , unsigned int numThreads=std::thread::hardware_concurrency() );
133
134 static void Terminate( void );
135
136private:
138 ThreadPool &operator = ( const ThreadPool & ){ return *this; }
139
140 template< typename Function >
141 static void _ParallelSections( std::future< void > *futures , const Function &function ){ *futures = std::async( std::launch::async , function ); }
142
143 template< typename Function , typename ... Functions >
144 static void _ParallelSections( std::future< void > *futures , const Function &function , const Functions& ... functions )
145 {
146 *futures = std::async( std::launch::async , function );
147 _ParallelSections( futures+1 , functions ... );
148 }
149 static inline void _ThreadInitFunction( unsigned int thread );
150
151 static bool _Close;
152#ifdef OLD_ATOMICS
153 static unsigned int _RemainingTasks;
154#else // !OLD_ATOMICS
155 static std::atomic< unsigned int > _RemainingTasks;
156#endif // OLD_ATOMICS
157 static std::mutex _Mutex;
158 static std::condition_variable _WaitingForWorkOrClose , _DoneWithWork;
159 static std::vector< std::thread > _Threads;
160 static std::function< void ( unsigned int ) > _ThreadFunction;
162};
163
164
165#endif // THREADS_INCLUDED
#define WARN_ONCE(...)
Definition exceptions.h:148
Definition threads.h:98
static void _ParallelSections(std::future< void > *futures, const Function &function)
Definition threads.h:141
ThreadPool(const ThreadPool &)
Definition threads.h:137
static bool _Close
Definition threads.h:151
static void Terminate(void)
Definition threads.cpp:157
static void ParallelSections(const Functions &... functions)
Definition threads.h:121
static std::function< void(unsigned int) > _ThreadFunction
Definition threads.h:160
static ParallelType _ParallelType
Definition threads.h:161
static void Parallel_for(size_t begin, size_t end, const std::function< void(unsigned int, size_t) > &iterationFunction, ScheduleType schedule=DefaultSchedule, size_t chunkSize=DefaultChunkSize)
Definition threads.cpp:58
static std::condition_variable _WaitingForWorkOrClose
Definition threads.h:158
ParallelType
Definition threads.h:100
@ NONE
Definition threads.h:101
@ THREAD_POOL
Definition threads.h:105
@ ASYNC
Definition threads.h:106
static const std::vector< std::string > ParallelNames
Definition threads.h:47
static size_t DefaultChunkSize
Definition threads.h:117
static std::mutex _Mutex
Definition threads.h:157
static void _ThreadInitFunction(unsigned int thread)
Definition threads.cpp:168
static void _ParallelSections(std::future< void > *futures, const Function &function, const Functions &... functions)
Definition threads.h:144
static void Init(ParallelType parallelType, unsigned int numThreads=std::thread::hardware_concurrency())
Definition threads.cpp:138
ThreadPool & operator=(const ThreadPool &)
Definition threads.h:138
static std::vector< std::thread > _Threads
Definition threads.h:159
static std::condition_variable _DoneWithWork
Definition threads.h:158
static unsigned int _RemainingTasks
Definition threads.h:153
ScheduleType
Definition threads.h:111
@ STATIC
Definition threads.h:112
@ DYNAMIC
Definition threads.h:113
static ScheduleType DefaultSchedule
Definition threads.h:118
static const std::vector< std::string > ScheduleNames
Definition threads.h:56
static unsigned int NumThreads(void)
Definition threads.cpp:136
bool SetAtomic32(volatile Value *value, Value newValue, Value oldValue)
Definition threads.h:53
bool SetAtomic64(volatile Value *value, Value newValue, Value oldValue)
Definition threads.h:67
bool SetAtomic(volatile Value *value, Value newValue, Value oldValue)
Definition threads.h:82