Skip to content

Commit

Permalink
Switch to C++11 threading API
Browse files Browse the repository at this point in the history
This removes dependencies on the POSIX threads API and uses exclusively
the C++11 standard for multi-threading. This is not complete yet,
compilation flags still need to be worked out and tested for MacOSX and
Windows.
  • Loading branch information
jdtournier committed Oct 15, 2014
1 parent c9194b5 commit 7a6bc92
Show file tree
Hide file tree
Showing 34 changed files with 522 additions and 850 deletions.
6 changes: 3 additions & 3 deletions build
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dependencies = False
verbose = False
targets = []

global todo, headers, object_deps, file_flags, thread_cflags, thread_ldflags, lock, print_lock, stop
global todo, headers, object_deps, file_flags, lock, print_lock, stop
global include_paths
todo, headers, object_deps, file_flags = {}, {}, {}, {}
lock = threading.Lock()
Expand Down Expand Up @@ -287,7 +287,7 @@ class Entry:
self.deps = list_cmd_deps(cc_file)

skip = False
flags = copy.copy (gsl_ldflags+ thread_ldflags)
flags = copy.copy (gsl_ldflags)
if 'Q' in file_flags[cc_file]: flags += qt_ldflags

if not skip:
Expand Down Expand Up @@ -315,7 +315,7 @@ class Entry:
self.action = 'CC'
cc_file = self.name[:-len(obj_suffix)] + cpp_suffix
self.deps = set([ cc_file ])
flags = copy.copy (gsl_cflags + thread_cflags)
flags = copy.copy (gsl_cflags)

if is_moc (cc_file):
src_header = cc_file[:-len(moc_cpp_suffix)] + h_suffix
Expand Down
4 changes: 1 addition & 3 deletions cmd/dwi2fod.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#include "command.h"
#include "ptr.h"
#include "progressbar.h"
#include "thread/exec.h"
#include "thread/queue.h"
#include "image/loop.h"
#include "image/threaded_loop.h"
#include "image/buffer.h"
#include "image/buffer_preload.h"
#include "image/voxel.h"
Expand Down
2 changes: 1 addition & 1 deletion cmd/dwi2response.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include "math/SH.h"
#include "math/vector.h"

#include "thread/queue.h"
#include "thread_queue.h"

#include "dwi/directions/set.h"
#include "dwi/gradient.h"
Expand Down
3 changes: 1 addition & 2 deletions cmd/dwi2tensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@

#include "command.h"
#include "progressbar.h"
#include "thread/exec.h"
#include "thread/queue.h"
#include "image/threaded_loop.h"
#include "image/voxel.h"
#include "image/buffer.h"
#include "image/buffer_preload.h"
Expand Down
2 changes: 1 addition & 1 deletion cmd/fod2metric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include "math/SH.h"
#include "math/vector.h"

#include "thread/queue.h"
#include "thread_queue.h"

#include "dwi/fmls.h"
#include "dwi/directions/set.h"
Expand Down
3 changes: 1 addition & 2 deletions cmd/sh2peaks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
#include "command.h"
#include "math/SH.h"
#include "progressbar.h"
#include "thread/exec.h"
#include "thread/queue.h"
#include "thread_queue.h"
#include "image/loop.h"
#include "image/buffer.h"
#include "image/voxel.h"
Expand Down
2 changes: 1 addition & 1 deletion cmd/tck2connectome.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#include "image/loop.h"
#include "image/voxel.h"

#include "thread/queue.h"
#include "thread_queue.h"



Expand Down
3 changes: 1 addition & 2 deletions cmd/tckedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
#include "exception.h"
#include "mrtrix.h"

#include "thread/exec.h"
#include "thread/queue.h"
#include "thread_queue.h"

#include "dwi/tractography/file.h"
#include "dwi/tractography/properties.h"
Expand Down
3 changes: 1 addition & 2 deletions cmd/tckmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
#include "image/header.h"
#include "image/voxel.h"
#include "math/matrix.h"
#include "thread/exec.h"
#include "thread/queue.h"
#include "thread_queue.h"

#include "dwi/tractography/file.h"
#include "dwi/tractography/properties.h"
Expand Down
2 changes: 1 addition & 1 deletion cmd/tcknodeextract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#include "image/transform.h"
#include "image/voxel.h"

#include "thread/queue.h"
#include "thread_queue.h"



Expand Down
2 changes: 1 addition & 1 deletion cmd/tcknormalise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include "get_set.h"
#include "image/buffer_preload.h"
#include "image/voxel.h"
#include "thread/queue.h"
#include "thread_queue.h"
#include "dwi/tractography/file.h"
#include "dwi/tractography/properties.h"

Expand Down
104 changes: 3 additions & 101 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ LDFLAGS Any additional flags to the linker.
LDLIB_FLAGS Any additional flags to the linker to generate a shared library.
PTHREAD_CFLAGS Any flags required to compile with POSIX threads.
PTHREAD_LDFLAGS Any flags required to link with POSIX threads.
GSL_CFLAGS Any flags required to compile with the GSL.
This may include in particular the path to the
include files, if not in a standard location
Expand Down Expand Up @@ -189,20 +185,17 @@ global cpp, cpp_cmd, ld, ld_args, ld_cmd

cxx = [ 'g++' ]
cxx_args = '-c CFLAGS SRC -o OBJECT'.split()
cpp_flags = [ '-std=c++11' ]
cpp_flags = [ '-std=c++11', '-pthread' ]

ld = [ 'g++' ]
ld_args = 'OBJECTS LDFLAGS -o EXECUTABLE'.split()
ld_flags = []
ld_flags = [ '-pthread' ]

if static:
ld_flags += [ '-static' ]

ld_lib_args = 'OBJECTS LDLIB_FLAGS -o LIB'.split()
ld_lib_flags = [ ]

thread_cflags = []
thread_ldflags = [ '-lpthread' ]
ld_lib_flags = [ '-pthread' ]

zlib_cflags = []
zlib_ldflags = [ '-lz' ]
Expand Down Expand Up @@ -477,52 +470,6 @@ else:



report ('Checking for unordered_map: ')
try:
compile ('''
#include <unordered_map>
int main() {
std::unordered_map<int,int> map;
return (map.size());
}
''', cpp_flags, ld_flags)
report ('present\n')
except:
report ('no\n')
report ('Checking for TR1 unordered_map: ')
try:
compile ('''
#include <tr1/unordered_map>
int main() {
std::tr1::unordered_map<int,int> map;
return (map.size());
}
''', cpp_flags, ld_flags)
report ('present\n')
cpp_flags += [ '-DMRTRIX_USE_TR1' ]
except:
report ('no - will use SGI std::hash_map instead\n')
cpp_flags += [ '-DMRTRIX_USE_HASH_MAP' ]




report ('Checking for 64-bit integer type: ')
try:
compile ('''
#include <stdint.h>
int main() {
int64_t t = 0;
return (t);
}
''', cpp_flags, ld_flags)
report ('yes\n')
except:
report ('no\n')
error ('<stdint.h> is not C99 compliant - it does not define a int64_t type.')



Expand Down Expand Up @@ -614,49 +561,6 @@ ld_lib_flags += zlib_ldflags



# POSIX threads:

report ('Checking for POSIX threads: ')

if 'PTHREAD_CFLAGS' in os.environ.keys(): thread_cflags = shlex.split (os.environ['PTHREAD_CFLAGS'])
if 'PTHREAD_LDFLAGS' in os.environ.keys(): thread_ldflags = shlex.split (os.environ['PTHREAD_LDFLAGS'])

try:
compile ('''
#include <pthread.h>
void* func (void*) { return (NULL); }
int main() {
pthread_t t;
if (pthread_create(&t, NULL, func, NULL)) return (1);
pthread_exit (NULL);
return (0);
}
''', cpp_flags + thread_cflags, ld_flags + thread_ldflags)
report ('yes\n')
except CompileError:
error ('''compiler error!
Use the PTHREAD_CFLAGS environment variable to set the path to
the pthread include files and to set any required flags
For example:
PTHREAD_CFLAGS="-I/usr/local/include" ./configure''')
except LinkError:
error ('''linker error!
Use the PTHREAD_LDFLAGS environment variable to set the path to
the pthread libraries and to set the library to use
For example:
PTHREAD_LDFLAGS="-L/usr/local/lib -lpthread" ./configure''')
except RuntimeError:
error ('''runtime error!
There is something wrong with your POSIX threads implementation!''')
except:
error (' POSIX threads implementation not found!')




# GSL flags:
Expand Down Expand Up @@ -1208,8 +1112,6 @@ else:
cache.write ('True\n')
commit ('ld_lib', ld_lib);
commit ('ld_lib_flags', ld_lib_flags);
commit ('thread_cflags', thread_cflags)
commit ('thread_ldflags', thread_ldflags)
commit ('gsl_cflags', gsl_cflags)
commit ('gsl_ldflags', gsl_ldflags)

Expand Down
48 changes: 14 additions & 34 deletions lib/image/threaded_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
#include "image/loop.h"
#include "image/utils.h"
#include "image/iterator.h"
#include "thread/mutex.h"
#include "thread/exec.h"
#include "thread.h"

namespace MR
{
Expand Down Expand Up @@ -361,7 +360,7 @@ namespace MR

//! get next position in the outer loop
bool next (Iterator& pos) {
Thread::Mutex::Lock lock (mutex);
std::lock_guard<std::mutex> lock (mutex);
if (loop.ok()) {
loop.set_position (dummy, pos);
loop.next (dummy);
Expand All @@ -372,17 +371,16 @@ namespace MR

//! invoke \a functor (const Iterator& pos) per voxel <em> in the outer axes only</em>
template <class Functor>
void run_outer (Functor&& functor, const std::string& thread_label = "unknown")
void run_outer (Functor&& functor)
{
if (Thread::number_of_threads() == 0) {
for (auto i = loop (dummy); i; ++i)
functor (dummy);
return;
}

__Outer<Functor> loop_thread (*this, functor);
Thread::Array<__Outer<Functor> > thread_list (loop_thread);
Thread::Exec threads (thread_list, thread_label);
__Outer<typename std::remove_reference<Functor>::type> loop_thread (*this, functor);
Thread::run (Thread::multi (loop_thread), "loop threads");
}


Expand All @@ -391,43 +389,25 @@ namespace MR
template <class Functor, class... VoxelType, typename std::enable_if<sizeof...(VoxelType) == 0, int>::type = 0>
void run (Functor&& functor, VoxelType&&... vox)
{
if (Thread::number_of_threads() == 0) {
LoopInOrder inner_loop (axes);
for (auto i = loop (dummy); i; ++i) {
for (auto j = inner_loop (dummy); j; ++j)
functor (dummy);
}
return;
}

__RunFunctorIter<Functor> loop_thread (*this, functor);
run_outer (loop_thread, "run thread");
__RunFunctorIter<typename std::remove_reference<Functor>::type> loop_thread (*this, functor);
run_outer (loop_thread);
}


template <class Functor, class... VoxelType, typename std::enable_if<sizeof...(VoxelType) != 0, int>::type = 0>
void run (Functor&& functor, VoxelType&&... vox)
{
if (Thread::number_of_threads() == 0) {
LoopInOrder inner_loop (axes);
for (auto i = loop (vox...); i; ++i) {
for (auto j = inner_loop (vox...); j; ++j)
functor (vox...);
}
return;
}

__RunFunctor<Functor, VoxelType...>
__RunFunctor<typename std::remove_reference<Functor>::type, typename std::remove_reference<VoxelType>::type...>
loop_thread (*this, functor, vox...);
run_outer (loop_thread, "run thread");
run_outer (loop_thread);
}


protected:
LoopInOrder loop;
Iterator dummy;
const std::vector<size_t> axes;
Thread::Mutex mutex;
std::mutex mutex;

static std::vector<size_t> __get_axes_in_thread (
const std::vector<size_t>& axes_in_loop,
Expand Down Expand Up @@ -471,7 +451,7 @@ namespace MR
template <class Functor>
class __Outer {
public:
__Outer (ThreadedLoop& shared_info, const Functor& functor) :
__Outer (ThreadedLoop& shared_info, Functor& functor) :
shared (shared_info),
func (functor) { }

Expand All @@ -484,7 +464,7 @@ namespace MR

protected:
ThreadedLoop& shared;
Functor func;
typename std::remove_reference<Functor>::type func;
};


Expand All @@ -505,7 +485,7 @@ namespace MR
}

protected:
Functor func;
typename std::remove_reference<Functor>::type func;
LoopInOrder loop;
};

Expand All @@ -528,7 +508,7 @@ namespace MR
}

protected:
Functor func;
typename std::remove_reference<Functor>::type func;
LoopInOrder loop;
const std::vector<size_t>& outer_axes;
std::tuple<VoxelType...> vox;
Expand Down
Loading

0 comments on commit 7a6bc92

Please sign in to comment.