bugfix: static member was not implemented
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataBuffer.h
CommitLineData
3f2a1b1c 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
b22e91eb 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*/
3f2a1b1c 14
15#include <cerrno>
8ede8717 16#include <vector>
3f2a1b1c 17#include "AliHLTLogging.h"
18#include "AliHLTDataTypes.h"
19#include "AliHLTDefinitions.h"
3f2a1b1c 20#include "TObject.h"
70ed7d01 21//#include "TList.h"
3f2a1b1c 22
b22e91eb 23class AliHLTComponent;
0c0c9d99 24/* @name internal data structures
25 */
26
b22e91eb 27/**
28 * @struct AliHLTDataSegment
29 * @brief Descriptor of a data segment within the buffer.
30 * @ingroup alihlt_system
3f2a1b1c 31 */
32struct AliHLTDataSegment {
0c0c9d99 33 AliHLTDataSegment()
85869391 34 :
35 fDataType(),
36 fSegmentOffset(0),
37 fSegmentSize(0),
38 fSpecification(0)
0c0c9d99 39 {
8ede8717 40 memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
0c0c9d99 41 }
42 AliHLTDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
85869391 43 :
44 fDataType(),
45 fSegmentOffset(offset),
46 fSegmentSize(size),
47 fSpecification(0)
0c0c9d99 48 {
8ede8717 49 memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
0c0c9d99 50 }
b22e91eb 51 /** the data type of this segment */
70ed7d01 52 AliHLTComponentDataType fDataType; // see above
b22e91eb 53 /** offset in byte within the data buffer */
70ed7d01 54 AliHLTUInt32_t fSegmentOffset; // see above
b22e91eb 55 /** size of the actual content */
70ed7d01 56 AliHLTUInt32_t fSegmentSize; // see above
b22e91eb 57 /** data specification */
70ed7d01 58 AliHLTUInt32_t fSpecification; // see above
3f2a1b1c 59};
60
b22e91eb 61/**
62 * @struct AliHLTRawBuffer
63 * @brief Descriptor of the raw data buffer which can host several segments.
64 * @ingroup alihlt_system
3f2a1b1c 65 */
66struct AliHLTRawBuffer {
b22e91eb 67 /** size of the currently occupied partition of the buffer */
70ed7d01 68 AliHLTUInt32_t fSize; // see above
b22e91eb 69 /** total size of the buffer, including safety margin */
70ed7d01 70 AliHLTUInt32_t fTotalSize; // see above
b22e91eb 71 /** the buffer */
70ed7d01 72 void* fPtr; //! transient
3f2a1b1c 73};
74
b22e91eb 75/**
76 * @class AliHLTConsumerDescriptor
77 * @brief Helper class to describe a consumer component.
78 *
70ed7d01 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
82 * bookkeeping easier.
b22e91eb 83 *
84 * @note This class is only used for the @ref alihlt_system.
85 *
86 * @ingroup alihlt_system
3f2a1b1c 87 */
53feaef5 88class AliHLTConsumerDescriptor : public TObject, public AliHLTLogging {
3f2a1b1c 89 public:
0c0c9d99 90 /** standard constructur */
3f2a1b1c 91 AliHLTConsumerDescriptor();
0c0c9d99 92 /** constructur
93 * @param pConsumer pointer to the consumer component
94 */
95 AliHLTConsumerDescriptor(AliHLTComponent* pConsumer);
85869391 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&);
100 /** destructor */
3f2a1b1c 101 ~AliHLTConsumerDescriptor();
102
0c0c9d99 103 /**
70ed7d01 104 * Get the component of this descriptor.
0c0c9d99 105 * @return pointer to the component
106 */
3f2a1b1c 107 AliHLTComponent* GetComponent() {return fpConsumer;}
3f2a1b1c 108
0c0c9d99 109 /**
70ed7d01 110 * Set an active data segment.
111 * the pointer will be handled in a container, no allocation, copy or
112 * cleanup.
bfccbf68 113 * @param offset offset of the segment in the buffer
114 * @param size size of the segment in the buffer
0c0c9d99 115 * @return >=0 if succeeded
116 */
117 int SetActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
118
119 /**
70ed7d01 120 * Check whether there is an active data segment of certain size with
121 * certain offset.
0c0c9d99 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 */
3f2a1b1c 126 int CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
0c0c9d99 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
70ed7d01 145 private:
146 /** consumer object */
147 AliHLTComponent* fpConsumer; //! transient
148
149 /** list of data segments */
150 vector<AliHLTDataSegment> fSegments; // see above
151
0c0c9d99 152 //ClassDef(AliHLTConsumerDescriptor, 0)
3f2a1b1c 153};
154
0c0c9d99 155/**
bfccbf68 156 * @class AliHLTDataBuffer
157 * @brief Handling of data buffers for the HLT.
b22e91eb 158 *
70ed7d01 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.
b22e91eb 168 *
169 * @note This class is only used for the @ref alihlt_system.
170 *
171 * @ingroup alihlt_system
0c0c9d99 172 */
53feaef5 173class AliHLTDataBuffer : public TObject, public AliHLTLogging {
3f2a1b1c 174 public:
70ed7d01 175 //////////////////////////////////////////////////////////////////////////////
0c0c9d99 176 // condtructors and destructors
177
178 /* standard constructor
179 */
3f2a1b1c 180 AliHLTDataBuffer();
85869391 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&);
185 /** destructor */
3f2a1b1c 186 virtual ~AliHLTDataBuffer();
187
70ed7d01 188 //////////////////////////////////////////////////////////////////////////////
3f2a1b1c 189 // initialization
190
0c0c9d99 191 /**
192 * Add component to the list of consumers
193 * @param pConsumer - a consumer of type AliHLTComponent
3f2a1b1c 194 */
0c0c9d99 195 int SetConsumer(AliHLTComponent* pConsumer);
3f2a1b1c 196
70ed7d01 197 //////////////////////////////////////////////////////////////////////////////
3f2a1b1c 198 // component to component communication
199
0c0c9d99 200 /**
70ed7d01 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
204 * components.
0c0c9d99 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>
3f2a1b1c 210 */
70ed7d01 211 int FindMatchingDataBlocks(const AliHLTComponent* pConsumer,
212 vector<AliHLTComponentDataType>* tgtList=NULL);
0c0c9d99 213
214 /**
215 * Subscribe to a segment of the data buffer.
70ed7d01 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>
0c0c9d99 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
70ed7d01 225 * @return: number of matching data blocks, neg. error code if failed<br>
226 * -EACCESS the consumer state can't be changed (activated)
0c0c9d99 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>
231 */
70ed7d01 232 int Subscribe(const AliHLTComponent* pConsumer,
233 AliHLTComponentBlockData* arrayBlockDesc,
234 int iArraySize);
0c0c9d99 235
236 /**
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>
70ed7d01 245 * -EACCESS the consumer state can not be changed (de-activated)
246 * -ENOENT consumer has not subscribed to the buffer <br>
0c0c9d99 247 * -EINVAL invalid parameter <br>
3f2a1b1c 248 */
8ede8717 249 int Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer);
3f2a1b1c 250
0c0c9d99 251 /**
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
3f2a1b1c 257 */
258 AliHLTUInt8_t* GetTargetBuffer(int iMinSize);
259
0c0c9d99 260 /**
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
2d7ff710 265 * which describes the data inside the buffer.<br>
70ed7d01 266 * The @ref AliHLTComponentBlockData segment descriptor comes directly from
267 * the @ref AliHLTComponent::ProcessEvent method.
0c0c9d99 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
3f2a1b1c 271 */
8ede8717 272 int SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arraySegments, int iSize);
3f2a1b1c 273
0c0c9d99 274 /**
275 * Check if the data buffer is empty.
276 * @return 1 if empty, 0 if not
3f2a1b1c 277 */
278 int IsEmpty();
279
0c0c9d99 280 /**
281 * Get the total and maximum size of the buffer.
282 * Lets see if this is needed later
3f2a1b1c 283 */
284 //int GetTotalSize();
285
0c0c9d99 286 /**
287 * Get the number of segments
288 * @return number of segments
3f2a1b1c 289 */
290 int GetNofSegments();
291
0c0c9d99 292 /**
293 * Get the number of consumers
294 * @return number of consumers
3f2a1b1c 295 */
296 int GetNofConsumers();
297
0c0c9d99 298 /**
299 * Get the number of active consumers
300 * @return number of active consumers
3f2a1b1c 301 */
302 int GetNofActiveConsumers();
303
9ce4bf4a 304 /**
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
310 */
311 int FindConsumer(AliHLTComponent* pConsumer, int bAllLists=1);
312
313 /**
314 * Public method to reset the buffer.
315 * Eventually with some additional checks. In normal operation,
316 * an external reset should not be necessary.
317 */
318 int Reset();
319
3f2a1b1c 320 private:
0c0c9d99 321 /* lets see if this is needed
8ede8717 322 AliHLTDataSegment* FindDataSegment(AliHLTComponentDataType datatype);
0c0c9d99 323 */
324
325 /**
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>
332 */
333 int FindMatchingDataSegments(const AliHLTComponent* pConsumer, vector<AliHLTDataSegment>& tgtList);
3f2a1b1c 334
0c0c9d99 335 /**
336 * Reset the data buffer.
9ce4bf4a 337 * Removes all consumers back to the @ref fConsumers list, deletes
338 * segments and releases the Raw Buffer.
3f2a1b1c 339 */
340 int ResetDataBuffer();
341
70ed7d01 342 //////////////////////////////////////////////////////////////////////////////
343
3f2a1b1c 344 // the data description
3f2a1b1c 345
0c0c9d99 346 // the data segments within this buffer
70ed7d01 347 vector<AliHLTDataSegment> fSegments; // see above
3f2a1b1c 348
0c0c9d99 349 // the list of all consumers which are going to subscribe to the buffer
70ed7d01 350 vector<AliHLTConsumerDescriptor*> fConsumers; // see above
0c0c9d99 351 // the list of all consumers which are currently subscribed to the buffer
70ed7d01 352 vector<AliHLTConsumerDescriptor*> fActiveConsumers; // see above
0c0c9d99 353 // the list of all consumers which are already released for the current event
70ed7d01 354 vector<AliHLTConsumerDescriptor*> fReleasedConsumers; // see above
3f2a1b1c 355
0c0c9d99 356 // the buffer instance
70ed7d01 357 AliHLTRawBuffer* fpBuffer; //! transient
3f2a1b1c 358
0c0c9d99 359 // flags indicating the state of the buffer
70ed7d01 360 AliHLTUInt32_t fFlags; // see above
3f2a1b1c 361
70ed7d01 362 //////////////////////////////////////////////////////////////////////////////
0c0c9d99 363 // global buffer handling, internal use only
364
365 /**
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
9ddaea75 368 * certain margin @ref fgMargin) from the list of free buffers.
0c0c9d99 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
3f2a1b1c 372 */
373 static AliHLTRawBuffer* CreateRawBuffer(AliHLTUInt32_t size);
374
0c0c9d99 375 /**
376 * Mark a buffer as free.
70ed7d01 377 * After the Data Buffer has finnished using the raw buffer, it is released
378 * and added to the list of available buffers.
0c0c9d99 379 * @param pBuffer the raw buffer to release
380 * @return >=0 if succeeded, neg. error code if failed
3f2a1b1c 381 */
382 static int ReleaseRawBuffer(AliHLTRawBuffer* pBuffer);
383
0c0c9d99 384 /**
385 * Deletes all the raw buffers.
70ed7d01 386 * When the last Data Buffer object is destructed, all raw data buffers are
387 * relesed.
3f2a1b1c 388 */
389 static int DeleteRawBuffers();
390
0c0c9d99 391 /**
392 * Number of instances of AliHLTDataBuffer.
70ed7d01 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.
0c0c9d99 396 */
70ed7d01 397 static int fgNofInstances; // see above
0c0c9d99 398 /** global list of free raw buffers */
70ed7d01 399 static vector<AliHLTRawBuffer*> fgFreeBuffers; // see above
0c0c9d99 400 /** global list of currently active raw buffers */
70ed7d01 401 static vector<AliHLTRawBuffer*> fgActiveBuffers; // see above
0c0c9d99 402 /** determines the raw buffer size margin at buffer requests */
70ed7d01 403 static AliHLTUInt32_t fgMargin; // see above
3f2a1b1c 404
0c0c9d99 405 /** global instance to HLT logging class for static methods */
70ed7d01 406 static AliHLTLogging fgLogging; // see above
3f2a1b1c 407
70ed7d01 408 //////////////////////////////////////////////////////////////////////////////
0c0c9d99 409 // internal helper functions
410
411 /**
412 * Find the consumer descriptor for a certain component and data type in
413 * a list of consumers.<br>
70ed7d01 414 * <b>Note:</b> There are three lists which contain the consumers in the
415 * different states.
0c0c9d99 416 * @param pConsumer pointer to consumer component
417 * @param list list where to search for the consumer
418 */
70ed7d01 419 AliHLTConsumerDescriptor* FindConsumer(const AliHLTComponent* pConsumer,
420 vector<AliHLTConsumerDescriptor*> &list) const;
0c0c9d99 421
422 /**
423 * Change the state of a consumer.
70ed7d01 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.
0c0c9d99 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
429 */
70ed7d01 430 int ChangeConsumerState(AliHLTConsumerDescriptor* pDesc,
431 vector<AliHLTConsumerDescriptor*> &srcList,
432 vector<AliHLTConsumerDescriptor*> &tgtList);
3f2a1b1c 433
0c0c9d99 434 /**
435 * Cleanup a consumer list.
436 * Release all allocated data structures. <b>Note:</b> Not the component itself!
437 */
3f2a1b1c 438 int CleanupConsumerList();
439
440 ClassDef(AliHLTDataBuffer, 0)
441};
442#endif // ALIHLTDATABUFFER_H