]>
Commit | Line | Data |
---|---|---|
f93bb075 | 1 | //-*- Mode: C++ -*- |
2 | // $Id$ | |
3f2a1b1c | 3 | |
4 | #ifndef ALIHLTDATABUFFER_H | |
5 | #define ALIHLTDATABUFFER_H | |
f93bb075 | 6 | //* This file is property of and copyright by the ALICE HLT Project * |
7 | //* ALICE Experiment at CERN, All rights reserved. * | |
8 | //* See cxx source for full Copyright notice * | |
3f2a1b1c | 9 | |
f93bb075 | 10 | // @file AliHLTDataBuffer.h |
11 | // @author Matthias Richter | |
12 | // @date | |
13 | // @brief Handling of Data Buffers for HLT components. | |
14 | // @note The class is used in Offline (AliRoot) context | |
3f2a1b1c | 15 | |
30338a30 | 16 | // see below for class documentation |
17 | // or | |
18 | // refer to README to build package | |
19 | // or | |
20 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
21 | ||
8ede8717 | 22 | #include <vector> |
2be3f004 | 23 | #include "TObject.h" |
3f2a1b1c | 24 | #include "AliHLTLogging.h" |
25 | #include "AliHLTDataTypes.h" | |
2be3f004 | 26 | #include "AliHLTComponent.h" |
3f2a1b1c | 27 | |
6235cd38 | 28 | class AliHLTConsumerDescriptor; |
b46ca65e | 29 | class AliHLTTask; |
3f2a1b1c | 30 | |
2be3f004 | 31 | /** list of AliHLTConsumerDescriptor pointers */ |
32 | typedef vector<AliHLTConsumerDescriptor*> AliHLTConsumerDescriptorPList; | |
33 | ||
b46ca65e | 34 | typedef AliHLTUInt8_t* AliHLTUInt8Pointer_t; |
35 | ||
0c0c9d99 | 36 | /** |
bfccbf68 | 37 | * @class AliHLTDataBuffer |
38 | * @brief Handling of data buffers for the HLT. | |
b22e91eb | 39 | * |
70ed7d01 | 40 | * The class provides handling of data buffers for HLT tasks. Each task gets |
41 | * its own Data Buffer instance. The buffer is grouped into different data | |
42 | * segments according to the output of the component.<br> | |
43 | * The Data Buffer keeps control over the data requests of the 'child' | |
44 | * components. Each component can subscribe to a certain segment of the data | |
45 | * buffer. It's state is then changed from 'reserved' to 'active'. After the | |
46 | * data processing, the component has to release the segment and it's state is | |
47 | * set to 'processed'. If all components have requested and released their data, | |
48 | * the Raw Buffer is released and pushed back in the list of available buffers. | |
b22e91eb | 49 | * |
50 | * @note This class is only used for the @ref alihlt_system. | |
51 | * | |
52 | * @ingroup alihlt_system | |
0c0c9d99 | 53 | */ |
6235cd38 | 54 | class AliHLTDataBuffer : public TObject, public AliHLTLogging |
55 | { | |
3f2a1b1c | 56 | public: |
70ed7d01 | 57 | ////////////////////////////////////////////////////////////////////////////// |
6235cd38 | 58 | // constructors and destructors |
0c0c9d99 | 59 | |
60 | /* standard constructor | |
61 | */ | |
3f2a1b1c | 62 | AliHLTDataBuffer(); |
85869391 | 63 | /** destructor */ |
3f2a1b1c | 64 | virtual ~AliHLTDataBuffer(); |
65 | ||
70ed7d01 | 66 | ////////////////////////////////////////////////////////////////////////////// |
3f2a1b1c | 67 | // initialization |
68 | ||
0c0c9d99 | 69 | /** |
70 | * Add component to the list of consumers | |
71 | * @param pConsumer - a consumer of type AliHLTComponent | |
3f2a1b1c | 72 | */ |
0c0c9d99 | 73 | int SetConsumer(AliHLTComponent* pConsumer); |
3f2a1b1c | 74 | |
70ed7d01 | 75 | ////////////////////////////////////////////////////////////////////////////// |
3f2a1b1c | 76 | // component to component communication |
77 | ||
0c0c9d99 | 78 | /** |
70ed7d01 | 79 | * Determine the number of matching data blocks for the component and a |
80 | * consumer component. <br> | |
81 | * The first approach will support only one output data type for processing | |
82 | * components. | |
0c0c9d99 | 83 | * @param pConsumer the component which subscribes to the buffer |
84 | * @param tgtList (optional) the list to receive the data types | |
85 | * @return: number of data blocks which match the input data types | |
86 | * of the consumer, neg. error code if failed <br> | |
87 | * -EINVAL invalid parameter <br> | |
3f2a1b1c | 88 | */ |
70ed7d01 | 89 | int FindMatchingDataBlocks(const AliHLTComponent* pConsumer, |
2be3f004 | 90 | AliHLTComponentDataTypeList* tgtList=NULL); |
0c0c9d99 | 91 | |
92 | /** | |
93 | * Subscribe to a segment of the data buffer. | |
70ed7d01 | 94 | * The function prepares the block descriptor for subsequent use with the |
95 | * AliHLTComponent::ProcessEvent method, the method can prepare several block | |
96 | * descriptors up to the array size specified by iArraySize. The return value | |
97 | * is independent from the array size the number of block descriptors which | |
98 | * would have been prepared if there was enough space in the array<br> | |
0c0c9d99 | 99 | * The method is used by the consumer component. |
100 | * @param pConsumer the component which subscribes to the buffer | |
e962f438 | 101 | * @param blockDescList block descriptor vector to be filled |
70ed7d01 | 102 | * @return: number of matching data blocks, neg. error code if failed<br> |
103 | * -EACCESS the consumer state can't be changed (activated) | |
0c0c9d99 | 104 | * -EBADF unresolved data segments <br> |
105 | * -ENOENT consumer component not found <br> | |
106 | * -ENODATA data buffer does not have raw data <br> | |
107 | * -EINVAL invalid parameter <br> | |
108 | */ | |
457ec821 | 109 | int Subscribe(const AliHLTComponent* pConsumer, |
110 | AliHLTComponentBlockDataList& blockDescList); | |
111 | ||
0c0c9d99 | 112 | /** |
113 | * Release an instance of the data buffer. | |
114 | * Resets the variables of the block descriptor. | |
115 | * If all buffer segments are released, the Data Buffer is reseted | |
116 | * and the Raw Buffer released.<br> | |
117 | * The method is used by the consumer component. | |
118 | * @param pBlockDesc descriptor of the data segment | |
119 | * @param pConsumer the component which subscribes to the buffer | |
b46ca65e | 120 | * @param pOwnerTask task owning this buffer |
0c0c9d99 | 121 | * @return: >0 if success, negative error code if failed <br> |
70ed7d01 | 122 | * -EACCESS the consumer state can not be changed (de-activated) |
123 | * -ENOENT consumer has not subscribed to the buffer <br> | |
0c0c9d99 | 124 | * -EINVAL invalid parameter <br> |
3f2a1b1c | 125 | */ |
b46ca65e | 126 | int Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer, |
127 | const AliHLTTask* pOwnerTask); | |
128 | ||
d4a18597 | 129 | /** |
130 | * Release a forwarded data block. | |
131 | */ | |
132 | int ReleaseForwardedBlock(AliHLTComponentBlockData* pBlockDesc, | |
133 | const AliHLTTask* pOwnerTask); | |
134 | ||
b46ca65e | 135 | /** |
136 | * Register an input data block for forwarding. | |
137 | * Consumer of this data buffer subscribe to forwarded data blocks in te same way. | |
138 | * Forwarded data blocks are released when the last consumer has released the | |
139 | * blocks. | |
140 | * @param pSrcTask original source task of the data block | |
141 | * @param pBlockDesc descriptor of the data segment | |
142 | */ | |
143 | int Forward(AliHLTTask* pSrcTask, AliHLTComponentBlockData* pBlockDesc); | |
3f2a1b1c | 144 | |
0c0c9d99 | 145 | /** |
146 | * Get a target buffer of minimum size iMinSize. | |
147 | * The method is used by the component which owns the Data Buffer to | |
148 | * allocate a buffer for the data it is going to produce. | |
149 | * @param iMinSize minumum size of the requested buffer | |
150 | * @return: pointer to target buffer if | |
3f2a1b1c | 151 | */ |
152 | AliHLTUInt8_t* GetTargetBuffer(int iMinSize); | |
153 | ||
0c0c9d99 | 154 | /** |
155 | * Set the segments for the data buffer. | |
156 | * This is usually done after the component has written the data to the buffer, | |
157 | * which was requested by the @ref GetTargetBuffer method. The component might | |
158 | * produce different types of data, for each type a segment has to be defined | |
2d7ff710 | 159 | * which describes the data inside the buffer.<br> |
70ed7d01 | 160 | * The @ref AliHLTComponentBlockData segment descriptor comes directly from |
161 | * the @ref AliHLTComponent::ProcessEvent method. | |
0c0c9d99 | 162 | * @param pTgt the target buffer which the segments refer to |
163 | * @param arraySegments the output block descriptors of the component | |
164 | * @param iSize size of the array | |
3f2a1b1c | 165 | */ |
8ede8717 | 166 | int SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arraySegments, int iSize); |
3f2a1b1c | 167 | |
0c0c9d99 | 168 | /** |
169 | * Check if the data buffer is empty. | |
170 | * @return 1 if empty, 0 if not | |
3f2a1b1c | 171 | */ |
172 | int IsEmpty(); | |
173 | ||
0c0c9d99 | 174 | /** |
175 | * Get the total and maximum size of the buffer. | |
176 | * Lets see if this is needed later | |
3f2a1b1c | 177 | */ |
178 | //int GetTotalSize(); | |
179 | ||
0c0c9d99 | 180 | /** |
d4a18597 | 181 | * Get the number of segments including the forwarded data blocks. |
0c0c9d99 | 182 | * @return number of segments |
3f2a1b1c | 183 | */ |
12c8715e | 184 | int GetNofSegments() const; |
3f2a1b1c | 185 | |
0c0c9d99 | 186 | /** |
b426991e | 187 | * Get the total number of consumers. |
188 | * This gives the number of consumers regardless of their state. | |
0c0c9d99 | 189 | * @return number of consumers |
3f2a1b1c | 190 | */ |
12c8715e | 191 | int GetNofConsumers() const; |
3f2a1b1c | 192 | |
0c0c9d99 | 193 | /** |
b426991e | 194 | * Get the number of consumers which still need to be processed during |
195 | * the current event. | |
196 | * @return number of consumers | |
197 | */ | |
12c8715e | 198 | int GetNofPendingConsumers() const; |
b426991e | 199 | |
200 | /** | |
201 | * Get the number of consumers currently under processing. | |
0c0c9d99 | 202 | * @return number of active consumers |
3f2a1b1c | 203 | */ |
12c8715e | 204 | int GetNofActiveConsumers() const; |
3f2a1b1c | 205 | |
9ce4bf4a | 206 | /** |
207 | * Check if a consumer is already in the list | |
208 | * @param pConsumer pointer to consumer component | |
209 | * @param bAllLists search in all lists if 1 | |
210 | * search only in fConsumer list if 0 | |
211 | * @return 1 if found, 0 if not | |
212 | */ | |
d4a18597 | 213 | int FindConsumer(const AliHLTComponent* pConsumer, int bAllLists=1); |
9ce4bf4a | 214 | |
215 | /** | |
216 | * Public method to reset the buffer. | |
217 | * Eventually with some additional checks. In normal operation, | |
218 | * an external reset should not be necessary. | |
219 | */ | |
220 | int Reset(); | |
221 | ||
12c8715e | 222 | /** |
223 | * Print info about the buffer | |
224 | */ | |
225 | virtual void Print(const char* option) const; | |
226 | ||
dba03d72 | 227 | /** |
228 | * Set local logging level | |
229 | * logging filter for individual object | |
230 | */ | |
231 | void SetLocalLoggingLevel(AliHLTComponentLogSeverity level) | |
232 | {fgLogging.SetLocalLoggingLevel(level); AliHLTLogging::SetLocalLoggingLevel(level);} | |
233 | ||
0a7afbf0 | 234 | /** |
235 | * Print summary of the global buffer management. | |
236 | */ | |
237 | static int PrintStatistics(); | |
238 | ||
239 | /** | |
240 | * Set the global event count. | |
241 | * The event count is deployed to find buffers which have not been used | |
242 | * for a while. In such a case to policy to find an appropriate buffer is | |
243 | * adjusted. | |
244 | */ | |
245 | static int SetGlobalEventCount(AliHLTUInt32_t eventCount) {fgEventCount=eventCount; return 0;} | |
246 | ||
6235cd38 | 247 | /** |
965919c8 | 248 | * @class AliHLTDataSegment |
6235cd38 | 249 | * @brief Descriptor of a data segment within the buffer. |
250 | */ | |
66043029 | 251 | class AliHLTDataSegment { |
2c3d24ca | 252 | friend class AliHLTDataBuffer; // TODO: implement some getters/setters |
66043029 | 253 | public: |
6235cd38 | 254 | AliHLTDataSegment() |
255 | : | |
b46ca65e | 256 | fDataType(kAliHLTVoidDataType), |
257 | fPtr(NULL), | |
6235cd38 | 258 | fSegmentOffset(0), |
259 | fSegmentSize(0), | |
260 | fSpecification(0) | |
261 | { | |
6235cd38 | 262 | } |
b46ca65e | 263 | |
264 | AliHLTDataSegment(AliHLTUInt8_t* ptr, AliHLTUInt32_t offset, AliHLTUInt32_t size) | |
265 | : | |
266 | fDataType(kAliHLTVoidDataType), | |
267 | fPtr(ptr), | |
268 | fSegmentOffset(offset), | |
269 | fSegmentSize(size), | |
270 | fSpecification(0) | |
271 | { | |
272 | } | |
273 | ||
274 | AliHLTDataSegment(void* ptr, AliHLTUInt32_t offset, AliHLTUInt32_t size) | |
6235cd38 | 275 | : |
b46ca65e | 276 | fDataType(kAliHLTVoidDataType), |
f93bb075 | 277 | fPtr(reinterpret_cast<AliHLTUInt8_t*>(ptr)), |
6235cd38 | 278 | fSegmentOffset(offset), |
279 | fSegmentSize(size), | |
280 | fSpecification(0) | |
281 | { | |
6235cd38 | 282 | } |
2be3f004 | 283 | |
b46ca65e | 284 | AliHLTDataSegment(void* ptr, AliHLTUInt32_t offset, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliHLTUInt32_t spec) |
285 | : | |
286 | fDataType(dt), | |
f93bb075 | 287 | fPtr(reinterpret_cast<AliHLTUInt8_t*>(ptr)), |
b46ca65e | 288 | fSegmentOffset(offset), |
289 | fSegmentSize(size), | |
290 | fSpecification(spec) | |
291 | { | |
292 | } | |
293 | ||
12c8715e | 294 | AliHLTDataSegment(const AliHLTDataSegment& src) |
295 | : | |
296 | fDataType(src.fDataType), | |
297 | fPtr(src.fPtr), | |
298 | fSegmentOffset(src.fSegmentOffset), | |
299 | fSegmentSize(src.fSegmentSize), | |
300 | fSpecification(src.fSpecification) | |
301 | { | |
302 | // AliHLTDataSegment just stores external pointers and properties | |
303 | } | |
304 | ||
305 | AliHLTDataSegment& operator=(const AliHLTDataSegment& src) | |
306 | { | |
307 | // AliHLTDataSegment just stores external pointers and properties | |
308 | fDataType=src.fDataType; | |
309 | fPtr=src.fPtr; | |
310 | fSegmentOffset=src.fSegmentOffset; | |
311 | fSegmentSize=src.fSegmentSize; | |
312 | fSpecification=src.fSpecification; | |
313 | return *this; | |
314 | } | |
315 | ||
316 | virtual ~AliHLTDataSegment() {} | |
317 | ||
b46ca65e | 318 | AliHLTUInt8_t* GetPtr() const {return (AliHLTUInt8_t*)*this;} |
319 | ||
320 | AliHLTUInt32_t GetSize() const {return fSegmentSize;} | |
321 | ||
322 | int operator==(const AliHLTDataSegment& seg) const | |
323 | { | |
324 | return (fPtr+fSegmentOffset==seg.fPtr+seg.fSegmentOffset) && (fSegmentSize==seg.fSegmentSize); | |
325 | } | |
326 | operator AliHLTUInt8_t*() const {return fPtr+fSegmentOffset;} | |
327 | ||
12c8715e | 328 | virtual void Print(const char* option) const; |
329 | ||
5df0cbb9 | 330 | private: |
6235cd38 | 331 | /** the data type of this segment */ |
332 | AliHLTComponentDataType fDataType; // see above | |
b46ca65e | 333 | /** pointer to the buffer */ |
334 | AliHLTUInt8Pointer_t fPtr; //!transient | |
6235cd38 | 335 | /** offset in byte within the data buffer */ |
336 | AliHLTUInt32_t fSegmentOffset; // see above | |
337 | /** size of the actual content */ | |
338 | AliHLTUInt32_t fSegmentSize; // see above | |
339 | /** data specification */ | |
340 | AliHLTUInt32_t fSpecification; // see above | |
f93bb075 | 341 | |
6235cd38 | 342 | }; |
343 | ||
12c8715e | 344 | /** |
345 | * @class AliHLTForwardedDataSegment | |
346 | * @brief Descriptor of a forwarded data segment. | |
347 | * Contains in addition information about the parent of this forwarded | |
348 | * block and the original data type and specification | |
349 | */ | |
350 | class AliHLTForwardedDataSegment : public AliHLTDataSegment { | |
351 | friend class AliHLTDataBuffer; // TODO: implement some getters/setters | |
352 | public: | |
353 | AliHLTForwardedDataSegment() | |
354 | : AliHLTDataSegment() | |
355 | , fParentSegment() | |
356 | , fParentTask(NULL) | |
357 | { | |
358 | } | |
359 | ||
360 | AliHLTForwardedDataSegment(AliHLTDataSegment& mySegment, AliHLTDataSegment& parentSegment, AliHLTTask* parentTask) | |
361 | : AliHLTDataSegment(mySegment) | |
362 | , fParentSegment(parentSegment) | |
363 | , fParentTask(parentTask) | |
364 | { | |
365 | } | |
366 | ||
367 | AliHLTForwardedDataSegment(const AliHLTForwardedDataSegment& src) | |
368 | : AliHLTDataSegment(src), | |
369 | fParentSegment(src.fParentSegment), | |
370 | fParentTask(src.fParentTask) | |
371 | { | |
372 | // AliHLTForwardedDataSegment just stores external pointers and properties | |
373 | } | |
374 | ||
375 | AliHLTForwardedDataSegment& operator=(const AliHLTForwardedDataSegment& src) | |
376 | { | |
377 | // AliHLTForwardedDataSegment just stores external pointers and properties | |
378 | AliHLTDataSegment::operator=(src); | |
379 | fParentSegment=src.fParentSegment; | |
380 | fParentTask=src.fParentTask; | |
381 | return *this; | |
382 | } | |
383 | ||
384 | virtual ~AliHLTForwardedDataSegment() {} | |
385 | ||
386 | virtual void Print(const char* option) const; | |
387 | ||
388 | private: | |
389 | /// description of the original segment | |
390 | AliHLTDataSegment fParentSegment; // see above | |
391 | /// the parent task | |
392 | AliHLTTask* fParentTask; //!transient | |
393 | }; | |
394 | ||
545d509f | 395 | class AliHLTRawBuffer; |
396 | typedef vector<AliHLTRawBuffer*> AliHLTRawBufferPList; | |
397 | ||
398 | /** | |
399 | * @class AliHLTRawPage | |
400 | * Memory allocation is organized in pages of a fixed size. Within a | |
401 | * page, AliHLTRawBuffer chunks are created. | |
402 | */ | |
403 | class AliHLTRawPage : public AliHLTLogging { | |
404 | public: | |
405 | /** standard constructor */ | |
406 | AliHLTRawPage() : fSize(0), fPtr(NULL), fFreeBuffers(), fUsedBuffers() {} | |
407 | /** constructor */ | |
408 | AliHLTRawPage(AliHLTUInt32_t pagesize); | |
409 | /** destructor */ | |
410 | virtual ~AliHLTRawPage(); | |
411 | ||
48dedf26 | 412 | /** alloc a buffer of specified size from the global pages*/ |
413 | static AliHLTRawBuffer* GlobalAlloc(AliHLTUInt32_t size, int verbosity=0); | |
414 | /** find buffer in the global pages */ | |
415 | static AliHLTRawPage* FindPage(AliHLTRawBuffer* buffer); | |
416 | /** cleanup the global pages */ | |
417 | static int GlobalClean(); | |
418 | /** adjust global page size */ | |
419 | static void SetGlobalPageSize(AliHLTUInt32_t size) {fgGlobalPageSize=size;} | |
420 | /** find next page after prev, or first page */ | |
f93bb075 | 421 | static AliHLTRawPage* NextPage(const AliHLTRawPage* prev=NULL); |
48dedf26 | 422 | |
545d509f | 423 | /** alloc a buffer of specified size */ |
424 | AliHLTRawBuffer* Alloc(AliHLTUInt32_t size); | |
425 | /** free a buffer and merge consecutive free buffers */ | |
426 | int Free(AliHLTRawBuffer* pBuffer); | |
775975be | 427 | /** set the size of a raw buffer and release the remaining part */ |
f93bb075 | 428 | int SetSize(const AliHLTRawBuffer* pBuffer, AliHLTUInt32_t size); |
48dedf26 | 429 | /// check if the buffer is in this page |
f93bb075 | 430 | bool HasBuffer(const AliHLTRawBuffer* pBuffer); |
775975be | 431 | |
432 | AliHLTUInt32_t Size() const {return fSize;} | |
433 | AliHLTUInt32_t Capacity() const; | |
434 | bool IsUsed() const {return fUsedBuffers.size()>0;} | |
48dedf26 | 435 | bool IsFragmented() const {return (fFreeBuffers.size()+fUsedBuffers.size())>1;} |
545d509f | 436 | |
437 | /** | |
438 | * Print page information | |
439 | */ | |
12c8715e | 440 | virtual void Print(const char* option); |
545d509f | 441 | |
442 | private: | |
443 | /** copy constructor prohibited */ | |
444 | AliHLTRawPage(const AliHLTRawPage&); | |
445 | /** assignment operator prohibited */ | |
446 | AliHLTRawPage& operator=(const AliHLTRawPage&); | |
447 | ||
48dedf26 | 448 | /// list of global pages |
449 | static vector<AliHLTDataBuffer::AliHLTRawPage*> fgGlobalPages; //! transient | |
450 | /// pages size of global pages | |
451 | static AliHLTUInt32_t fgGlobalPageSize; //! transient | |
452 | ||
545d509f | 453 | /** page size */ |
454 | AliHLTUInt32_t fSize; // see above | |
455 | /** the memory segment */ | |
456 | AliHLTUInt8_t* fPtr; //! transient | |
457 | ||
458 | /** list of free buffers */ | |
459 | AliHLTRawBufferPList fFreeBuffers; //! transient | |
460 | /** list of used buffers */ | |
461 | AliHLTRawBufferPList fUsedBuffers; //! transient | |
462 | }; | |
463 | ||
6235cd38 | 464 | /** |
965919c8 | 465 | * @class AliHLTRawBuffer |
6235cd38 | 466 | * @brief Descriptor of the raw data buffer which can host several segments. |
467 | */ | |
66043029 | 468 | class AliHLTRawBuffer { |
469 | public: | |
470 | /** standard constructor */ | |
545d509f | 471 | AliHLTRawBuffer() : fSize(0), fTotalSize(0), fExternalPtr(NULL), fPtr(NULL), fLastEventCount(0) {} |
d6cbe999 | 472 | /** constructor */ |
473 | AliHLTRawBuffer(AliHLTUInt32_t size); | |
545d509f | 474 | /** constructor */ |
475 | AliHLTRawBuffer(AliHLTUInt32_t size, AliHLTUInt8_t* buffer); | |
d6cbe999 | 476 | /** destructor */ |
477 | virtual ~AliHLTRawBuffer(); | |
478 | ||
479 | /** | |
480 | * Use a fraction of the buffer. | |
481 | * @param size size in bytes to be used | |
482 | * @return pointer to buffer | |
483 | */ | |
484 | AliHLTUInt8_t* UseBuffer(AliHLTUInt32_t size); | |
485 | ||
545d509f | 486 | /** |
487 | * split a buffer at specified size | |
488 | * only possible for buffers with external memory | |
489 | */ | |
490 | AliHLTRawBuffer* Split(AliHLTUInt32_t size); | |
491 | ||
d6cbe999 | 492 | /** |
493 | * Check whether buffer fits for a request. | |
0a7afbf0 | 494 | * A buffer fits if it is at least of the requested size and at most |
495 | * the requested size plus a margin. The margin increases with the | |
496 | * number of events the buffer has not been used. | |
d6cbe999 | 497 | * @param size size of the request in bytes |
498 | * @return 1 if buffer is big enough, 0 if not | |
499 | */ | |
500 | int CheckSize(AliHLTUInt32_t size) const; | |
501 | ||
c0a2bfc2 | 502 | /** |
503 | * Get used size of the buffer | |
504 | */ | |
505 | AliHLTUInt32_t GetUsedSize() const {return fSize;} | |
506 | ||
d6cbe999 | 507 | /** |
508 | * Get total size of the buffer | |
509 | */ | |
510 | AliHLTUInt32_t GetTotalSize() const {return fTotalSize;} | |
511 | ||
c0a2bfc2 | 512 | /** |
513 | * Get pointer of data buffer | |
514 | */ | |
515 | AliHLTUInt8_t* GetPointer() const {return fPtr;} | |
516 | ||
d6cbe999 | 517 | /** |
518 | * Write check pattern | |
519 | */ | |
520 | int WritePattern(const char* pattern, int size); | |
521 | ||
522 | /** | |
523 | * Check pattern | |
524 | */ | |
525 | int CheckPattern(const char* pattern, int size) const; | |
526 | ||
527 | /** | |
528 | * Reset buffer. | |
529 | * Data buffer remains allocated, used size set to 0 | |
530 | */ | |
531 | int Reset(); | |
1e6e67ec | 532 | |
545d509f | 533 | /* |
534 | * Merge buffer with succeeding buffer. | |
535 | * Only possible if the buffers are consecutive with out any gap. | |
536 | */ | |
537 | int Merge(const AliHLTRawBuffer& succ); | |
538 | ||
539 | /** | |
540 | * Print buffer information | |
541 | */ | |
12c8715e | 542 | virtual void Print(const char* option) const; |
545d509f | 543 | |
2c3d24ca | 544 | int operator==(void* ptr) const; |
9c86c94e | 545 | int operator==(AliHLTUInt8_t* ptr) const {return fPtr==ptr;} |
2c3d24ca | 546 | int operator<(void* ptr) const; |
547 | int operator<=(void* ptr) const; | |
548 | int operator>(void* ptr) const; | |
549 | int operator-(void* ptr) const; | |
550 | int operator<(const AliHLTRawBuffer& op) const; | |
551 | int operator<=(const AliHLTRawBuffer& op) const; | |
552 | int operator>(const AliHLTRawBuffer& op) const; | |
1e6e67ec | 553 | |
3a7c0444 | 554 | operator void*() const {return fPtr;} |
555 | operator AliHLTUInt8_t*() const {return fPtr;} | |
1e6e67ec | 556 | |
5df0cbb9 | 557 | private: |
d6cbe999 | 558 | /** copy constructor prohibited */ |
559 | AliHLTRawBuffer(const AliHLTRawBuffer&); | |
560 | /** assignment operator prohibited */ | |
561 | AliHLTRawBuffer& operator=(const AliHLTRawBuffer&); | |
562 | ||
6235cd38 | 563 | /** size of the currently occupied partition of the buffer */ |
564 | AliHLTUInt32_t fSize; // see above | |
565 | /** total size of the buffer, including safety margin */ | |
566 | AliHLTUInt32_t fTotalSize; // see above | |
545d509f | 567 | /** optional external buffer */ |
568 | AliHLTUInt8_t* fExternalPtr; //! transient | |
569 | /** the buffer, external or allocated */ | |
1e6e67ec | 570 | AliHLTUInt8_t* fPtr; //! transient |
0a7afbf0 | 571 | /** last event count where the buffer has been used */ |
572 | AliHLTUInt32_t fLastEventCount; //! transient | |
6235cd38 | 573 | }; |
574 | ||
3f2a1b1c | 575 | private: |
b426991e | 576 | /** copy constructor prohibited */ |
577 | AliHLTDataBuffer(const AliHLTDataBuffer&); | |
578 | /** assignment operator prohibited */ | |
579 | AliHLTDataBuffer& operator=(const AliHLTDataBuffer&); | |
580 | ||
0c0c9d99 | 581 | /* lets see if this is needed |
6235cd38 | 582 | AliHLTDataSegment* FindDataSegment(AliHLTComponentDataType datatype); |
0c0c9d99 | 583 | */ |
584 | ||
585 | /** | |
586 | * Find those data segments which match the input types of a component. | |
587 | * @param pConsumer the component which subscribes to the buffer | |
588 | * @param tgtList the list to receive the data segment descriptors | |
589 | * @return: number of data blocks which match the input data types | |
590 | * of the consumer, neg. error code if failed <br> | |
591 | * -EINVAL invalid parameter <br> | |
592 | */ | |
90ebac25 | 593 | int FindMatchingDataSegments(const AliHLTComponent* pConsumer, |
594 | vector<AliHLTDataBuffer::AliHLTDataSegment>& tgtList); | |
3f2a1b1c | 595 | |
48dedf26 | 596 | protected: |
597 | // 2010-02-01 make function protected in order to be used from unit test | |
0c0c9d99 | 598 | /** |
599 | * Reset the data buffer. | |
9ce4bf4a | 600 | * Removes all consumers back to the @ref fConsumers list, deletes |
601 | * segments and releases the Raw Buffer. | |
3f2a1b1c | 602 | */ |
603 | int ResetDataBuffer(); | |
48dedf26 | 604 | private: |
3f2a1b1c | 605 | |
70ed7d01 | 606 | ////////////////////////////////////////////////////////////////////////////// |
607 | ||
3f2a1b1c | 608 | // the data description |
3f2a1b1c | 609 | |
0c0c9d99 | 610 | // the data segments within this buffer |
70ed7d01 | 611 | vector<AliHLTDataSegment> fSegments; // see above |
3f2a1b1c | 612 | |
0c0c9d99 | 613 | // the list of all consumers which are going to subscribe to the buffer |
2be3f004 | 614 | AliHLTConsumerDescriptorPList fConsumers; // see above |
0c0c9d99 | 615 | // the list of all consumers which are currently subscribed to the buffer |
2be3f004 | 616 | AliHLTConsumerDescriptorPList fActiveConsumers; // see above |
0c0c9d99 | 617 | // the list of all consumers which are already released for the current event |
2be3f004 | 618 | AliHLTConsumerDescriptorPList fReleasedConsumers; // see above |
3f2a1b1c | 619 | |
0c0c9d99 | 620 | // the buffer instance |
70ed7d01 | 621 | AliHLTRawBuffer* fpBuffer; //! transient |
3f2a1b1c | 622 | |
0c0c9d99 | 623 | // flags indicating the state of the buffer |
70ed7d01 | 624 | AliHLTUInt32_t fFlags; // see above |
3f2a1b1c | 625 | |
b46ca65e | 626 | /** list of tasks with forwarded data blocks */ |
627 | vector<AliHLTTask*> fForwardedSegmentSources; //! transient | |
628 | ||
629 | /** list of forwarded block descriptors */ | |
630 | vector<AliHLTDataSegment> fForwardedSegments; //! transient | |
631 | ||
70ed7d01 | 632 | ////////////////////////////////////////////////////////////////////////////// |
0c0c9d99 | 633 | // global buffer handling, internal use only |
634 | ||
635 | /** | |
636 | * Create a raw buffer of a certain size. | |
637 | * The function tries to find a buffer of the given size (or a bit bigger by a | |
9ddaea75 | 638 | * certain margin @ref fgMargin) from the list of free buffers. |
0c0c9d99 | 639 | * If no buffer is available, a new one is created and added to the buffer handling. |
640 | * @param size min. size of the requested buffer | |
641 | * @return pointer to raw buffer | |
3f2a1b1c | 642 | */ |
643 | static AliHLTRawBuffer* CreateRawBuffer(AliHLTUInt32_t size); | |
644 | ||
48dedf26 | 645 | /** |
646 | * Set the data size of a raw buffer after it has been filled by | |
647 | * the component. | |
648 | */ | |
649 | int SetRawBufferDataSize(AliHLTRawBuffer* pBuffer, AliHLTUInt32_t size) const; | |
650 | ||
0c0c9d99 | 651 | /** |
652 | * Mark a buffer as free. | |
70ed7d01 | 653 | * After the Data Buffer has finnished using the raw buffer, it is released |
654 | * and added to the list of available buffers. | |
0c0c9d99 | 655 | * @param pBuffer the raw buffer to release |
656 | * @return >=0 if succeeded, neg. error code if failed | |
3f2a1b1c | 657 | */ |
658 | static int ReleaseRawBuffer(AliHLTRawBuffer* pBuffer); | |
659 | ||
0c0c9d99 | 660 | /** |
661 | * Deletes all the raw buffers. | |
70ed7d01 | 662 | * When the last Data Buffer object is destructed, all raw data buffers are |
663 | * relesed. | |
3f2a1b1c | 664 | */ |
665 | static int DeleteRawBuffers(); | |
666 | ||
0c0c9d99 | 667 | /** |
668 | * Number of instances of AliHLTDataBuffer. | |
70ed7d01 | 669 | * The statice variable is incremented and decremented in the constructor/ |
670 | * destructor. All internal data structures are cleaned up when the last | |
671 | * instance is exiting. | |
0c0c9d99 | 672 | */ |
70ed7d01 | 673 | static int fgNofInstances; // see above |
0c0c9d99 | 674 | /** global list of free raw buffers */ |
70ed7d01 | 675 | static vector<AliHLTRawBuffer*> fgFreeBuffers; // see above |
0c0c9d99 | 676 | /** global list of currently active raw buffers */ |
70ed7d01 | 677 | static vector<AliHLTRawBuffer*> fgActiveBuffers; // see above |
0c0c9d99 | 678 | /** determines the raw buffer size margin at buffer requests */ |
70ed7d01 | 679 | static AliHLTUInt32_t fgMargin; // see above |
3f2a1b1c | 680 | |
0c0c9d99 | 681 | /** global instance to HLT logging class for static methods */ |
70ed7d01 | 682 | static AliHLTLogging fgLogging; // see above |
3f2a1b1c | 683 | |
8451168b | 684 | /** size of the safety pattern */ |
685 | static const Int_t fgkSafetyPatternSize; // see above | |
686 | ||
687 | /** the safety pattern */ | |
688 | static const char fgkSafetyPattern[]; //!transient | |
689 | ||
0a7afbf0 | 690 | static AliHLTUInt32_t fgEventCount; //!transient |
691 | ||
70ed7d01 | 692 | ////////////////////////////////////////////////////////////////////////////// |
0c0c9d99 | 693 | // internal helper functions |
694 | ||
695 | /** | |
696 | * Find the consumer descriptor for a certain component and data type in | |
697 | * a list of consumers.<br> | |
70ed7d01 | 698 | * <b>Note:</b> There are three lists which contain the consumers in the |
699 | * different states. | |
0c0c9d99 | 700 | * @param pConsumer pointer to consumer component |
701 | * @param list list where to search for the consumer | |
702 | */ | |
70ed7d01 | 703 | AliHLTConsumerDescriptor* FindConsumer(const AliHLTComponent* pConsumer, |
2be3f004 | 704 | AliHLTConsumerDescriptorPList &list) const; |
0c0c9d99 | 705 | |
706 | /** | |
707 | * Change the state of a consumer. | |
70ed7d01 | 708 | * The state of a consumer is determined by the list it is strored in, the |
709 | * method moves a consumer from the source to the target list. | |
0c0c9d99 | 710 | * @param pDesc pointer to consumer descriptor |
711 | * @param srcList list where the consumer is currently to be found | |
712 | * @param tgtList list where to move the consumer | |
713 | */ | |
70ed7d01 | 714 | int ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, |
2be3f004 | 715 | AliHLTConsumerDescriptorPList &srcList, |
716 | AliHLTConsumerDescriptorPList &tgtList); | |
3f2a1b1c | 717 | |
0c0c9d99 | 718 | /** |
719 | * Cleanup a consumer list. | |
720 | * Release all allocated data structures. <b>Note:</b> Not the component itself! | |
721 | */ | |
3f2a1b1c | 722 | int CleanupConsumerList(); |
723 | ||
0a7afbf0 | 724 | ClassDef(AliHLTDataBuffer, 1) |
3f2a1b1c | 725 | }; |
6235cd38 | 726 | |
3f2a1b1c | 727 | #endif // ALIHLTDATABUFFER_H |