]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTDataBuffer.h
- made package indepentend of src
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataBuffer.h
1 // @(#) $Id$
2
3 #ifndef ALIHLTDATABUFFER_H
4 #define ALIHLTDATABUFFER_H
5 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
6  * See cxx source for full Copyright notice                               */
7
8 /** @file   AliHLTDataBuffer.h
9     @author Matthias Richter
10     @date   
11     @brief  Handling of Data Buffers for HLT components.
12     @note   The class is used in Offline (AliRoot) context
13 */
14
15 #include <cerrno>
16 #include "AliHLTLogging.h"
17 #include "AliHLTDataTypes.h"
18 #include "AliHLTDefinitions.h"
19 #include "TObject.h"
20 #include "TList.h"
21
22 class AliHLTComponent;
23 /* @name internal data structures
24  */
25
26 /**
27  * @struct AliHLTDataSegment
28  * @brief  Descriptor of a data segment within the buffer.
29  * @ingroup alihlt_system
30  */
31 struct AliHLTDataSegment {
32   AliHLTDataSegment()
33     :
34     fDataType(),
35     fSegmentOffset(0),
36     fSegmentSize(0),
37     fSpecification(0)
38   {
39     memset(&fDataType, 0, sizeof(AliHLTComponent_DataType));
40   }
41   AliHLTDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size) 
42     :
43     fDataType(),
44     fSegmentOffset(offset),
45     fSegmentSize(size),
46     fSpecification(0)
47   {
48     memset(&fDataType, 0, sizeof(AliHLTComponent_DataType));
49   }
50   /** the data type of this segment */
51   AliHLTComponent_DataType fDataType;
52   /** offset in byte within the data buffer */
53   AliHLTUInt32_t fSegmentOffset;
54   /** size of the actual content */
55   AliHLTUInt32_t fSegmentSize;
56   /** data specification */
57   AliHLTUInt32_t fSpecification;
58 };
59
60 /**
61  * @struct AliHLTRawBuffer
62  * @brief  Descriptor of the raw data buffer which can host several segments.
63  * @ingroup alihlt_system
64  */
65 struct AliHLTRawBuffer {
66   /** size of the currently occupied partition of the buffer */
67   AliHLTUInt32_t fSize;
68   /** total size of the buffer, including safety margin */
69   AliHLTUInt32_t fTotalSize;
70   /** the buffer */
71   void* fPtr;
72 };
73
74 /**
75  * @class AliHLTConsumerDescriptor
76  * @brief Helper class to describe a consumer component.
77  *
78  * There is unfortunately no unique determination of the data type from the component
79  * itself possible, thats why both component and data type have to be initialized
80  * and are stored in a compound. The class is intended to make bookkeeping easier.
81  *
82  * @note This class is only used for the @ref alihlt_system.
83  *
84  * @ingroup alihlt_system
85  */
86 class AliHLTConsumerDescriptor : public AliHLTLogging, public TObject {
87  private:
88   AliHLTComponent* fpConsumer;
89   vector<AliHLTDataSegment> fSegments;
90
91  public:
92   /** standard constructur */
93   AliHLTConsumerDescriptor();
94   /** constructur 
95    * @param pConsumer pointer to the consumer component
96    */
97   AliHLTConsumerDescriptor(AliHLTComponent* pConsumer);
98   /** not a valid copy constructor, defined according to effective C++ style */
99   AliHLTConsumerDescriptor(const AliHLTConsumerDescriptor&);
100   /** not a valid assignment op, but defined according to effective C++ style */
101   AliHLTConsumerDescriptor& operator=(const AliHLTConsumerDescriptor&);
102   /** destructor */
103   ~AliHLTConsumerDescriptor();
104
105   /**
106    * Get the component of this descriptor
107    * @return pointer to the component
108    */
109   AliHLTComponent* GetComponent() {return fpConsumer;}
110
111   /**
112    * Set an active data segment
113    * the pointer will be handled in a container, not allocation, copy or cleanup
114    * @param offset  offset of the segment in the buffer
115    * @param size    size of the segment in the buffer
116    * @return >=0 if succeeded
117    */
118   int SetActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
119
120   /**
121    * check whether there is an active data segment of certain size with certain offset
122    * @param offset  offset of the data segment in the data buffer
123    * @param size    size of the data segment in the data buffer
124    * @return > if existend, 0 if not
125    */
126   int CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
127
128   /** find an active data segment of certain size with certain offset
129    * will see if this is necessary
130    * @param offset  offset of the data segment in the data buffer
131    * @param size    size of the data segment in the data buffer
132    * @return offset of the data segment
133    */
134   //AliHLTUInt32_t FindActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
135
136   /** get the number of active segments for this consumer
137    * @return number of active segments
138    */
139   int GetNofActiveSegments() {return fSegments.size();};
140
141   /**
142    */
143   int ReleaseActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
144
145   //ClassDef(AliHLTConsumerDescriptor, 0)
146 };
147
148 /**
149  * @class AliHLTDataBuffer
150  * @brief  Handling of data buffers for the HLT.
151  * 
152  * The class provides handling of data buffers for HLT components. Each component gets its
153  * own Data Buffer instance. The buffer is grouped into different data segments according
154  * to the output of the component.<br>
155  * The Data Buffer keeps control over the data requests of the 'child' componets. Each 
156  * component can subscribe to a certain segment of the data buffer. It's state is that 
157  * changed from 'reserved' to 'active'. After the data processing the component has to 
158  * release the segment and it's state is set to 'processed'.
159  * If all components have requested and released their data, the Raw Buffer is released
160  * and pushed back in the list of available buffers. 
161  *
162  * @note This class is only used for the @ref alihlt_system.
163  *
164  * @ingroup alihlt_system
165  */
166 class AliHLTDataBuffer : public AliHLTLogging, public TObject {
167  public:
168   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
169   // condtructors and destructors
170
171   /* standard constructor
172    */
173   AliHLTDataBuffer();
174   /** not a valid copy constructor, defined according to effective C++ style */
175   AliHLTDataBuffer(const AliHLTDataBuffer&);
176   /** not a valid assignment op, but defined according to effective C++ style */
177   AliHLTDataBuffer& operator=(const AliHLTDataBuffer&);
178   /** destructor */
179   virtual ~AliHLTDataBuffer();
180
181   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
182   // initialization
183
184   /**
185    * Add component to the list of consumers
186    * @param pConsumer - a consumer of type AliHLTComponent
187    */
188   int SetConsumer(AliHLTComponent* pConsumer);
189
190   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
191   // component to component communication
192
193   /**
194    * Determine the number of matching data blocks for the component and a consumer
195    * component. <br>
196    * The first approach will support only one output data type for processing components.
197    * @param pConsumer       the component which subscribes to the buffer
198    * @param tgtList         (optional) the list to receive the data types
199    * @return: number of data blocks which match the input data types 
200    *          of the consumer, neg. error code if failed <br>
201    *          -EINVAL       invalid parameter <br>
202    */
203   int FindMatchingDataBlocks(const AliHLTComponent* pConsumer, vector<AliHLTComponent_DataType>* tgtList=NULL);
204
205   /**
206    * Subscribe to a segment of the data buffer.
207    * The function prepares the block descriptor for subsequent use with the AliHLTComponent::ProcessEvent
208    * method, the method can prepare several block descriptors up to the array size specified by
209    * iArraySize. The return value is independent from the array size the number of block descriptors 
210    * which would have been prepared if there was enough space in the array<br>
211    * The method is used by the consumer component.
212    * @param pConsumer       the component which subscribes to the buffer
213    * @param arrayBlockDesc  pointer to block descriptor to be filled
214    * @param iArraySize      size of the block descriptor array
215    * @return: number of matching data blocks if success, negative error code if failed<br>
216    *          -EACCESS      the state of the consumer can not be changed (activated)
217    *          -EBADF        unresolved data segments <br>
218    *          -ENOENT       consumer component not found <br>
219    *          -ENODATA      data buffer does not have raw data <br>
220    *          -EINVAL       invalid parameter <br>
221    */
222   int Subscribe(const AliHLTComponent* pConsumer, AliHLTComponent_BlockData* arrayBlockDesc, int iArraySize);
223
224   /**
225    * Release an instance of the data buffer.
226    * Resets the variables of the block descriptor.
227    * If all buffer segments are released, the Data Buffer is reseted
228    * and the Raw Buffer released.<br>
229    * The method is used by the consumer component.
230    * @param pBlockDesc      descriptor of the data segment
231    * @param pConsumer       the component which subscribes to the buffer
232    * @return: >0 if success, negative error code if failed <br>
233    *          -EACCESS      the state of the consumer can not be changed (de-activated)
234    *          -ENOENT       consumer component has not subscribed to the buffer <br>
235    *          -EINVAL       invalid parameter <br>
236    */
237   int Release(AliHLTComponent_BlockData* pBlockDesc, const AliHLTComponent* pConsumer);
238
239   /**
240    * Get a target buffer of minimum size iMinSize.
241    * The method is used by the component which owns the Data Buffer to 
242    * allocate a buffer for the data it is going to produce.
243    * @param iMinSize        minumum size of the requested buffer
244    * @return: pointer to target buffer if 
245    */
246   AliHLTUInt8_t* GetTargetBuffer(int iMinSize);
247
248   /**
249    * Set the segments for the data buffer.
250    * This is usually done after the component has written the data to the buffer, 
251    * which was requested by the @ref GetTargetBuffer method. The component might
252    * produce different types of data, for each type a segment has to be defined
253    * which describes the data inside the bauffer.<br>
254    * The @ref AliHLTComponent_BlockData segment descriptor comes directly from the
255    * @ref AliHLTComponent::ProcessEvent method.
256    * @param pTgt            the target buffer which the segments refer to
257    * @param arraySegments   the output block descriptors of the component
258    * @param iSize           size of the array
259    */
260   int SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponent_BlockData* arraySegments, int iSize);
261
262   /**
263    * Check if the data buffer is empty.
264    * @return 1 if empty, 0 if not
265    */
266   int IsEmpty();
267
268   /**
269    * Get the total and maximum size of the buffer.
270    * Lets see if this is needed later
271    */
272   //int GetTotalSize();
273
274   /**
275    * Get the number of segments
276    * @return number of segments
277    */
278   int GetNofSegments();
279
280   /**
281    * Get the number of consumers
282    * @return number of consumers
283    */
284   int GetNofConsumers();
285
286   /**
287    * Get the number of active consumers
288    * @return number of active consumers
289    */
290   int GetNofActiveConsumers();
291
292  private:
293   /* lets see if this is needed
294   AliHLTDataSegment* FindDataSegment(AliHLTComponent_DataType datatype);
295   */
296
297   /**
298    * Find those data segments which match the input types of a component.
299    * @param pConsumer       the component which subscribes to the buffer
300    * @param tgtList         the list to receive the data segment descriptors
301    * @return: number of data blocks which match the input data types 
302    *          of the consumer, neg. error code if failed <br>
303    *          -EINVAL       invalid parameter <br>
304    */
305   int FindMatchingDataSegments(const AliHLTComponent* pConsumer, vector<AliHLTDataSegment>& tgtList);
306
307   /**
308    * Reset the data buffer.
309    * Removes all consumers back to the @ref fConsumers list
310    * and releases the Raw Buffer.
311    */
312   int ResetDataBuffer();
313
314
315   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
316   // the data description
317
318   // the data segments within this buffer
319   vector<AliHLTDataSegment> fSegments;
320
321   // the list of all consumers which are going to subscribe to the buffer
322   vector<AliHLTConsumerDescriptor*> fConsumers;
323   // the list of all consumers which are currently subscribed to the buffer
324   vector<AliHLTConsumerDescriptor*> fActiveConsumers;
325   // the list of all consumers which are already released for the current event
326   vector<AliHLTConsumerDescriptor*> fReleasedConsumers;
327
328   // the buffer instance
329   AliHLTRawBuffer* fpBuffer;
330
331   // flags indicating the state of the buffer
332   AliHLTUInt32_t fFlags;
333
334   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
335   // global buffer handling, internal use only
336
337   /**
338    * Create a raw buffer of a certain size.
339    * The function tries to find a buffer of the given size (or a bit bigger by a 
340    * certain margin @ref fMargin) from the list of free buffers.
341    * If no buffer is available, a new one is created and added to the buffer handling.
342    * @param size            min. size of the requested buffer
343    * @return pointer to raw buffer
344    */
345   static AliHLTRawBuffer* CreateRawBuffer(AliHLTUInt32_t size);
346
347   /**
348    * Mark a buffer as free.
349    * After the Data Buffer has finnished using the raw buffer, it is released and
350    * added to the list of available buffers.
351    * @param pBuffer         the raw buffer to release
352    * @return >=0 if succeeded, neg. error code if failed
353    */
354   static int ReleaseRawBuffer(AliHLTRawBuffer* pBuffer);
355
356   /**
357    * Deletes all the raw buffers.
358    * When the last Data Buffer object is destructed, all raw data buffers are relesed.
359    */
360   static int DeleteRawBuffers();
361
362   /**
363    * Number of instances of AliHLTDataBuffer.
364    * The statice variable is incremented and decremented in the constructor/destructor.
365    * All internal data structures are cleaned up when the last instance is exiting.
366    */
367   static int fNofInstances;
368   /** global list of free raw buffers */
369   static vector<AliHLTRawBuffer*> fFreeBuffers;
370   /** global list of currently active raw buffers */
371   static vector<AliHLTRawBuffer*> fActiveBuffers;
372   /** determines the raw buffer size margin at buffer requests */
373   static AliHLTUInt32_t fMargin;
374
375   /** global instance to HLT logging class for static methods */
376   static AliHLTLogging fgLogging;
377
378   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
379   // internal helper functions
380
381   /**
382    * Find the consumer descriptor for a certain component and data type in 
383    * a list of consumers.<br>
384    * <b>Note:</b> There are three lists which contain the consumers in the different states.
385    * @param pConsumer       pointer to consumer component
386    * @param list            list where to search for the consumer
387    */
388   AliHLTConsumerDescriptor* FindConsumer(const AliHLTComponent* pConsumer, vector<AliHLTConsumerDescriptor*> &list);
389
390   /**
391    * Change the state of a consumer.
392    * The state of a consumer is determined by the list it is strored in, the method moves a consumer from 
393    * the source to the target list.
394    * @param pDesc           pointer to consumer descriptor
395    * @param srcList         list where the consumer is currently to be found
396    * @param tgtList         list where to move the consumer
397    */
398   int ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, vector<AliHLTConsumerDescriptor*> &srcList, vector<AliHLTConsumerDescriptor*> &tgtList);
399
400   /**
401    * Cleanup a consumer list.
402    * Release all allocated data structures. <b>Note:</b> Not the component itself!
403    */
404   int CleanupConsumerList();
405
406   ClassDef(AliHLTDataBuffer, 0)
407 };
408 #endif // ALIHLTDATABUFFER_H