ArmarX Shared Memory

The ArmarX shared memory provides unidirectional shared memory communication. Further, classes are provided which allow unidirectional communication which either uses Ice or shared memory dependent on whether a local or a remote connection is used.

The API documentation can be found here: SharedMemory

Using simple shared memory

The simple shared memory mechanism provides mechanisms to share memory between a SharedMemoryProvider and a SharedMemoryConsumer. Both provider and consumer can be running in different processes in the same machine. The SharedMemoryProvider needs to be constructed before the SharedMemoryConsumer. Otherwise the SharedMemoryConsumer construction will fail.
Methods for synchronization are providing using either a scoped mechanism or lock / unlock methods.

// create a shared memory provider of type int and size 1 with name SharedMemory
sharedMemoryProvider.reset( new SharedMemoryProvider<int>("SharedMemory", 1));
// create a shared memory consumer of type int
// The SharedMemoryConsumer has to be constructed after the SharedMemoryProvider.
// The shared memory can be accessed from any process running on the same machine
// as the SharedMemoryProvider.
try
{
sharedMemoryConsumer.reset( new SharedMemoryConsumer<int>("SharedMemory"));
} catch(exceptions::local::SharedMemoryException e)
{
// provider not constructed
}
// write to the shared memory and protection via scoped lock
// lock / unlock can be used as an alternative
{
SharedMemoryScopedWriteLockPtr lock = sharedMemoryProvider->getScopedWriteLock();
int* data = sharedMemoryProvider->getMemory();
*data = 100;
}
// reading from shared memory and protection via scoped lock
// lock / unlock can be used as an alternative
{
SharedMemoryScopedReadLockPtr lock = sharedMemoryConsumer->getScopedReadLock();
int* data = sharedMemoryConsumer->getMemory();
printf("Data: %d\n", *data); // 100
}

Using combined Ice and shared memory transfer

The combined Ice and shared memory mechanism allows to exchange high amounts of data between two processes either via shared memory or using Ice. Whether Ice or shared memory transfer is used is selected automatically using the hardware id of the both machines involved in the communications. If the hardware ids of both sides are the same, shared memory transfer is used. Otherwise Ice transfer is used.
In general, the Provider needs to be started using start() before start() of the component can be called. The correct sequence is guaranteed when calling the constructors in onInitComponent() or equivalent and the start() methods in onConnectComponent(). The sequence is achieve making use of the components dependency mechanism.

A component that writes to the IceSharedMemory mechanism can be implemented in the following way:

namespace armarx
{
class SharedMemoryWriter :
virtual public PeriodicComponent
{
protected:
void onInitComponent()
{
sharedMemoryProvider = new IceSharedMemoryProvider<int>(this, 1);
}
void onStartComponent()
{
sharedMemoryProvider->start();
counter = 0;
}
void periodicExec()
{
SharedMemoryScopedWriteLockPtr lock = sharedMemoryProvider->getScopedWriteLock();
int* buffer = sharedMemoryProvider->getBuffer();
*buffer = counter;
std::cout << "Set value to " << counter << std::endl;
counter++;
}
std::string getDefaultName() { return "SharedMemoryWriter"; }
private:
}
}

In a similar manner, read access to the IceSharedMemory mechanism is provided:

namespace armarx
{
class SharedMemoryReader :
virtual public PeriodicComponent
{
protected:
void onInitComponent()
{
sharedMemoryConsumer = new IceSharedMemoryConsumer<int>(this,"SharedMemoryWriter");
}
void onStartComponent()
{
sharedMemoryConsumer->start();
}
void periodicExec()
{
int result;
sharedMemoryConsumer->getData(&result);
ARMARX_LOG << eINFO << "Retrieved value " << result << std::endl;
}
std::string getDefaultName() { return "SharedMemoryReader"; }
private:
}
}
armarx::IceSharedMemoryProvider::pointer_type
IceUtil::Handle< IceSharedMemoryProvider< MemoryObject, MemoryObjectMetaInfo > > pointer_type
pointer type for convenience.
Definition: IceSharedMemoryProvider.h:273
armarx::SharedMemoryScopedWriteLockPtr
std::shared_ptr< SharedMemoryScopedWriteLock > SharedMemoryScopedWriteLockPtr
Definition: SharedMemoryProvider.h:46
armarx::SharedMemoryScopedReadLockPtr
std::shared_ptr< SharedMemoryScopedReadLock > SharedMemoryScopedReadLockPtr
Definition: SharedMemoryConsumer.h:43
armarx::IceSharedMemoryConsumer::pointer_type
IceUtil::Handle< IceSharedMemoryConsumer< MemoryObject, MemoryObjectMetaInfo > > pointer_type
pointer type for convenience.
Definition: IceSharedMemoryConsumer.h:209
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::SharedMemoryConsumer::pointer_type
std::shared_ptr< SharedMemoryConsumer< MemoryObject, MemoryObjectMetaInfo > > pointer_type
Pointer type for convenience.
Definition: SharedMemoryConsumer.h:223
armarx::SharedMemoryProvider::pointer_type
std::shared_ptr< SharedMemoryProvider< MemoryObject, MemoryObjectMetaInfo > > pointer_type
Pointer type for convenience.
Definition: SharedMemoryProvider.h:335
ARMARX_LOG
#define ARMARX_LOG
Definition: Logging.h:163
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28