3f2a1b1c |
1 | // $Id$ |
2 | |
3 | /************************************************************************** |
9be2600f |
4 | * This file is property of and copyright by the ALICE HLT Project * |
5 | * ALICE Experiment at CERN, All rights reserved. * |
3f2a1b1c |
6 | * * |
9be2600f |
7 | * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * |
8 | * for The ALICE HLT Project. * |
3f2a1b1c |
9 | * * |
10 | * Permission to use, copy, modify and distribute this software and its * |
11 | * documentation strictly for non-commercial purposes is hereby granted * |
12 | * without fee, provided that the above copyright notice appears in all * |
13 | * copies and that both the copyright notice and this permission notice * |
14 | * appear in the supporting documentation. The authors make no claims * |
15 | * about the suitability of this software for any purpose. It is * |
16 | * provided "as is" without express or implied warranty. * |
17 | **************************************************************************/ |
18 | |
b22e91eb |
19 | /** @file AliHLTDataBuffer.cxx |
20 | @author Matthias Richter |
21 | @date |
22 | @brief Handling of Data Buffers for HLT components. |
23 | */ |
3f2a1b1c |
24 | |
30338a30 |
25 | // see header file for class documentation |
26 | // or |
27 | // refer to README to build package |
28 | // or |
29 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt |
30 | |
0c0c9d99 |
31 | #if __GNUC__>= 3 |
3f2a1b1c |
32 | using namespace std; |
33 | #endif |
34 | |
35 | #include "AliHLTDataBuffer.h" |
6235cd38 |
36 | #include "AliHLTConsumerDescriptor.h" |
b22e91eb |
37 | #include "AliHLTComponent.h" |
66043029 |
38 | #include <cerrno> |
d6cbe999 |
39 | #include <cassert> |
66043029 |
40 | //#include <string> |
41 | //#include "AliHLTSystem.h" |
3f2a1b1c |
42 | |
b22e91eb |
43 | /** ROOT macro for the implementation of ROOT specific class methods */ |
3f2a1b1c |
44 | ClassImp(AliHLTDataBuffer) |
45 | |
3f2a1b1c |
46 | AliHLTDataBuffer::AliHLTDataBuffer() |
85869391 |
47 | : |
48 | fSegments(), |
49 | fConsumers(), |
50 | fActiveConsumers(), |
51 | fReleasedConsumers(), |
52 | fpBuffer(NULL), |
53 | fFlags(0) |
3f2a1b1c |
54 | { |
70ed7d01 |
55 | // see header file for class documentation |
56 | // or |
57 | // refer to README to build package |
58 | // or |
59 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt |
85869391 |
60 | fSegments.empty(); |
61 | fConsumers.empty(); |
62 | fActiveConsumers.empty(); |
63 | fReleasedConsumers.empty(); |
70ed7d01 |
64 | fgNofInstances++; |
3f2a1b1c |
65 | } |
66 | |
70ed7d01 |
67 | int AliHLTDataBuffer::fgNofInstances=0; |
6235cd38 |
68 | vector<AliHLTDataBuffer::AliHLTRawBuffer*> AliHLTDataBuffer::fgFreeBuffers; |
69 | vector<AliHLTDataBuffer::AliHLTRawBuffer*> AliHLTDataBuffer::fgActiveBuffers; |
70ed7d01 |
70 | AliHLTUInt32_t AliHLTDataBuffer::fgMargin=1024; |
b22e91eb |
71 | AliHLTLogging AliHLTDataBuffer::fgLogging; |
8451168b |
72 | const Int_t AliHLTDataBuffer::fgkSafetyPatternSize=16; |
73 | const char AliHLTDataBuffer::fgkSafetyPattern[]={0x28, 0x63, 0x29, 0x4d, 0x52, 0x49, 0x43, 0x48, 0x54, 0x45, 0x52, 0x20, 0x32, 0x30, 0x30, 0x37}; |
b22e91eb |
74 | |
3f2a1b1c |
75 | AliHLTDataBuffer::~AliHLTDataBuffer() |
76 | { |
70ed7d01 |
77 | // see header file for function documentation |
78 | if (--fgNofInstances<=0) { |
3f2a1b1c |
79 | DeleteRawBuffers(); |
80 | } |
81 | CleanupConsumerList(); |
82 | } |
83 | |
0c0c9d99 |
84 | int AliHLTDataBuffer::SetConsumer(AliHLTComponent* pConsumer) |
3f2a1b1c |
85 | { |
70ed7d01 |
86 | // see header file for function documentation |
3f2a1b1c |
87 | int iResult=0; |
88 | if (pConsumer) { |
9ce4bf4a |
89 | if (FindConsumer(pConsumer)) { |
90 | HLTWarning("consumer %s (%p) already set to data buffer %p", pConsumer->GetComponentID(), pConsumer, this); |
91 | } |
0c0c9d99 |
92 | AliHLTConsumerDescriptor* pDesc=new AliHLTConsumerDescriptor(pConsumer); |
3f2a1b1c |
93 | if (pDesc) { |
94 | fConsumers.push_back(pDesc); |
9ce4bf4a |
95 | HLTDebug("set consumer %s (%p) to data buffer %p", pConsumer->GetComponentID(), pConsumer, this); |
3f2a1b1c |
96 | } else { |
97 | HLTError("memory allocation failed"); |
98 | iResult=-ENOMEM; |
99 | } |
100 | } else { |
9ce4bf4a |
101 | HLTError("invalid parameter: consumer component (nil)"); |
3f2a1b1c |
102 | iResult=-EINVAL; |
103 | } |
104 | return iResult; |
105 | } |
106 | |
8ede8717 |
107 | int AliHLTDataBuffer::FindMatchingDataBlocks(const AliHLTComponent* pConsumer, vector<AliHLTComponentDataType>* tgtList) |
0c0c9d99 |
108 | { |
70ed7d01 |
109 | // see header file for function documentation |
0c0c9d99 |
110 | int iResult=0; |
111 | if (pConsumer) { |
6235cd38 |
112 | vector<AliHLTDataBuffer::AliHLTDataSegment> segments; |
0c0c9d99 |
113 | if ((iResult=FindMatchingDataSegments(pConsumer, segments))>=0) { |
114 | if (tgtList) { |
6235cd38 |
115 | vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=segments.begin(); |
0c0c9d99 |
116 | while (segment!=segments.end()) { |
117 | tgtList->push_back((*segment).fDataType); |
118 | segment++; |
119 | } |
120 | } |
121 | iResult=segments.size(); |
122 | } |
123 | } else { |
124 | iResult=-EINVAL; |
125 | } |
126 | return iResult; |
127 | } |
128 | |
6235cd38 |
129 | int AliHLTDataBuffer::FindMatchingDataSegments(const AliHLTComponent* pConsumer, vector<AliHLTDataBuffer::AliHLTDataSegment>& tgtList) |
0c0c9d99 |
130 | { |
70ed7d01 |
131 | // see header file for function documentation |
0c0c9d99 |
132 | int iResult=0; |
9b7fe12d |
133 | |
134 | // Matthias 26.09.2007 relax the restriction to matching data blocks |
135 | // all blocks are passed to the consumer, which is the policy also in |
136 | // PubSub |
137 | tgtList.assign(fSegments.begin(), fSegments.end()); |
138 | iResult=tgtList.size(); |
139 | return iResult; |
140 | |
0c0c9d99 |
141 | if (pConsumer) { |
8ede8717 |
142 | vector<AliHLTComponentDataType> dtlist; |
0c0c9d99 |
143 | ((AliHLTComponent*)pConsumer)->GetInputDataTypes(dtlist); |
6235cd38 |
144 | vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=fSegments.begin(); |
0c0c9d99 |
145 | while (segment!=fSegments.end()) { |
8ede8717 |
146 | vector<AliHLTComponentDataType>::iterator type=dtlist.begin(); |
0c0c9d99 |
147 | while (type!=dtlist.end()) { |
9ce4bf4a |
148 | if ((*segment).fDataType==(*type) || |
149 | (*type)==kAliHLTAnyDataType) { |
0c0c9d99 |
150 | tgtList.push_back(*segment); |
151 | iResult++; |
152 | break; |
153 | } |
154 | type++; |
155 | } |
156 | segment++; |
157 | } |
158 | } else { |
159 | iResult=-EINVAL; |
160 | } |
161 | return iResult; |
162 | } |
163 | |
8ede8717 |
164 | int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponentBlockData* arrayBlockDesc, int iArraySize) |
3f2a1b1c |
165 | { |
70ed7d01 |
166 | // see header file for function documentation |
3f2a1b1c |
167 | int iResult=0; |
0c0c9d99 |
168 | if (pConsumer && arrayBlockDesc) { |
3f2a1b1c |
169 | if (fpBuffer) { |
0c0c9d99 |
170 | AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fConsumers); |
3f2a1b1c |
171 | if (pDesc) { |
6235cd38 |
172 | vector<AliHLTDataBuffer::AliHLTDataSegment> tgtList; |
9b7fe12d |
173 | // Matthias 26.07.2007 AliHLTSystem should behave the same way as PubSub |
174 | // so it does not matter if there are matching data types or not, unless |
175 | // we implement such a check in PubSub |
176 | if ((iResult=FindMatchingDataSegments(pConsumer, tgtList))>=0) { |
0c0c9d99 |
177 | int i =0; |
6235cd38 |
178 | vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=tgtList.begin(); |
0c0c9d99 |
179 | while (segment!=tgtList.end() && i<iArraySize) { |
3f2a1b1c |
180 | // fill the block data descriptor |
8ede8717 |
181 | arrayBlockDesc[i].fStructSize=sizeof(AliHLTComponentBlockData); |
3f2a1b1c |
182 | // the shared memory key is not used in AliRoot |
8ede8717 |
183 | arrayBlockDesc[i].fShmKey.fStructSize=sizeof(AliHLTComponentShmData); |
184 | arrayBlockDesc[i].fShmKey.fShmType=gkAliHLTComponentInvalidShmType; |
185 | arrayBlockDesc[i].fShmKey.fShmID=gkAliHLTComponentInvalidShmID; |
3294f81a |
186 | // This models the behavior of PubSub. |
187 | // For incoming data blocks, fOffset must be ignored by the |
188 | // processing component. It is set for bookkeeping in the framework. |
189 | // fPtr always points to the beginning of the data. |
0c0c9d99 |
190 | arrayBlockDesc[i].fOffset=(*segment).fSegmentOffset; |
3294f81a |
191 | AliHLTUInt8_t* pTgt=*fpBuffer; |
192 | pTgt+=(*segment).fSegmentOffset; |
193 | arrayBlockDesc[i].fPtr=reinterpret_cast<void*>(pTgt); |
0c0c9d99 |
194 | arrayBlockDesc[i].fSize=(*segment).fSegmentSize; |
195 | arrayBlockDesc[i].fDataType=(*segment).fDataType; |
196 | arrayBlockDesc[i].fSpecification=(*segment).fSpecification; |
197 | pDesc->SetActiveDataSegment(arrayBlockDesc[i].fOffset, arrayBlockDesc[i].fSize); |
1e6e67ec |
198 | HLTDebug("component %p (%s) subscribed to segment #%d offset %d size %d data type %s %#x", |
199 | pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), i, arrayBlockDesc[i].fOffset, |
200 | arrayBlockDesc[i].fSize, (AliHLTComponent::DataType2Text(arrayBlockDesc[i].fDataType)).c_str(), |
201 | arrayBlockDesc[i].fSpecification); |
0c0c9d99 |
202 | i++; |
203 | segment++; |
204 | } |
9b7fe12d |
205 | // check whether there was enough space for the segments |
298ef463 |
206 | if (i!=(int)tgtList.size()) { |
9b7fe12d |
207 | HLTError("too little space in block descriptor array: required %d, available %d", tgtList.size(), iArraySize); |
208 | iResult=-ENOSPC; |
209 | } else { |
0c0c9d99 |
210 | // move this consumer to the active list |
211 | if (ChangeConsumerState(pDesc, fConsumers, fActiveConsumers)>=0) { |
212 | HLTDebug("component %p (%s) subscribed to data buffer %p", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), this); |
3f2a1b1c |
213 | } else { |
0c0c9d99 |
214 | // TODO: cleanup the consumer descriptor correctly |
8ede8717 |
215 | memset(arrayBlockDesc, 0, iArraySize*sizeof(AliHLTComponentBlockData)); |
3f2a1b1c |
216 | HLTError("can not activate consumer %p for data buffer %p", pConsumer, this); |
217 | iResult=-EACCES; |
218 | } |
9b7fe12d |
219 | } |
3f2a1b1c |
220 | } else { |
0c0c9d99 |
221 | HLTError("unresolved data segment(s) for component %p (%s)", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID()); |
3f2a1b1c |
222 | iResult=-EBADF; |
223 | } |
224 | } else { |
0c0c9d99 |
225 | HLTError("component %p is not a data consumer of data buffer %s", pConsumer, this); |
3f2a1b1c |
226 | iResult=-ENOENT; |
227 | } |
228 | } else { |
9b7fe12d |
229 | // Matthias 26.07.2007 until now, data had to be present for successful subscription |
230 | // in order to be consistent with the PubSub framework, this restiction has been |
231 | // removed |
232 | //HLTError("data buffer %p is empty", this); |
233 | //iResult=-ENODATA; |
3f2a1b1c |
234 | } |
235 | } else { |
236 | HLTError("invalid parameter"); |
237 | iResult=-EINVAL; |
238 | } |
239 | return iResult; |
240 | } |
241 | |
8ede8717 |
242 | int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer) |
3f2a1b1c |
243 | { |
70ed7d01 |
244 | // see header file for function documentation |
3f2a1b1c |
245 | int iResult=0; |
246 | if (pBlockDesc && pConsumer) { |
0c0c9d99 |
247 | AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fActiveConsumers); |
248 | if (pDesc) { |
249 | if ((iResult=pDesc->CheckActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize))!=1) { |
250 | HLTWarning("data segment missmatch, component %p has not subscribed to a segment with offset %#x and size %d", pConsumer, pBlockDesc->fOffset, pBlockDesc->fSize); |
251 | // TODO: appropriate error handling, but so far optional |
252 | iResult=0; |
253 | } else { |
254 | pDesc->ReleaseActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize); |
3f2a1b1c |
255 | pBlockDesc->fOffset=0; |
256 | pBlockDesc->fPtr=NULL; |
257 | pBlockDesc->fSize=0; |
0c0c9d99 |
258 | } |
259 | if (pDesc->GetNofActiveSegments()==0) { |
3f2a1b1c |
260 | if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) { |
b426991e |
261 | if (GetNofActiveConsumers()==0 && GetNofPendingConsumers()==0) { |
0c0c9d99 |
262 | // this is the last consumer, reset the consumer list and release the raw buffer |
3f2a1b1c |
263 | ResetDataBuffer(); |
3f2a1b1c |
264 | } |
265 | } else { |
266 | HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this); |
267 | iResult=-EACCES; |
268 | } |
3f2a1b1c |
269 | } |
0c0c9d99 |
270 | } else { |
271 | HLTWarning("component %p has currently not subscribed to the data buffer %p", pConsumer, this); |
272 | iResult=-ENOENT; |
273 | } |
3f2a1b1c |
274 | } else { |
275 | HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer); |
276 | iResult=-EINVAL; |
277 | } |
278 | return iResult; |
279 | } |
280 | |
281 | AliHLTUInt8_t* AliHLTDataBuffer::GetTargetBuffer(int iMinSize) |
282 | { |
70ed7d01 |
283 | // see header file for function documentation |
3f2a1b1c |
284 | AliHLTUInt8_t* pTargetBuffer=NULL; |
b6800be0 |
285 | if (fpBuffer!=NULL) { |
286 | HLTWarning("data buffer not properly reset, possible memory leak\n"); |
287 | } |
3f2a1b1c |
288 | fpBuffer=CreateRawBuffer(iMinSize); |
9ce4bf4a |
289 | if (fpBuffer) { |
1e6e67ec |
290 | pTargetBuffer=*fpBuffer; |
9ce4bf4a |
291 | } else { |
292 | HLTError("can not create raw buffer"); |
293 | } |
3f2a1b1c |
294 | return pTargetBuffer; |
295 | } |
296 | |
8ede8717 |
297 | int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arrayBlockData, int iSize) |
3f2a1b1c |
298 | { |
70ed7d01 |
299 | // see header file for function documentation |
3f2a1b1c |
300 | int iResult=0; |
301 | if (pTgt && arrayBlockData && iSize>=0) { |
0c0c9d99 |
302 | if (fpBuffer) { |
1e6e67ec |
303 | if (*fpBuffer==pTgt) { |
6235cd38 |
304 | AliHLTDataBuffer::AliHLTDataSegment segment; |
0c0c9d99 |
305 | for (int i=0; i<iSize; i++) { |
3294f81a |
306 | // This function has to model the behavior of PubSub |
307 | // For output blocks only the fOffset value is used, this must be the offset |
308 | // relative to the output pointer. fPtr must be either NULL or the output |
309 | // pointer |
6434d28a |
310 | if (arrayBlockData[i].fPtr==NULL || |
3294f81a |
311 | arrayBlockData[i].fPtr==*fpBuffer) { |
c0a2bfc2 |
312 | if (arrayBlockData[i].fOffset+arrayBlockData[i].fSize<=fpBuffer->GetUsedSize()) { |
3294f81a |
313 | segment.fSegmentOffset=arrayBlockData[i].fOffset; |
1e6e67ec |
314 | segment.fSegmentSize=arrayBlockData[i].fSize; |
315 | segment.fDataType=arrayBlockData[i].fDataType; |
316 | segment.fSpecification=arrayBlockData[i].fSpecification; |
317 | fSegments.push_back(segment); |
318 | HLTDebug("set segment %s with size %d at offset %d", AliHLTComponent::DataType2Text(segment.fDataType).data(), segment.fSegmentSize, segment.fSegmentOffset); |
319 | } else { |
320 | HLTError("block data specification %#d (%s) exceeds size of data buffer", i, AliHLTComponent::DataType2Text(arrayBlockData[i].fDataType).data()); |
c0a2bfc2 |
321 | HLTError("block offset=%d, block size=%d, buffer size=%d", arrayBlockData[i].fOffset, arrayBlockData[i].fSize, fpBuffer->GetUsedSize()); |
1e6e67ec |
322 | iResult=-E2BIG; |
323 | } |
0c0c9d99 |
324 | } else { |
3294f81a |
325 | HLTError("invalid pointer (%p) in block data specification (buffer %p size %d)." |
326 | "please note: for output blocks only the fOffset value is valid and must " |
c0a2bfc2 |
327 | "be relative to the output buffer", arrayBlockData[i].fPtr, fpBuffer->GetPointer(), fpBuffer->GetUsedSize()); |
1e6e67ec |
328 | iResult=-ERANGE; |
0c0c9d99 |
329 | } |
330 | } |
3f2a1b1c |
331 | } else { |
c0a2bfc2 |
332 | HLTError("this data buffer (%p) does not match the internal data buffer %p of raw buffer %p", pTgt, fpBuffer->GetPointer(), fpBuffer); |
8451168b |
333 | iResult=-EINVAL; |
3f2a1b1c |
334 | } |
0c0c9d99 |
335 | } else { |
336 | HLTFatal("internal data structur missmatch"); |
337 | iResult=-EFAULT; |
3f2a1b1c |
338 | } |
339 | } else { |
0c0c9d99 |
340 | HLTError("invalid parameter: pTgtBuffer=%p arrayBlockData=%p", pTgt, arrayBlockData); |
3f2a1b1c |
341 | iResult=-EINVAL; |
342 | } |
343 | return iResult; |
344 | } |
345 | |
346 | int AliHLTDataBuffer::IsEmpty() |
347 | { |
70ed7d01 |
348 | // see header file for function documentation |
3f2a1b1c |
349 | int iResult=fpBuffer==NULL || GetNofSegments()==0; |
350 | return iResult; |
351 | } |
352 | |
353 | int AliHLTDataBuffer::GetNofSegments() |
354 | { |
70ed7d01 |
355 | // see header file for function documentation |
3f2a1b1c |
356 | int iResult=fSegments.size(); |
357 | return iResult; |
358 | } |
359 | |
360 | int AliHLTDataBuffer::GetNofConsumers() |
361 | { |
70ed7d01 |
362 | // see header file for function documentation |
3f2a1b1c |
363 | int iResult=fConsumers.size() + GetNofActiveConsumers() + fReleasedConsumers.size(); |
364 | return iResult; |
365 | } |
366 | |
b426991e |
367 | int AliHLTDataBuffer::GetNofPendingConsumers() |
368 | { |
369 | // see header file for function documentation |
370 | int iResult=fConsumers.size(); |
371 | return iResult; |
372 | } |
373 | |
3f2a1b1c |
374 | int AliHLTDataBuffer::GetNofActiveConsumers() |
375 | { |
70ed7d01 |
376 | // see header file for function documentation |
3f2a1b1c |
377 | int iResult=fActiveConsumers.size(); |
378 | return iResult; |
379 | } |
380 | |
6235cd38 |
381 | AliHLTDataBuffer::AliHLTRawBuffer* AliHLTDataBuffer::CreateRawBuffer(AliHLTUInt32_t size) |
3f2a1b1c |
382 | { |
70ed7d01 |
383 | // see header file for function documentation |
3f2a1b1c |
384 | AliHLTRawBuffer* pRawBuffer=NULL; |
7a5ccd96 |
385 | unsigned int reqSize=size+fgkSafetyPatternSize; |
70ed7d01 |
386 | vector<AliHLTRawBuffer*>::iterator buffer=fgFreeBuffers.begin(); |
387 | while (buffer!=fgFreeBuffers.end() && pRawBuffer==NULL) { |
d6cbe999 |
388 | if ((*buffer)->CheckSize(reqSize)) { |
3f2a1b1c |
389 | // assign this element |
390 | pRawBuffer=*buffer; |
d6cbe999 |
391 | pRawBuffer->UseBuffer(size); |
70ed7d01 |
392 | fgFreeBuffers.erase(buffer); |
c0a2bfc2 |
393 | fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "raw buffer container %p provided for request of %d bytes (total %d available in buffer %p)", pRawBuffer, size, pRawBuffer->GetTotalSize(), pRawBuffer->GetPointer()); |
70ed7d01 |
394 | fgActiveBuffers.push_back(pRawBuffer); |
0c0c9d99 |
395 | break; |
3f2a1b1c |
396 | } |
0c0c9d99 |
397 | buffer++; |
3f2a1b1c |
398 | } |
399 | if (pRawBuffer==NULL) { |
0c0c9d99 |
400 | // no buffer found, create a new one |
d6cbe999 |
401 | pRawBuffer=new AliHLTRawBuffer(reqSize); |
3f2a1b1c |
402 | if (pRawBuffer) { |
c0a2bfc2 |
403 | if (pRawBuffer->GetPointer()) { |
d6cbe999 |
404 | pRawBuffer->UseBuffer(size); |
70ed7d01 |
405 | fgActiveBuffers.push_back(pRawBuffer); |
c0a2bfc2 |
406 | fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "new raw buffer %p of size %d created (container %p)", pRawBuffer->GetPointer(), pRawBuffer->GetTotalSize(), pRawBuffer); |
3f2a1b1c |
407 | } else { |
408 | delete pRawBuffer; |
409 | pRawBuffer=NULL; |
0c0c9d99 |
410 | fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "memory allocation failed"); |
3f2a1b1c |
411 | } |
412 | } else { |
0c0c9d99 |
413 | fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "memory allocation failed"); |
3f2a1b1c |
414 | } |
415 | } |
73ede1d3 |
416 | if (pRawBuffer!=NULL && fgkSafetyPatternSize>0) { |
c0a2bfc2 |
417 | //fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "writing safety pattern to %p offset %d", (*buffer)->GetPointer(), (*buffer)->GetUsedSize()); |
d6cbe999 |
418 | int res=pRawBuffer->WritePattern(fgkSafetyPattern, fgkSafetyPatternSize); |
419 | assert(res>=0); |
73ede1d3 |
420 | } |
3f2a1b1c |
421 | return pRawBuffer; |
422 | } |
423 | |
424 | int AliHLTDataBuffer::ReleaseRawBuffer(AliHLTRawBuffer* pBuffer) |
425 | { |
70ed7d01 |
426 | // see header file for function documentation |
3f2a1b1c |
427 | int iResult=0; |
428 | if (pBuffer) { |
70ed7d01 |
429 | vector<AliHLTRawBuffer*>::iterator buffer=fgActiveBuffers.begin(); |
430 | while (buffer!=fgActiveBuffers.end() && (*buffer)!=pBuffer) { |
3f2a1b1c |
431 | buffer++; |
432 | } |
70ed7d01 |
433 | if (buffer!=fgActiveBuffers.end()) { |
8451168b |
434 | if (fgkSafetyPatternSize>0) { |
c0a2bfc2 |
435 | //fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "comparing safety pattern at %p offset %d", (*buffer)->GetPointer(), reinterpret_cast<AliHLTUInt32_t>(*buffer)); |
d6cbe999 |
436 | if ((*buffer)->CheckPattern(fgkSafetyPattern, fgkSafetyPatternSize)) { |
c0a2bfc2 |
437 | fgLogging.Logging(kHLTLogFatal, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "component has written beyond end of data buffer %p size %d", (*buffer)->GetPointer(), (*buffer)->GetUsedSize()); |
8451168b |
438 | } |
439 | } |
d6cbe999 |
440 | (*buffer)->Reset(); |
70ed7d01 |
441 | fgFreeBuffers.push_back(*buffer); |
442 | fgActiveBuffers.erase(buffer); |
3f2a1b1c |
443 | } else { |
0c0c9d99 |
444 | fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "can not find raw buffer container %p in the list of active containers", pBuffer); |
3f2a1b1c |
445 | iResult=-ENOENT; |
446 | } |
447 | } else { |
0c0c9d99 |
448 | fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "invalid parameter"); |
3f2a1b1c |
449 | iResult=-EINVAL; |
450 | } |
451 | return iResult; |
452 | } |
453 | |
454 | |
455 | int AliHLTDataBuffer::DeleteRawBuffers() |
456 | { |
70ed7d01 |
457 | // see header file for function documentation |
3f2a1b1c |
458 | int iResult=0; |
70ed7d01 |
459 | vector<AliHLTRawBuffer*>::iterator buffer=fgFreeBuffers.begin(); |
460 | while (buffer!=fgFreeBuffers.end()) { |
3f2a1b1c |
461 | delete *buffer; |
70ed7d01 |
462 | fgFreeBuffers.erase(buffer); |
463 | buffer=fgFreeBuffers.begin(); |
3f2a1b1c |
464 | } |
70ed7d01 |
465 | buffer=fgActiveBuffers.begin(); |
466 | while (buffer!=fgActiveBuffers.end()) { |
c0a2bfc2 |
467 | fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "request to delete active raw buffer container (raw buffer %p, size %d)", (*buffer)->GetPointer(), (*buffer)->GetTotalSize()); |
3f2a1b1c |
468 | delete *buffer; |
70ed7d01 |
469 | fgActiveBuffers.erase(buffer); |
470 | buffer=fgActiveBuffers.begin(); |
3f2a1b1c |
471 | } |
472 | return iResult; |
473 | } |
474 | |
70ed7d01 |
475 | AliHLTConsumerDescriptor* AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, vector<AliHLTConsumerDescriptor*> &list) const |
3f2a1b1c |
476 | { |
70ed7d01 |
477 | // see header file for function documentation |
3f2a1b1c |
478 | AliHLTConsumerDescriptor* pDesc=NULL; |
479 | vector<AliHLTConsumerDescriptor*>::iterator desc=list.begin(); |
480 | while (desc!=list.end() && pDesc==NULL) { |
0c0c9d99 |
481 | if ((pConsumer==NULL || (*desc)->GetComponent()==pConsumer)) { |
3f2a1b1c |
482 | pDesc=*desc; |
483 | } |
0c0c9d99 |
484 | desc++; |
3f2a1b1c |
485 | } |
486 | return pDesc; |
487 | } |
488 | |
0c0c9d99 |
489 | int AliHLTDataBuffer::ResetDataBuffer() |
490 | { |
70ed7d01 |
491 | // see header file for function documentation |
3f2a1b1c |
492 | int iResult=0; |
0c0c9d99 |
493 | AliHLTRawBuffer* pBuffer=fpBuffer; |
3f2a1b1c |
494 | fpBuffer=NULL; |
9ce4bf4a |
495 | |
496 | // cleanup consumer states |
b426991e |
497 | vector<AliHLTConsumerDescriptor*>::iterator desc; |
498 | // if (GetNofPendingConsumers()>0) { |
499 | // desc=fConsumers.begin(); |
500 | // while (desc!=fConsumers.end()) { |
501 | // AliHLTComponent* pComp=(*desc)->GetComponent(); |
502 | // HLTError("internal error: consumer %p (%s %p) did not get data from data buffer %p", *desc, pComp?pComp->GetComponentID():"", pComp, this); |
503 | // desc++; |
504 | // } |
505 | // } |
506 | desc=fReleasedConsumers.begin(); |
3f2a1b1c |
507 | while (desc!=fReleasedConsumers.end()) { |
508 | AliHLTConsumerDescriptor* pDesc=*desc; |
509 | fReleasedConsumers.erase(desc); |
510 | desc=fReleasedConsumers.begin(); |
511 | fConsumers.push_back(pDesc); |
512 | } |
513 | desc=fActiveConsumers.begin(); |
514 | while (desc!=fActiveConsumers.end()) { |
515 | AliHLTConsumerDescriptor* pDesc=*desc; |
516 | HLTWarning("consumer %p was not released", pDesc); |
517 | fActiveConsumers.erase(desc); |
518 | desc=fActiveConsumers.begin(); |
519 | fConsumers.push_back(pDesc); |
520 | } |
9ce4bf4a |
521 | |
522 | // cleanup segments |
6235cd38 |
523 | vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=fSegments.begin(); |
9ce4bf4a |
524 | while (segment!=fSegments.end()) { |
525 | fSegments.erase(segment); |
526 | segment=fSegments.begin(); |
527 | } |
528 | |
529 | // cleanup raw buffer |
530 | if (pBuffer) { |
531 | ReleaseRawBuffer(pBuffer); |
532 | } |
3f2a1b1c |
533 | return iResult; |
534 | } |
535 | |
9ce4bf4a |
536 | int AliHLTDataBuffer::Reset() |
537 | { |
70ed7d01 |
538 | // see header file for function documentation |
9ce4bf4a |
539 | return ResetDataBuffer(); |
540 | } |
541 | |
0c0c9d99 |
542 | // this is the version which works on lists of components instead of consumer descriptors |
543 | // int AliHLTDataBuffer::ChangeConsumerState(AliHLTComponent* pConsumer, vector<AliHLTComponent*> &srcList, vector<AliHLTComponent*> &tgtList) |
544 | // { |
545 | // int iResult=0; |
546 | // if (pDesc) { |
547 | // vector<AliHLTComponent*>::iterator desc=srcList.begin(); |
548 | // while (desc!=srcList.end()) { |
549 | // if ((*desc)==pConsumer) { |
550 | // srcList.erase(desc); |
551 | // tgtList.push_back(pConsumer); |
552 | // break; |
553 | // } |
554 | // desc++; |
555 | // } |
556 | // if (desc==srcList.end()) { |
557 | // HLTError("can not find consumer component %p in list", pConsumer); |
558 | // iResult=-ENOENT; |
559 | // } |
560 | // } else { |
561 | // HLTError("invalid parameter"); |
562 | // iResult=-EINVAL; |
563 | // } |
564 | // return iResult; |
565 | // } |
566 | |
3f2a1b1c |
567 | int AliHLTDataBuffer::ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, vector<AliHLTConsumerDescriptor*> &srcList, vector<AliHLTConsumerDescriptor*> &tgtList) |
568 | { |
70ed7d01 |
569 | // see header file for function documentation |
9ce4bf4a |
570 | int iResult=-ENOENT; |
3f2a1b1c |
571 | if (pDesc) { |
572 | vector<AliHLTConsumerDescriptor*>::iterator desc=srcList.begin(); |
573 | while (desc!=srcList.end()) { |
574 | if ((*desc)==pDesc) { |
575 | srcList.erase(desc); |
576 | tgtList.push_back(pDesc); |
9ce4bf4a |
577 | iResult=0; |
3f2a1b1c |
578 | break; |
579 | } |
0c0c9d99 |
580 | desc++; |
3f2a1b1c |
581 | } |
9ce4bf4a |
582 | if (iResult<0) { |
3f2a1b1c |
583 | HLTError("can not find consumer descriptor %p in list", pDesc); |
3f2a1b1c |
584 | } |
585 | } else { |
586 | HLTError("invalid parameter"); |
587 | iResult=-EINVAL; |
588 | } |
589 | return iResult; |
590 | } |
591 | |
70ed7d01 |
592 | int AliHLTDataBuffer::CleanupConsumerList() |
593 | { |
594 | // see header file for function documentation |
3f2a1b1c |
595 | int iResult=0; |
596 | ResetDataBuffer(); |
597 | vector<AliHLTConsumerDescriptor*>::iterator desc=fConsumers.begin(); |
598 | while (desc!=fConsumers.end()) { |
599 | delete *desc; |
600 | fConsumers.erase(desc); |
601 | desc=fConsumers.begin(); |
602 | } |
603 | return iResult; |
604 | } |
9ce4bf4a |
605 | |
70ed7d01 |
606 | int AliHLTDataBuffer::FindConsumer(AliHLTComponent* pConsumer, int bAllLists) |
607 | { |
608 | // see header file for function documentation |
9ce4bf4a |
609 | vector<AliHLTConsumerDescriptor*>::iterator desc=fConsumers.begin(); |
610 | while (desc!=fConsumers.end()) { |
611 | if ((*desc)->GetComponent()==pConsumer) |
612 | return 1; |
613 | desc++; |
614 | } |
615 | if (bAllLists==0) return 0; |
616 | |
617 | desc=fActiveConsumers.begin(); |
618 | while (desc!=fActiveConsumers.end()) { |
619 | if ((*desc)->GetComponent()==pConsumer) |
620 | return 1; |
621 | desc++; |
622 | } |
623 | desc=fReleasedConsumers.begin(); |
624 | while (desc!=fReleasedConsumers.end()) { |
625 | if ((*desc)->GetComponent()==pConsumer) |
626 | return 1; |
627 | desc++; |
628 | } |
629 | return 0; |
630 | } |
1e6e67ec |
631 | |
d6cbe999 |
632 | AliHLTDataBuffer::AliHLTRawBuffer::AliHLTRawBuffer(AliHLTUInt32_t size) |
633 | : |
c0a2bfc2 |
634 | fSize(0), |
d6cbe999 |
635 | fTotalSize(size), |
636 | fPtr(static_cast<AliHLTUInt8_t*>(malloc(size))) |
637 | { |
638 | // see header file for class documentation |
639 | // or |
640 | // refer to README to build package |
641 | // or |
642 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt |
643 | if (fPtr==NULL) { |
644 | fSize=0; |
645 | fTotalSize=0; |
646 | } |
647 | } |
648 | |
649 | AliHLTDataBuffer::AliHLTRawBuffer::~AliHLTRawBuffer() |
650 | { |
651 | if (fPtr) { |
652 | free(fPtr); |
653 | } |
654 | fPtr=NULL; |
655 | fSize=0; |
656 | fTotalSize=0; |
657 | } |
658 | |
3a7c0444 |
659 | int AliHLTDataBuffer::AliHLTRawBuffer::operator==(void* ptr) const |
1e6e67ec |
660 | { |
3a7c0444 |
661 | // see header file for function documentation |
1e6e67ec |
662 | return fPtr == static_cast<AliHLTUInt8_t*>(ptr); |
663 | } |
664 | |
3a7c0444 |
665 | int AliHLTDataBuffer::AliHLTRawBuffer::operator<=(void* ptr) const |
1e6e67ec |
666 | { |
3a7c0444 |
667 | // see header file for function documentation |
1e6e67ec |
668 | int iResult=fPtr <= static_cast<AliHLTUInt8_t*>(ptr); |
669 | //printf("%p: %p <= %p (%d)\n", this, fPtr, ptr, iResult); |
670 | return iResult; |
671 | } |
672 | |
3a7c0444 |
673 | int AliHLTDataBuffer::AliHLTRawBuffer::operator>(void* ptr) const |
1e6e67ec |
674 | { |
3a7c0444 |
675 | // see header file for function documentation |
1e6e67ec |
676 | int iResult=fPtr+fSize > static_cast<AliHLTUInt8_t*>(ptr); |
677 | //printf("%p: %p + %d > %p (%d)\n", this, fPtr, fSize, ptr, iResult); |
678 | return iResult; |
679 | } |
680 | |
3a7c0444 |
681 | int AliHLTDataBuffer::AliHLTRawBuffer::operator-(void* ptr) const |
1e6e67ec |
682 | { |
3a7c0444 |
683 | // see header file for function documentation |
1e6e67ec |
684 | return static_cast<int>(static_cast<AliHLTUInt8_t*>(ptr)-fPtr); |
685 | } |
d6cbe999 |
686 | |
687 | AliHLTUInt8_t* AliHLTDataBuffer::AliHLTRawBuffer::UseBuffer(AliHLTUInt32_t size) |
688 | { |
689 | // see header file for function documentation |
690 | if (size>0 && CheckSize(size)) { |
691 | fSize=size; |
692 | return fPtr; |
693 | } |
694 | return NULL; |
695 | } |
696 | |
697 | int AliHLTDataBuffer::AliHLTRawBuffer::CheckSize(AliHLTUInt32_t size) const |
698 | { |
699 | // see header file for function documentation |
700 | return fTotalSize>=size && ((fTotalSize-size)<fgMargin); |
701 | } |
702 | |
703 | int AliHLTDataBuffer::AliHLTRawBuffer::Reset() |
704 | { |
705 | // see header file for function documentation |
706 | fSize=0; |
707 | } |
708 | |
709 | int AliHLTDataBuffer::AliHLTRawBuffer::WritePattern(const char* pattern, int size) |
710 | { |
711 | // see header file for function documentation |
712 | int iResult=0; |
713 | if (pattern!=NULL && size>0) { |
714 | if (fSize+size<=fTotalSize) { |
715 | memcpy(((char*)fPtr)+fSize, pattern, size); |
716 | iResult=size; |
717 | } else { |
718 | iResult=-ENOSPC; |
719 | } |
720 | } |
721 | return iResult; |
722 | } |
723 | |
724 | int AliHLTDataBuffer::AliHLTRawBuffer::CheckPattern(const char* pattern, int size) const |
725 | { |
726 | // see header file for function documentation |
727 | int iResult=0; |
728 | if (pattern!=NULL && size>0) { |
729 | if (fSize+size<=fTotalSize) { |
730 | iResult=memcmp(((char*)fPtr)+fSize, pattern, size)!=0; |
731 | } else { |
732 | iResult=-ENOSPC; |
733 | } |
734 | } |
735 | return iResult; |
736 | } |