SUNphi  1.0
Barrier.hpp
Go to the documentation of this file.
1 #ifndef _BARRIER_HPP
2 #define _BARRIER_HPP
3 
4 /// \file Barrier.hpp
5 ///
6 /// \brief Define the threads barrier
7 
8 #ifdef HAVE_CONFIG_H
9  #include "config.hpp"
10 #endif
11 
12 #include <cstring>
13 
14 #include <debug/MinimalCrash.hpp>
15 #include <threads/Thread.hpp>
16 
17 namespace SUNphi
18 {
19 #ifdef USE_THREADS
20  /// Wrapper for the pthread barrier functionality
21  ///
22  /// Low level barrier not meant to be called explictly
23  class Barrier
24  {
25  /// Raw barrier
26  pthread_barrier_t barrier;
27 
28 #ifdef DEBUG_MODE
29 
30  /// Value used to check the barrier
31  [[maybe_unused ]]
32  const char* currBarrName;
33 
34 #endif
35 
36  /// Raw synchronization, simply wait that all threads call this
37  void rawSync()
38  {
39  /// Call the barrier and get the result
40  const int rc=
41  pthread_barrier_wait(&barrier);
42 
43  if(rc!=0 and rc!=PTHREAD_BARRIER_SERIAL_THREAD)
44  MINIMAL_CRASH_STDLIBERR("while barrier was waiting");
45  }
46 
47  public:
48 
49  /// Build the barrier for \c nThreads threads
50  Barrier(const int& nThreads) ///< Number of threads for which the barrier is defined
51  {
52  if(pthread_barrier_init(&barrier,nullptr,nThreads)!=0)
53  MINIMAL_CRASH_STDLIBERR("while barrier inited");
54  }
55 
56  /// Destroys the barrier
57  ~Barrier()
58  {
59  if(pthread_barrier_destroy(&barrier)!=0)
60  MINIMAL_CRASH_STDLIBERR("while barrier was destroyed");
61  }
62 
63  /// Synchronize, without checking the name of the barrier
64  void sync()
65  {
66  rawSync();
67  }
68 
69  /// Synchronize checking the name of the barrier
70  void sync(const char* barrName, ///< Name of the barrier
71  const int& threadId) ///< Id of the thread used coming to check
72  {
73  rawSync();
74 
75 #ifdef DEBUG_MODE
76 
77  if(threadId==masterThreadId)
78  currBarrName=
79  barrName;
80 
81  rawSync();
82 
83  if(currBarrName!=barrName)
84  MINIMAL_CRASH("Thread id %d was expecting %s but encountered %s",threadId,currBarrName,barrName);
85 
86 #endif
87 
88  }
89  };
90 
91 #else
92 
93  /// Fake barrier
94  struct Barrier
95  {
96  /// Dummy build the barrier for \c nThreads threads
97  Barrier(const int& nThreads) ///< Number of threads for which the barrier is defined
98  {
99  }
100 
101  /// Dummy synchronize checking the name of the barrier
102  void sync(const char* barrName=nullptr, ///< Name of the barrier
103  const int& threadId=0) ///< Id of the thread used coming to check
104  {
105  }
106  };
107 
108 #endif
109 
110 }
111 
112 #endif
#define MINIMAL_CRASH_STDLIBERR(STRING)
Minimal crash with stdlib error.