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