next up previous contents index
Next: Processes Up: Interprocess communication Previous: Command Protocol   Contents   Index


Memory Buffers

For interprocess communication on the MAIN computer a segment of shared memory was used1. A contiguous block of shared memory is accessible for four processes running on the MAIN machine (daq_main, daq_fe, daq_rec, and daq_mon). This block is divided on an information segment and fixed size buffers. The size of each buffer is guaranteed to be larger than biggest possible event (5 Kbytes). The buffers are binded in circular linked list.

This data structure (class MemPool) is created, deleted, and reseted by the daq_main process. Other processes use these buffers. The daq_fe process works as a producer filling the buffers by events. The daq_rec process works as a main high-priority consumer. The daq_mon process works as a secondary consumer.

Each memory buffer can be in one of four states:

enum BufferState {
    Empty = 0,         // buffer is empty
    Ready,             // buffer has been filled (by daq_fe)
    Written,           // buffer has been stored (by daq_rec)
    Monitored          // buffer has been monitored (by daq_mon)
};

The processes change the buffer states as shown in the table 8. For example, initially a buffer is in the Empty state, daq_fe fills it and the buffer goes to the Ready state, if then it is taken by daq_mon it becomes in the Monitored state, and finally it is stored by daq_rec and returns back to the Empty state.


Table 8: Buffer state transitions: E - empty, R - ready, W - written, M - monitored.
  Processes
State daq_fe daq_rec daq_mon
E R - -
R R W M
W R - E
M R E -


When a process works with a buffer it locks it using

enum BufferLock {
    Unlocked = 0,          // buffer may be used
    WriteLock = 1,         // buffer is written
    ReadRecLock = 2,       // buffer is read by daq_rec
    ReadMonLock = 4        // buffer is read by daq_mon
};

The main task of class MemPool is to provide raw memory buffers for the clients. GetWriteBuffer() is called by daq_fe and returns a pointer to the next (always next) buffer which is locked by WriteLock. GetReadBuffer() is called by daq_rec and returns a pointer to the next (always next) filled buffer which is locked by ReadRecLock. GetAnyReadBuffer() is called by daq_mon and returns a pointer to the first available filled buffer which is locked by ReadMonLock.

class MemPool {
public:
  // ...
  void * GetWriteBuffer();
  void * GetReadBuffer();
  void * GetAnyReadBuffer();
  void   ReleaseWriteBuffer();
  void   ReleaseReadBuffer();
  void   ReleaseAnyReadBuffer();
  // ...
};

As it was mentioned above the block of shared memory has an information segment. This segment consists of three parts:


next up previous contents index
Next: Processes Up: Interprocess communication Previous: Command Protocol   Contents   Index
Alexander V.Inyakin 2002-04-05