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 */
8 /** @file AliHLTDataBuffer.h
9 @author Matthias Richter
11 @brief Handling of Data Buffers for HLT components.
12 @note The class is used in Offline (AliRoot) context
17 #include "AliHLTLogging.h"
18 #include "AliHLTDataTypes.h"
19 #include "AliHLTDefinitions.h"
23 class AliHLTComponent;
24 /* @name internal data structures
28 * @struct AliHLTDataSegment
29 * @brief Descriptor of a data segment within the buffer.
30 * @ingroup alihlt_system
32 struct AliHLTDataSegment {
40 memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
42 AliHLTDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
45 fSegmentOffset(offset),
49 memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
51 /** the data type of this segment */
52 AliHLTComponentDataType fDataType; // see above
53 /** offset in byte within the data buffer */
54 AliHLTUInt32_t fSegmentOffset; // see above
55 /** size of the actual content */
56 AliHLTUInt32_t fSegmentSize; // see above
57 /** data specification */
58 AliHLTUInt32_t fSpecification; // see above
62 * @struct AliHLTRawBuffer
63 * @brief Descriptor of the raw data buffer which can host several segments.
64 * @ingroup alihlt_system
66 struct AliHLTRawBuffer {
67 /** size of the currently occupied partition of the buffer */
68 AliHLTUInt32_t fSize; // see above
69 /** total size of the buffer, including safety margin */
70 AliHLTUInt32_t fTotalSize; // see above
72 void* fPtr; //! transient
76 * @class AliHLTConsumerDescriptor
77 * @brief Helper class to describe a consumer component.
79 * There is unfortunately no unique determination of the data type from the
80 * component itself possible, thats why both component and data type have to
81 * be initialized and are stored in a compound. The class is intended to make
84 * @note This class is only used for the @ref alihlt_system.
86 * @ingroup alihlt_system
88 class AliHLTConsumerDescriptor : public TObject, public AliHLTLogging {
90 /** standard constructur */
91 AliHLTConsumerDescriptor();
93 * @param pConsumer pointer to the consumer component
95 AliHLTConsumerDescriptor(AliHLTComponent* pConsumer);
96 /** not a valid copy constructor, defined according to effective C++ style */
97 AliHLTConsumerDescriptor(const AliHLTConsumerDescriptor&);
98 /** not a valid assignment op, but defined according to effective C++ style */
99 AliHLTConsumerDescriptor& operator=(const AliHLTConsumerDescriptor&);
101 ~AliHLTConsumerDescriptor();
104 * Get the component of this descriptor.
105 * @return pointer to the component
107 AliHLTComponent* GetComponent() {return fpConsumer;}
110 * Set an active data segment.
111 * the pointer will be handled in a container, no allocation, copy or
113 * @param offset offset of the segment in the buffer
114 * @param size size of the segment in the buffer
115 * @return >=0 if succeeded
117 int SetActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
120 * Check whether there is an active data segment of certain size with
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
126 int CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
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
134 //AliHLTUInt32_t FindActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
136 /** get the number of active segments for this consumer
137 * @return number of active segments
139 int GetNofActiveSegments() {return fSegments.size();};
143 int ReleaseActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
146 /** consumer object */
147 AliHLTComponent* fpConsumer; //! transient
149 /** list of data segments */
150 vector<AliHLTDataSegment> fSegments; // see above
152 //ClassDef(AliHLTConsumerDescriptor, 0)
156 * @class AliHLTDataBuffer
157 * @brief Handling of data buffers for the HLT.
159 * The class provides handling of data buffers for HLT tasks. Each task gets
160 * its own Data Buffer instance. The buffer is grouped into different data
161 * segments according to the output of the component.<br>
162 * The Data Buffer keeps control over the data requests of the 'child'
163 * components. Each component can subscribe to a certain segment of the data
164 * buffer. It's state is then changed from 'reserved' to 'active'. After the
165 * data processing, the component has to release the segment and it's state is
166 * set to 'processed'. If all components have requested and released their data,
167 * the Raw Buffer is released and pushed back in the list of available buffers.
169 * @note This class is only used for the @ref alihlt_system.
171 * @ingroup alihlt_system
173 class AliHLTDataBuffer : public TObject, public AliHLTLogging {
175 //////////////////////////////////////////////////////////////////////////////
176 // condtructors and destructors
178 /* standard constructor
181 /** not a valid copy constructor, defined according to effective C++ style */
182 AliHLTDataBuffer(const AliHLTDataBuffer&);
183 /** not a valid assignment op, but defined according to effective C++ style */
184 AliHLTDataBuffer& operator=(const AliHLTDataBuffer&);
186 virtual ~AliHLTDataBuffer();
188 //////////////////////////////////////////////////////////////////////////////
192 * Add component to the list of consumers
193 * @param pConsumer - a consumer of type AliHLTComponent
195 int SetConsumer(AliHLTComponent* pConsumer);
197 //////////////////////////////////////////////////////////////////////////////
198 // component to component communication
201 * Determine the number of matching data blocks for the component and a
202 * consumer component. <br>
203 * The first approach will support only one output data type for processing
205 * @param pConsumer the component which subscribes to the buffer
206 * @param tgtList (optional) the list to receive the data types
207 * @return: number of data blocks which match the input data types
208 * of the consumer, neg. error code if failed <br>
209 * -EINVAL invalid parameter <br>
211 int FindMatchingDataBlocks(const AliHLTComponent* pConsumer,
212 vector<AliHLTComponentDataType>* tgtList=NULL);
215 * Subscribe to a segment of the data buffer.
216 * The function prepares the block descriptor for subsequent use with the
217 * AliHLTComponent::ProcessEvent method, the method can prepare several block
218 * descriptors up to the array size specified by iArraySize. The return value
219 * is independent from the array size the number of block descriptors which
220 * would have been prepared if there was enough space in the array<br>
221 * The method is used by the consumer component.
222 * @param pConsumer the component which subscribes to the buffer
223 * @param arrayBlockDesc pointer to block descriptor to be filled
224 * @param iArraySize size of the block descriptor array
225 * @return: number of matching data blocks, neg. error code if failed<br>
226 * -EACCESS the consumer state can't be changed (activated)
227 * -EBADF unresolved data segments <br>
228 * -ENOENT consumer component not found <br>
229 * -ENODATA data buffer does not have raw data <br>
230 * -EINVAL invalid parameter <br>
232 int Subscribe(const AliHLTComponent* pConsumer,
233 AliHLTComponentBlockData* arrayBlockDesc,
237 * Release an instance of the data buffer.
238 * Resets the variables of the block descriptor.
239 * If all buffer segments are released, the Data Buffer is reseted
240 * and the Raw Buffer released.<br>
241 * The method is used by the consumer component.
242 * @param pBlockDesc descriptor of the data segment
243 * @param pConsumer the component which subscribes to the buffer
244 * @return: >0 if success, negative error code if failed <br>
245 * -EACCESS the consumer state can not be changed (de-activated)
246 * -ENOENT consumer has not subscribed to the buffer <br>
247 * -EINVAL invalid parameter <br>
249 int Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer);
252 * Get a target buffer of minimum size iMinSize.
253 * The method is used by the component which owns the Data Buffer to
254 * allocate a buffer for the data it is going to produce.
255 * @param iMinSize minumum size of the requested buffer
256 * @return: pointer to target buffer if
258 AliHLTUInt8_t* GetTargetBuffer(int iMinSize);
261 * Set the segments for the data buffer.
262 * This is usually done after the component has written the data to the buffer,
263 * which was requested by the @ref GetTargetBuffer method. The component might
264 * produce different types of data, for each type a segment has to be defined
265 * which describes the data inside the buffer.<br>
266 * The @ref AliHLTComponentBlockData segment descriptor comes directly from
267 * the @ref AliHLTComponent::ProcessEvent method.
268 * @param pTgt the target buffer which the segments refer to
269 * @param arraySegments the output block descriptors of the component
270 * @param iSize size of the array
272 int SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arraySegments, int iSize);
275 * Check if the data buffer is empty.
276 * @return 1 if empty, 0 if not
281 * Get the total and maximum size of the buffer.
282 * Lets see if this is needed later
284 //int GetTotalSize();
287 * Get the number of segments
288 * @return number of segments
290 int GetNofSegments();
293 * Get the number of consumers
294 * @return number of consumers
296 int GetNofConsumers();
299 * Get the number of active consumers
300 * @return number of active consumers
302 int GetNofActiveConsumers();
305 * Check if a consumer is already in the list
306 * @param pConsumer pointer to consumer component
307 * @param bAllLists search in all lists if 1
308 * search only in fConsumer list if 0
309 * @return 1 if found, 0 if not
311 int FindConsumer(AliHLTComponent* pConsumer, int bAllLists=1);
314 * Public method to reset the buffer.
315 * Eventually with some additional checks. In normal operation,
316 * an external reset should not be necessary.
321 /* lets see if this is needed
322 AliHLTDataSegment* FindDataSegment(AliHLTComponentDataType datatype);
326 * Find those data segments which match the input types of a component.
327 * @param pConsumer the component which subscribes to the buffer
328 * @param tgtList the list to receive the data segment descriptors
329 * @return: number of data blocks which match the input data types
330 * of the consumer, neg. error code if failed <br>
331 * -EINVAL invalid parameter <br>
333 int FindMatchingDataSegments(const AliHLTComponent* pConsumer, vector<AliHLTDataSegment>& tgtList);
336 * Reset the data buffer.
337 * Removes all consumers back to the @ref fConsumers list, deletes
338 * segments and releases the Raw Buffer.
340 int ResetDataBuffer();
342 //////////////////////////////////////////////////////////////////////////////
344 // the data description
346 // the data segments within this buffer
347 vector<AliHLTDataSegment> fSegments; // see above
349 // the list of all consumers which are going to subscribe to the buffer
350 vector<AliHLTConsumerDescriptor*> fConsumers; // see above
351 // the list of all consumers which are currently subscribed to the buffer
352 vector<AliHLTConsumerDescriptor*> fActiveConsumers; // see above
353 // the list of all consumers which are already released for the current event
354 vector<AliHLTConsumerDescriptor*> fReleasedConsumers; // see above
356 // the buffer instance
357 AliHLTRawBuffer* fpBuffer; //! transient
359 // flags indicating the state of the buffer
360 AliHLTUInt32_t fFlags; // see above
362 //////////////////////////////////////////////////////////////////////////////
363 // global buffer handling, internal use only
366 * Create a raw buffer of a certain size.
367 * The function tries to find a buffer of the given size (or a bit bigger by a
368 * certain margin @ref fMargin) from the list of free buffers.
369 * If no buffer is available, a new one is created and added to the buffer handling.
370 * @param size min. size of the requested buffer
371 * @return pointer to raw buffer
373 static AliHLTRawBuffer* CreateRawBuffer(AliHLTUInt32_t size);
376 * Mark a buffer as free.
377 * After the Data Buffer has finnished using the raw buffer, it is released
378 * and added to the list of available buffers.
379 * @param pBuffer the raw buffer to release
380 * @return >=0 if succeeded, neg. error code if failed
382 static int ReleaseRawBuffer(AliHLTRawBuffer* pBuffer);
385 * Deletes all the raw buffers.
386 * When the last Data Buffer object is destructed, all raw data buffers are
389 static int DeleteRawBuffers();
392 * Number of instances of AliHLTDataBuffer.
393 * The statice variable is incremented and decremented in the constructor/
394 * destructor. All internal data structures are cleaned up when the last
395 * instance is exiting.
397 static int fgNofInstances; // see above
398 /** global list of free raw buffers */
399 static vector<AliHLTRawBuffer*> fgFreeBuffers; // see above
400 /** global list of currently active raw buffers */
401 static vector<AliHLTRawBuffer*> fgActiveBuffers; // see above
402 /** determines the raw buffer size margin at buffer requests */
403 static AliHLTUInt32_t fgMargin; // see above
405 /** global instance to HLT logging class for static methods */
406 static AliHLTLogging fgLogging; // see above
408 //////////////////////////////////////////////////////////////////////////////
409 // internal helper functions
412 * Find the consumer descriptor for a certain component and data type in
413 * a list of consumers.<br>
414 * <b>Note:</b> There are three lists which contain the consumers in the
416 * @param pConsumer pointer to consumer component
417 * @param list list where to search for the consumer
419 AliHLTConsumerDescriptor* FindConsumer(const AliHLTComponent* pConsumer,
420 vector<AliHLTConsumerDescriptor*> &list) const;
423 * Change the state of a consumer.
424 * The state of a consumer is determined by the list it is strored in, the
425 * method moves a consumer from the source to the target list.
426 * @param pDesc pointer to consumer descriptor
427 * @param srcList list where the consumer is currently to be found
428 * @param tgtList list where to move the consumer
430 int ChangeConsumerState(AliHLTConsumerDescriptor* pDesc,
431 vector<AliHLTConsumerDescriptor*> &srcList,
432 vector<AliHLTConsumerDescriptor*> &tgtList);
435 * Cleanup a consumer list.
436 * Release all allocated data structures. <b>Note:</b> Not the component itself!
438 int CleanupConsumerList();
440 ClassDef(AliHLTDataBuffer, 0)
442 #endif // ALIHLTDATABUFFER_H