]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTDataBuffer.h
first sketch of the HLTOUT handler
[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
30338a30 15// see below for class documentation
16// or
17// refer to README to build package
18// or
19// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
20
8ede8717 21#include <vector>
2be3f004 22#include "TObject.h"
3f2a1b1c 23#include "AliHLTLogging.h"
24#include "AliHLTDataTypes.h"
2be3f004 25#include "AliHLTComponent.h"
3f2a1b1c 26
6235cd38 27class AliHLTConsumerDescriptor;
3f2a1b1c 28
2be3f004 29/** list of AliHLTConsumerDescriptor pointers */
30typedef vector<AliHLTConsumerDescriptor*> AliHLTConsumerDescriptorPList;
31
0c0c9d99 32/**
bfccbf68 33 * @class AliHLTDataBuffer
34 * @brief Handling of data buffers for the HLT.
b22e91eb 35 *
70ed7d01 36 * The class provides handling of data buffers for HLT tasks. Each task gets
37 * its own Data Buffer instance. The buffer is grouped into different data
38 * segments according to the output of the component.<br>
39 * The Data Buffer keeps control over the data requests of the 'child'
40 * components. Each component can subscribe to a certain segment of the data
41 * buffer. It's state is then changed from 'reserved' to 'active'. After the
42 * data processing, the component has to release the segment and it's state is
43 * set to 'processed'. If all components have requested and released their data,
44 * the Raw Buffer is released and pushed back in the list of available buffers.
b22e91eb 45 *
46 * @note This class is only used for the @ref alihlt_system.
47 *
48 * @ingroup alihlt_system
0c0c9d99 49 */
6235cd38 50class AliHLTDataBuffer : public TObject, public AliHLTLogging
51{
3f2a1b1c 52 public:
70ed7d01 53 //////////////////////////////////////////////////////////////////////////////
6235cd38 54 // constructors and destructors
0c0c9d99 55
56 /* standard constructor
57 */
3f2a1b1c 58 AliHLTDataBuffer();
85869391 59 /** destructor */
3f2a1b1c 60 virtual ~AliHLTDataBuffer();
61
70ed7d01 62 //////////////////////////////////////////////////////////////////////////////
3f2a1b1c 63 // initialization
64
0c0c9d99 65 /**
66 * Add component to the list of consumers
67 * @param pConsumer - a consumer of type AliHLTComponent
3f2a1b1c 68 */
0c0c9d99 69 int SetConsumer(AliHLTComponent* pConsumer);
3f2a1b1c 70
70ed7d01 71 //////////////////////////////////////////////////////////////////////////////
3f2a1b1c 72 // component to component communication
73
0c0c9d99 74 /**
70ed7d01 75 * Determine the number of matching data blocks for the component and a
76 * consumer component. <br>
77 * The first approach will support only one output data type for processing
78 * components.
0c0c9d99 79 * @param pConsumer the component which subscribes to the buffer
80 * @param tgtList (optional) the list to receive the data types
81 * @return: number of data blocks which match the input data types
82 * of the consumer, neg. error code if failed <br>
83 * -EINVAL invalid parameter <br>
3f2a1b1c 84 */
70ed7d01 85 int FindMatchingDataBlocks(const AliHLTComponent* pConsumer,
2be3f004 86 AliHLTComponentDataTypeList* tgtList=NULL);
0c0c9d99 87
88 /**
89 * Subscribe to a segment of the data buffer.
70ed7d01 90 * The function prepares the block descriptor for subsequent use with the
91 * AliHLTComponent::ProcessEvent method, the method can prepare several block
92 * descriptors up to the array size specified by iArraySize. The return value
93 * is independent from the array size the number of block descriptors which
94 * would have been prepared if there was enough space in the array<br>
0c0c9d99 95 * The method is used by the consumer component.
96 * @param pConsumer the component which subscribes to the buffer
97 * @param arrayBlockDesc pointer to block descriptor to be filled
98 * @param iArraySize size of the block descriptor array
70ed7d01 99 * @return: number of matching data blocks, neg. error code if failed<br>
100 * -EACCESS the consumer state can't be changed (activated)
0c0c9d99 101 * -EBADF unresolved data segments <br>
102 * -ENOENT consumer component not found <br>
103 * -ENODATA data buffer does not have raw data <br>
104 * -EINVAL invalid parameter <br>
105 */
70ed7d01 106 int Subscribe(const AliHLTComponent* pConsumer,
107 AliHLTComponentBlockData* arrayBlockDesc,
108 int iArraySize);
0c0c9d99 109
110 /**
111 * Release an instance of the data buffer.
112 * Resets the variables of the block descriptor.
113 * If all buffer segments are released, the Data Buffer is reseted
114 * and the Raw Buffer released.<br>
115 * The method is used by the consumer component.
116 * @param pBlockDesc descriptor of the data segment
117 * @param pConsumer the component which subscribes to the buffer
118 * @return: >0 if success, negative error code if failed <br>
70ed7d01 119 * -EACCESS the consumer state can not be changed (de-activated)
120 * -ENOENT consumer has not subscribed to the buffer <br>
0c0c9d99 121 * -EINVAL invalid parameter <br>
3f2a1b1c 122 */
8ede8717 123 int Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer);
3f2a1b1c 124
0c0c9d99 125 /**
126 * Get a target buffer of minimum size iMinSize.
127 * The method is used by the component which owns the Data Buffer to
128 * allocate a buffer for the data it is going to produce.
129 * @param iMinSize minumum size of the requested buffer
130 * @return: pointer to target buffer if
3f2a1b1c 131 */
132 AliHLTUInt8_t* GetTargetBuffer(int iMinSize);
133
0c0c9d99 134 /**
135 * Set the segments for the data buffer.
136 * This is usually done after the component has written the data to the buffer,
137 * which was requested by the @ref GetTargetBuffer method. The component might
138 * produce different types of data, for each type a segment has to be defined
2d7ff710 139 * which describes the data inside the buffer.<br>
70ed7d01 140 * The @ref AliHLTComponentBlockData segment descriptor comes directly from
141 * the @ref AliHLTComponent::ProcessEvent method.
0c0c9d99 142 * @param pTgt the target buffer which the segments refer to
143 * @param arraySegments the output block descriptors of the component
144 * @param iSize size of the array
3f2a1b1c 145 */
8ede8717 146 int SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arraySegments, int iSize);
3f2a1b1c 147
0c0c9d99 148 /**
149 * Check if the data buffer is empty.
150 * @return 1 if empty, 0 if not
3f2a1b1c 151 */
152 int IsEmpty();
153
0c0c9d99 154 /**
155 * Get the total and maximum size of the buffer.
156 * Lets see if this is needed later
3f2a1b1c 157 */
158 //int GetTotalSize();
159
0c0c9d99 160 /**
161 * Get the number of segments
162 * @return number of segments
3f2a1b1c 163 */
164 int GetNofSegments();
165
0c0c9d99 166 /**
b426991e 167 * Get the total number of consumers.
168 * This gives the number of consumers regardless of their state.
0c0c9d99 169 * @return number of consumers
3f2a1b1c 170 */
171 int GetNofConsumers();
172
0c0c9d99 173 /**
b426991e 174 * Get the number of consumers which still need to be processed during
175 * the current event.
176 * @return number of consumers
177 */
178 int GetNofPendingConsumers();
179
180 /**
181 * Get the number of consumers currently under processing.
0c0c9d99 182 * @return number of active consumers
3f2a1b1c 183 */
184 int GetNofActiveConsumers();
185
9ce4bf4a 186 /**
187 * Check if a consumer is already in the list
188 * @param pConsumer pointer to consumer component
189 * @param bAllLists search in all lists if 1
190 * search only in fConsumer list if 0
191 * @return 1 if found, 0 if not
192 */
193 int FindConsumer(AliHLTComponent* pConsumer, int bAllLists=1);
194
195 /**
196 * Public method to reset the buffer.
197 * Eventually with some additional checks. In normal operation,
198 * an external reset should not be necessary.
199 */
200 int Reset();
201
6235cd38 202 /**
965919c8 203 * @class AliHLTDataSegment
6235cd38 204 * @brief Descriptor of a data segment within the buffer.
205 */
66043029 206 class AliHLTDataSegment {
5df0cbb9 207 friend class AliHLTDataBuffer;
208 friend class AliHLTConsumerDescriptor;
66043029 209 public:
6235cd38 210 AliHLTDataSegment()
211 :
212 fDataType(),
213 fSegmentOffset(0),
214 fSegmentSize(0),
215 fSpecification(0)
216 {
217 memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
218 }
219 AliHLTDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
220 :
221 fDataType(),
222 fSegmentOffset(offset),
223 fSegmentSize(size),
224 fSpecification(0)
225 {
226 memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
227 }
2be3f004 228
5df0cbb9 229 private:
6235cd38 230 /** the data type of this segment */
231 AliHLTComponentDataType fDataType; // see above
232 /** offset in byte within the data buffer */
233 AliHLTUInt32_t fSegmentOffset; // see above
234 /** size of the actual content */
235 AliHLTUInt32_t fSegmentSize; // see above
236 /** data specification */
237 AliHLTUInt32_t fSpecification; // see above
238 };
239
240 /**
965919c8 241 * @class AliHLTRawBuffer
6235cd38 242 * @brief Descriptor of the raw data buffer which can host several segments.
243 */
66043029 244 class AliHLTRawBuffer {
245 public:
246 /** standard constructor */
247 AliHLTRawBuffer() : fSize(0), fTotalSize(0), fPtr(NULL) {}
d6cbe999 248 /** constructor */
249 AliHLTRawBuffer(AliHLTUInt32_t size);
250 /** destructor */
251 virtual ~AliHLTRawBuffer();
252
253 /**
254 * Use a fraction of the buffer.
255 * @param size size in bytes to be used
256 * @return pointer to buffer
257 */
258 AliHLTUInt8_t* UseBuffer(AliHLTUInt32_t size);
259
260 /**
261 * Check whether buffer fits for a request.
262 * @param size size of the request in bytes
263 * @return 1 if buffer is big enough, 0 if not
264 */
265 int CheckSize(AliHLTUInt32_t size) const;
266
c0a2bfc2 267 /**
268 * Get used size of the buffer
269 */
270 AliHLTUInt32_t GetUsedSize() const {return fSize;}
271
d6cbe999 272 /**
273 * Get total size of the buffer
274 */
275 AliHLTUInt32_t GetTotalSize() const {return fTotalSize;}
276
c0a2bfc2 277 /**
278 * Get pointer of data buffer
279 */
280 AliHLTUInt8_t* GetPointer() const {return fPtr;}
281
d6cbe999 282 /**
283 * Write check pattern
284 */
285 int WritePattern(const char* pattern, int size);
286
287 /**
288 * Check pattern
289 */
290 int CheckPattern(const char* pattern, int size) const;
291
292 /**
293 * Reset buffer.
294 * Data buffer remains allocated, used size set to 0
295 */
296 int Reset();
1e6e67ec 297
3a7c0444 298 int operator==(void*) const;
299 int operator==(AliHLTUInt8_t* ptr) const {return fPtr==ptr;}
300 int operator<=(void*) const;
301 int operator>(void*) const;
302 int operator-(void*) const;
1e6e67ec 303
3a7c0444 304 operator void*() const {return fPtr;}
305 operator AliHLTUInt8_t*() const {return fPtr;}
1e6e67ec 306
5df0cbb9 307 private:
d6cbe999 308 /** copy constructor prohibited */
309 AliHLTRawBuffer(const AliHLTRawBuffer&);
310 /** assignment operator prohibited */
311 AliHLTRawBuffer& operator=(const AliHLTRawBuffer&);
312
6235cd38 313 /** size of the currently occupied partition of the buffer */
314 AliHLTUInt32_t fSize; // see above
315 /** total size of the buffer, including safety margin */
316 AliHLTUInt32_t fTotalSize; // see above
317 /** the buffer */
1e6e67ec 318 AliHLTUInt8_t* fPtr; //! transient
6235cd38 319 };
320
3f2a1b1c 321 private:
b426991e 322 /** copy constructor prohibited */
323 AliHLTDataBuffer(const AliHLTDataBuffer&);
324 /** assignment operator prohibited */
325 AliHLTDataBuffer& operator=(const AliHLTDataBuffer&);
326
0c0c9d99 327 /* lets see if this is needed
6235cd38 328 AliHLTDataSegment* FindDataSegment(AliHLTComponentDataType datatype);
0c0c9d99 329 */
330
331 /**
332 * Find those data segments which match the input types of a component.
333 * @param pConsumer the component which subscribes to the buffer
334 * @param tgtList the list to receive the data segment descriptors
335 * @return: number of data blocks which match the input data types
336 * of the consumer, neg. error code if failed <br>
337 * -EINVAL invalid parameter <br>
338 */
90ebac25 339 int FindMatchingDataSegments(const AliHLTComponent* pConsumer,
340 vector<AliHLTDataBuffer::AliHLTDataSegment>& tgtList);
3f2a1b1c 341
0c0c9d99 342 /**
343 * Reset the data buffer.
9ce4bf4a 344 * Removes all consumers back to the @ref fConsumers list, deletes
345 * segments and releases the Raw Buffer.
3f2a1b1c 346 */
347 int ResetDataBuffer();
348
70ed7d01 349 //////////////////////////////////////////////////////////////////////////////
350
3f2a1b1c 351 // the data description
3f2a1b1c 352
0c0c9d99 353 // the data segments within this buffer
70ed7d01 354 vector<AliHLTDataSegment> fSegments; // see above
3f2a1b1c 355
0c0c9d99 356 // the list of all consumers which are going to subscribe to the buffer
2be3f004 357 AliHLTConsumerDescriptorPList fConsumers; // see above
0c0c9d99 358 // the list of all consumers which are currently subscribed to the buffer
2be3f004 359 AliHLTConsumerDescriptorPList fActiveConsumers; // see above
0c0c9d99 360 // the list of all consumers which are already released for the current event
2be3f004 361 AliHLTConsumerDescriptorPList fReleasedConsumers; // see above
3f2a1b1c 362
0c0c9d99 363 // the buffer instance
70ed7d01 364 AliHLTRawBuffer* fpBuffer; //! transient
3f2a1b1c 365
0c0c9d99 366 // flags indicating the state of the buffer
70ed7d01 367 AliHLTUInt32_t fFlags; // see above
3f2a1b1c 368
70ed7d01 369 //////////////////////////////////////////////////////////////////////////////
0c0c9d99 370 // global buffer handling, internal use only
371
372 /**
373 * Create a raw buffer of a certain size.
374 * The function tries to find a buffer of the given size (or a bit bigger by a
9ddaea75 375 * certain margin @ref fgMargin) from the list of free buffers.
0c0c9d99 376 * If no buffer is available, a new one is created and added to the buffer handling.
377 * @param size min. size of the requested buffer
378 * @return pointer to raw buffer
3f2a1b1c 379 */
380 static AliHLTRawBuffer* CreateRawBuffer(AliHLTUInt32_t size);
381
0c0c9d99 382 /**
383 * Mark a buffer as free.
70ed7d01 384 * After the Data Buffer has finnished using the raw buffer, it is released
385 * and added to the list of available buffers.
0c0c9d99 386 * @param pBuffer the raw buffer to release
387 * @return >=0 if succeeded, neg. error code if failed
3f2a1b1c 388 */
389 static int ReleaseRawBuffer(AliHLTRawBuffer* pBuffer);
390
0c0c9d99 391 /**
392 * Deletes all the raw buffers.
70ed7d01 393 * When the last Data Buffer object is destructed, all raw data buffers are
394 * relesed.
3f2a1b1c 395 */
396 static int DeleteRawBuffers();
397
0c0c9d99 398 /**
399 * Number of instances of AliHLTDataBuffer.
70ed7d01 400 * The statice variable is incremented and decremented in the constructor/
401 * destructor. All internal data structures are cleaned up when the last
402 * instance is exiting.
0c0c9d99 403 */
70ed7d01 404 static int fgNofInstances; // see above
0c0c9d99 405 /** global list of free raw buffers */
70ed7d01 406 static vector<AliHLTRawBuffer*> fgFreeBuffers; // see above
0c0c9d99 407 /** global list of currently active raw buffers */
70ed7d01 408 static vector<AliHLTRawBuffer*> fgActiveBuffers; // see above
0c0c9d99 409 /** determines the raw buffer size margin at buffer requests */
70ed7d01 410 static AliHLTUInt32_t fgMargin; // see above
3f2a1b1c 411
0c0c9d99 412 /** global instance to HLT logging class for static methods */
70ed7d01 413 static AliHLTLogging fgLogging; // see above
3f2a1b1c 414
8451168b 415 /** size of the safety pattern */
416 static const Int_t fgkSafetyPatternSize; // see above
417
418 /** the safety pattern */
419 static const char fgkSafetyPattern[]; //!transient
420
70ed7d01 421 //////////////////////////////////////////////////////////////////////////////
0c0c9d99 422 // internal helper functions
423
424 /**
425 * Find the consumer descriptor for a certain component and data type in
426 * a list of consumers.<br>
70ed7d01 427 * <b>Note:</b> There are three lists which contain the consumers in the
428 * different states.
0c0c9d99 429 * @param pConsumer pointer to consumer component
430 * @param list list where to search for the consumer
431 */
70ed7d01 432 AliHLTConsumerDescriptor* FindConsumer(const AliHLTComponent* pConsumer,
2be3f004 433 AliHLTConsumerDescriptorPList &list) const;
0c0c9d99 434
435 /**
436 * Change the state of a consumer.
70ed7d01 437 * The state of a consumer is determined by the list it is strored in, the
438 * method moves a consumer from the source to the target list.
0c0c9d99 439 * @param pDesc pointer to consumer descriptor
440 * @param srcList list where the consumer is currently to be found
441 * @param tgtList list where to move the consumer
442 */
70ed7d01 443 int ChangeConsumerState(AliHLTConsumerDescriptor* pDesc,
2be3f004 444 AliHLTConsumerDescriptorPList &srcList,
445 AliHLTConsumerDescriptorPList &tgtList);
3f2a1b1c 446
0c0c9d99 447 /**
448 * Cleanup a consumer list.
449 * Release all allocated data structures. <b>Note:</b> Not the component itself!
450 */
3f2a1b1c 451 int CleanupConsumerList();
452
453 ClassDef(AliHLTDataBuffer, 0)
454};
6235cd38 455
3f2a1b1c 456#endif // ALIHLTDATABUFFER_H