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