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