|
Peano
|
Service Repository. More...
#include <ServiceRepository.h>


Data Structures | |
| struct | ServiceEntry |
Public Member Functions | |
| virtual | ~ServiceRepository () |
| void | addService (Service *const service, const std::string &name) |
| Add a new service. | |
| bool | hasService (Service *service) const |
| This routine is thread-safe. | |
| void | removeService (Service *const service) |
| This routine is thread-safe, i.e. | |
| virtual void | receiveDanglingMessages () override |
| Answer to MPI Messages. | |
| std::string | getListOfRegisteredServices () const |
| void | init () |
| Maybe the only service that you don't have to init and shutdown. | |
| virtual void | shutdown () override |
Public Member Functions inherited from tarch::services::Service | |
| virtual | ~Service () |
Static Public Member Functions | |
| static ServiceRepository & | getInstance () |
Private Types | |
| typedef std::vector< ServiceEntry > | ServiceContainer |
Private Member Functions | |
| ServiceRepository () | |
Private Attributes | |
| ServiceContainer | _services |
| tarch::multicore::RecursiveSemaphore | _receiveDanglingMessagesSemaphore |
Static Private Attributes | |
| static tarch::services::ServiceRepository | _singleton |
Additional Inherited Members | |
Protected Attributes inherited from tarch::services::Service | |
| tarch::multicore::RecursiveSemaphore | _receiveDanglingMessagesSemaphore |
| Recursive semaphores. | |
Service Repository.
See the interface Service for a detailed description. The registry is a service itself, but it does not register as a service.
Definition at line 27 of file ServiceRepository.h.
|
private |
Definition at line 34 of file ServiceRepository.h.
|
private |
|
virtual |
| void tarch::services::ServiceRepository::addService | ( | Service *const | service, |
| const std::string & | name ) |
Add a new service.
This routine is thread-safe, i.e. it blocks other addService() calls as well as receiveDanglingMessages().
I add a recursive semaphore to the addService() routine, as I think this is correct. However, this routine is called very early in the execution. I get seg faults with TBB in this case, and guess this is due to some memory lacking a proper initialisation. So I omit the recursive semaphore whenever I use TBB.
| service | Pointer to service |
| name | Name of service (mandatory, not empty) |
|
static |
| std::string tarch::services::ServiceRepository::getListOfRegisteredServices | ( | ) | const |
| bool tarch::services::ServiceRepository::hasService | ( | Service * | service | ) | const |
This routine is thread-safe.
| void tarch::services::ServiceRepository::init | ( | ) |
Maybe the only service that you don't have to init and shutdown.
|
overridevirtual |
Answer to MPI Messages.
Tell all registered services to answer to MPI messages that are still pending in the MPI queues.
I once had an implementation that checks via Iprobe whether to call the receiveDanglingMessages() of all registered services. Without that probe, my ExaHyPE 2 code did crash. Today, I think this has been a bug in the way how parts of the code handled the requests, so I could remove the snippet again.
From a theory point of view, it makes sense nevertheless to allow codes to do something else while receiveDanglingMessages() is called. If this routine is called, the system basically flags that there's a lack of MPI progression or poor load balancing, so the routine indeed should give a user code to do something meaningful meanwhile.
I thought it would be an excellent idea to process some tasks therefore. With a lot of tasks, this is a poor idea. Potentially p-1 threads hit the task queue (if one thread is doing I/O for example) and then they all block each other and no MPI progress is made, as very few tasks call the actual MPI routines. So I removed that line to process a task, and this has made the system much more stable.
It is important that you never ever call receiveDanglingMessages() of a service directly. Instead, you always should go to the repository. The reasons reads as follows: Most services do not protect their receiveDanglingMessages() with an additional semaphore. So two threads might hit it and both thus issue an Iprobe. Let there be one MPI message in the queue. Both probes return a true and, hence, both threads issue a receive. Unfortunately, only one of them succeeds. We could have solved that with new MPI features, but we also solve it in the old-fashioned way if you only issue receives through the repository, as the repository invokes the services, but it first blocks all other threads through a semaphore.
This routine is thread-safe compared to addService() and removeService().
Implements tarch::services::Service.
Referenced by swift2::ParticleSpecies::allReduce().

| void tarch::services::ServiceRepository::removeService | ( | Service *const | service | ) |
This routine is thread-safe, i.e.
it blocks out receiveDanglingMessages() and all other routine which register or de-register services.
|
overridevirtual |
Implements tarch::services::Service.
|
private |
Definition at line 38 of file ServiceRepository.h.
|
private |
Definition at line 36 of file ServiceRepository.h.
|
staticprivate |
Definition at line 43 of file ServiceRepository.h.