]>
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 | |
cb9600c7 | 308 | if (this==&src) return *this; |
12c8715e | 309 | fDataType=src.fDataType; |
310 | fPtr=src.fPtr; | |
311 | fSegmentOffset=src.fSegmentOffset; | |
312 | fSegmentSize=src.fSegmentSize; | |
313 | fSpecification=src.fSpecification; | |
314 | return *this; | |
315 | } | |
316 | ||
317 | virtual ~AliHLTDataSegment() {} | |
318 | ||
b46ca65e | 319 | AliHLTUInt8_t* GetPtr() const {return (AliHLTUInt8_t*)*this;} |
320 | ||
321 | AliHLTUInt32_t GetSize() const {return fSegmentSize;} | |
322 | ||
323 | int operator==(const AliHLTDataSegment& seg) const | |
324 | { | |
325 | return (fPtr+fSegmentOffset==seg.fPtr+seg.fSegmentOffset) && (fSegmentSize==seg.fSegmentSize); | |
326 | } | |
327 | operator AliHLTUInt8_t*() const {return fPtr+fSegmentOffset;} | |
328 | ||
12c8715e | 329 | virtual void Print(const char* option) const; |
330 | ||
5df0cbb9 | 331 | private: |
6235cd38 | 332 | /** the data type of this segment */ |
333 | AliHLTComponentDataType fDataType; // see above | |
b46ca65e | 334 | /** pointer to the buffer */ |
335 | AliHLTUInt8Pointer_t fPtr; //!transient | |
6235cd38 | 336 | /** offset in byte within the data buffer */ |
337 | AliHLTUInt32_t fSegmentOffset; // see above | |
338 | /** size of the actual content */ | |
339 | AliHLTUInt32_t fSegmentSize; // see above | |
340 | /** data specification */ | |
341 | AliHLTUInt32_t fSpecification; // see above | |
f93bb075 | 342 | |
6235cd38 | 343 | }; |
344 | ||
12c8715e | 345 | /** |
346 | * @class AliHLTForwardedDataSegment | |
347 | * @brief Descriptor of a forwarded data segment. | |
348 | * Contains in addition information about the parent of this forwarded | |
349 | * block and the original data type and specification | |
350 | */ | |
351 | class AliHLTForwardedDataSegment : public AliHLTDataSegment { | |
352 | friend class AliHLTDataBuffer; // TODO: implement some getters/setters | |
353 | public: | |
354 | AliHLTForwardedDataSegment() | |
355 | : AliHLTDataSegment() | |
356 | , fParentSegment() | |
357 | , fParentTask(NULL) | |
358 | { | |
359 | } | |
360 | ||
361 | AliHLTForwardedDataSegment(AliHLTDataSegment& mySegment, AliHLTDataSegment& parentSegment, AliHLTTask* parentTask) | |
362 | : AliHLTDataSegment(mySegment) | |
363 | , fParentSegment(parentSegment) | |
364 | , fParentTask(parentTask) | |
365 | { | |
366 | } | |
367 | ||
368 | AliHLTForwardedDataSegment(const AliHLTForwardedDataSegment& src) | |
369 | : AliHLTDataSegment(src), | |
370 | fParentSegment(src.fParentSegment), | |
371 | fParentTask(src.fParentTask) | |
372 | { | |
373 | // AliHLTForwardedDataSegment just stores external pointers and properties | |
374 | } | |
375 | ||
376 | AliHLTForwardedDataSegment& operator=(const AliHLTForwardedDataSegment& src) | |
377 | { | |
378 | // AliHLTForwardedDataSegment just stores external pointers and properties | |
379 | AliHLTDataSegment::operator=(src); | |
380 | fParentSegment=src.fParentSegment; | |
381 | fParentTask=src.fParentTask; | |
382 | return *this; | |
383 | } | |
384 | ||
385 | virtual ~AliHLTForwardedDataSegment() {} | |
386 | ||
387 | virtual void Print(const char* option) const; | |
388 | ||
389 | private: | |
390 | /// description of the original segment | |
391 | AliHLTDataSegment fParentSegment; // see above | |
392 | /// the parent task | |
393 | AliHLTTask* fParentTask; //!transient | |
394 | }; | |
395 | ||
545d509f | 396 | class AliHLTRawBuffer; |
397 | typedef vector<AliHLTRawBuffer*> AliHLTRawBufferPList; | |
398 | ||
399 | /** | |
400 | * @class AliHLTRawPage | |
401 | * Memory allocation is organized in pages of a fixed size. Within a | |
402 | * page, AliHLTRawBuffer chunks are created. | |
403 | */ | |
404 | class AliHLTRawPage : public AliHLTLogging { | |
405 | public: | |
406 | /** standard constructor */ | |
407 | AliHLTRawPage() : fSize(0), fPtr(NULL), fFreeBuffers(), fUsedBuffers() {} | |
408 | /** constructor */ | |
409 | AliHLTRawPage(AliHLTUInt32_t pagesize); | |
410 | /** destructor */ | |
411 | virtual ~AliHLTRawPage(); | |
412 | ||
48dedf26 | 413 | /** alloc a buffer of specified size from the global pages*/ |
414 | static AliHLTRawBuffer* GlobalAlloc(AliHLTUInt32_t size, int verbosity=0); | |
415 | /** find buffer in the global pages */ | |
416 | static AliHLTRawPage* FindPage(AliHLTRawBuffer* buffer); | |
417 | /** cleanup the global pages */ | |
418 | static int GlobalClean(); | |
419 | /** adjust global page size */ | |
420 | static void SetGlobalPageSize(AliHLTUInt32_t size) {fgGlobalPageSize=size;} | |
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, |
595 | vector<AliHLTDataBuffer::AliHLTDataSegment>& 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 |