Peano
|
Boolean semaphore across MPI ranks. More...
#include <BooleanSemaphore.h>
Data Structures | |
class | BooleanSemaphoreService |
Public Member Functions | |
BooleanSemaphore () | |
Create new boolean semaphore spanning all MPI ranks. | |
~BooleanSemaphore () | |
Private Member Functions | |
void | enterCriticalSection () |
Waits until I can enter the critical section. | |
void | leaveCriticalSection () |
Tells the semaphore that it is about to leave. | |
BooleanSemaphore (const BooleanSemaphore &)=delete | |
You may not copy a semaphore. | |
BooleanSemaphore & | operator= (const BooleanSemaphore &)=delete |
You may not copy a semaphore. | |
Private Attributes | |
const int | _semaphoreNumber |
tarch::multicore::BooleanSemaphore | _localRankLockRequestSemaphore |
Static Private Attributes | |
static tarch::logging::Log | _log |
static int | _semaphoreCounter |
Friends | |
class | Rank |
class | tarch::mpi::Lock |
Boolean semaphore across MPI ranks.
Only one thread on one rank gets access to a certain code region. This means that this particular semaphore represents a critical section across both threads and ranks in one go. It is inherently multithreading-safe.
Each boolean semaphore constructs a unique global number which is used to identify the semaphore within the whole system. When we request a lock, we send an integer message with this number to the global master through the semaphore tag. If we we release it, we send the negative number back.
As an mpi semaphore includes all ranks and all threads, it is something that is more general than a "normal" tarch::multicore::BooleanSemaphore. Therefore, the mpi semaphore hosts a multicore semaphore. As long as a thread on the local rank has blocked a critical section, we don't even have to go to the global master.
However, this is not the only semaphore: On the global master, we need a second semaphore to protect the global semaphore map. This map might be changed even if we are not in a critical section.
The implementation is straightforward:
Multiple request handling routines (calls of acquireLock()) can be active at the same time, i.e. reside on the global master's call stack. They will be served one by one, although implicitly in reverse order as we work with the call stack. It is important to poll receiveDanglingMessages() all the time, as we might wait for a lock to be freed, but for the lock to be freed, we have to check unexpected aka dangling messages.
Definition at line 71 of file BooleanSemaphore.h.
|
privatedelete |
You may not copy a semaphore.
tarch::mpi::BooleanSemaphore::BooleanSemaphore | ( | ) |
Create new boolean semaphore spanning all MPI ranks.
Register a new global semaphore. Please note that global semaphores have to be static, and that each rank has to have the same one and create the MPI semaphores in the same order (SPMD programming paradigm).
What happens is that the constructor grabs a unique number for this MPI semaphore, and stores it in _semaphoreNumber. This number will later be used globally to identify this semaphore type.
Definition at line 25 of file BooleanSemaphore.cpp.
References _semaphoreCounter.
tarch::mpi::BooleanSemaphore::~BooleanSemaphore | ( | ) |
Definition at line 31 of file BooleanSemaphore.cpp.
|
private |
Waits until I can enter the critical section.
This operation is protected, as you should not invoke it directly. Use tarch::mpi::Lock to acquire it. With such a lock object, you can be sure that the lock is released (the latest when the object is destroyed. This way, your code is a little bit more deadlock-free. You cannot forget to release an MPI semaphore.
Definition at line 15 of file BooleanSemaphore.cpp.
References _localRankLockRequestSemaphore, _semaphoreNumber, tarch::mpi::BooleanSemaphore::BooleanSemaphoreService::acquireLock(), tarch::multicore::BooleanSemaphore::enterCriticalSection(), and tarch::mpi::BooleanSemaphore::BooleanSemaphoreService::getInstance().
|
private |
Tells the semaphore that it is about to leave.
Definition at line 20 of file BooleanSemaphore.cpp.
|
privatedelete |
You may not copy a semaphore.
|
friend |
Definition at line 308 of file BooleanSemaphore.h.
|
friend |
Definition at line 309 of file BooleanSemaphore.h.
|
private |
Definition at line 320 of file BooleanSemaphore.h.
Referenced by enterCriticalSection().
|
staticprivate |
Definition at line 311 of file BooleanSemaphore.h.
|
staticprivate |
Definition at line 313 of file BooleanSemaphore.h.
Referenced by BooleanSemaphore().
|
private |
Definition at line 315 of file BooleanSemaphore.h.
Referenced by enterCriticalSection().