]>
Commit | Line | Data |
---|---|---|
7a436c89 | 1 | // $Id$ |
2 | // splitted from AliHLTConfiguration.cxx,v 1.25 2007/10/12 13:24:47 | |
3 | /************************************************************************** | |
4 | * This file is property of and copyright by the ALICE HLT Project * | |
5 | * ALICE Experiment at CERN, All rights reserved. * | |
6 | * * | |
7 | * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
8 | * for The ALICE HLT Project. * | |
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 | ||
19 | /** @file AliHLTTask.cxx | |
20 | @author Matthias Richter | |
21 | @date | |
22 | @brief Implementation of HLT tasks. | |
23 | */ | |
24 | ||
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 | ||
31 | #if __GNUC__>= 3 | |
32 | using namespace std; | |
33 | #endif | |
34 | ||
35 | #include <cerrno> | |
b46ca65e | 36 | #include <cassert> |
7a436c89 | 37 | #include <iostream> |
38 | #include <string> | |
39 | #include "AliHLTTask.h" | |
40 | #include "AliHLTConfiguration.h" | |
41 | #include "AliHLTComponent.h" | |
42 | #include "AliHLTComponentHandler.h" | |
43 | #include "TList.h" | |
44 | ||
45 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
46 | ClassImp(AliHLTTask) | |
47 | ||
48 | AliHLTTask::AliHLTTask() | |
49 | : | |
50 | fpConfiguration(NULL), | |
51 | fpComponent(NULL), | |
52 | fpDataBuffer(NULL), | |
53 | fListTargets(), | |
54 | fListDependencies(), | |
55 | fBlockDataArray() | |
56 | { | |
57 | // see header file for class documentation | |
58 | // or | |
59 | // refer to README to build package | |
60 | // or | |
61 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
62 | } | |
63 | ||
64 | AliHLTTask::AliHLTTask(AliHLTConfiguration* pConf) | |
65 | : | |
66 | fpConfiguration(pConf), | |
67 | fpComponent(NULL), | |
68 | fpDataBuffer(NULL), | |
69 | fListTargets(), | |
70 | fListDependencies(), | |
71 | fBlockDataArray() | |
72 | { | |
73 | // see header file for function documentation | |
74 | } | |
75 | ||
76 | AliHLTTask::~AliHLTTask() | |
77 | { | |
78 | // see header file for function documentation | |
79 | TObjLink* lnk=fListDependencies.FirstLink(); | |
80 | ||
81 | while (lnk!=NULL) { | |
82 | AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject(); | |
83 | pTask->UnsetTarget(this); | |
84 | lnk=lnk->Next(); | |
85 | } | |
86 | lnk=fListTargets.FirstLink(); | |
87 | ||
88 | while (lnk!=NULL) { | |
89 | AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject(); | |
90 | pTask->UnsetDependency(this); | |
91 | lnk=lnk->Next(); | |
92 | } | |
93 | ||
94 | if (fpComponent) delete fpComponent; | |
95 | fpComponent=NULL; | |
96 | } | |
97 | ||
98 | int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH) | |
99 | { | |
100 | // see header file for function documentation | |
101 | int iResult=0; | |
102 | if (fpConfiguration!=NULL && pConf!=NULL && fpConfiguration!=pConf) { | |
103 | HLTWarning("overriding existing reference to configuration object %p (%s) by %p", | |
104 | fpConfiguration, GetName(), pConf); | |
105 | } | |
106 | if (pConf!=NULL) fpConfiguration=pConf; | |
48abe484 | 107 | iResult=CreateComponent(fpConfiguration, pCH, fpComponent); |
108 | if (iResult>=0) { | |
109 | iResult=CustomInit(pCH); | |
110 | } | |
111 | return iResult; | |
112 | } | |
113 | ||
114 | int AliHLTTask::CreateComponent(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH, AliHLTComponent*& pComponent) const | |
115 | { | |
116 | // see header file for class documentation | |
117 | int iResult=0; | |
118 | if (pConf) { | |
7a436c89 | 119 | if (pCH) { |
120 | int argc=0; | |
121 | const char** argv=NULL; | |
48abe484 | 122 | if ((iResult=pConf->GetArguments(&argv))>=0) { |
7a436c89 | 123 | argc=iResult; // just to make it clear |
124 | // TODO: we have to think about the optional environment parameter, | |
48abe484 | 125 | // currently just set to NULL. |
126 | iResult=pCH->CreateComponent(pConf->GetComponentID(), pComponent); | |
127 | if (pComponent && iResult>=0) { | |
128 | TString description; | |
129 | description.Form("chainid=%s", GetName()); | |
130 | pComponent->SetComponentDescription(description.Data()); | |
131 | const AliHLTAnalysisEnvironment* pEnv=pCH->GetEnvironment(); | |
132 | if ((iResult=pComponent->Init(pEnv, NULL, argc, argv))>=0) { | |
133 | //HLTDebug("component %s (%p) created", pComponent->GetComponentID(), pComponent); | |
134 | } else { | |
135 | HLTError("Initialization of component \"%s\" failed with error %d", pComponent->GetComponentID(), iResult); | |
136 | } | |
7a436c89 | 137 | } else { |
48abe484 | 138 | //HLTError("can not find component \"%s\" (%d)", pConf->GetComponentID(), iResult); |
7a436c89 | 139 | } |
140 | } else { | |
48abe484 | 141 | HLTError("can not get argument list for configuration %s (%s)", pConf->GetName(), pConf->GetComponentID()); |
7a436c89 | 142 | iResult=-EINVAL; |
143 | } | |
144 | } else { | |
145 | HLTError("component handler instance needed for task initialization"); | |
146 | iResult=-EINVAL; | |
147 | } | |
148 | } else { | |
149 | HLTError("configuration object instance needed for task initialization"); | |
150 | iResult=-EINVAL; | |
151 | } | |
152 | return iResult; | |
153 | } | |
154 | ||
155 | int AliHLTTask::Deinit() | |
156 | { | |
157 | // see header file for function documentation | |
158 | int iResult=0; | |
7131ea63 | 159 | CustomCleanup(); |
7a436c89 | 160 | AliHLTComponent* pComponent=GetComponent(); |
161 | fpComponent=NULL; | |
162 | if (pComponent) { | |
163 | //HLTDebug("delete component %s (%p)", pComponent->GetComponentID(), pComponent); | |
164 | pComponent->Deinit(); | |
165 | delete pComponent; | |
166 | } else { | |
167 | HLTWarning("task %s (%p) doesn't seem to be in initialized", GetName(), this); | |
168 | } | |
169 | return iResult; | |
170 | } | |
171 | ||
172 | const char *AliHLTTask::GetName() const | |
173 | { | |
174 | // see header file for function documentation | |
175 | if (fpConfiguration) | |
176 | return fpConfiguration->GetName(); | |
177 | return TObject::GetName(); | |
178 | } | |
179 | ||
180 | AliHLTConfiguration* AliHLTTask::GetConf() const | |
181 | { | |
182 | // see header file for function documentation | |
183 | return fpConfiguration; | |
184 | } | |
185 | ||
186 | AliHLTComponent* AliHLTTask::GetComponent() const | |
187 | { | |
188 | // see header file for function documentation | |
189 | return fpComponent; | |
190 | } | |
191 | ||
192 | AliHLTTask* AliHLTTask::FindDependency(const char* id) | |
193 | { | |
194 | // see header file for function documentation | |
195 | AliHLTTask* pTask=NULL; | |
196 | if (id) { | |
197 | pTask=(AliHLTTask*)fListDependencies.FindObject(id); | |
198 | } | |
199 | return pTask; | |
200 | } | |
201 | ||
202 | int AliHLTTask::FollowDependency(const char* id, TList* pTgtList) | |
203 | { | |
204 | // see header file for function documentation | |
205 | int iResult=0; | |
206 | if (id) { | |
207 | AliHLTTask* pDep=NULL; | |
208 | if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) { | |
209 | if (pTgtList) pTgtList->Add(pDep); | |
210 | iResult++; | |
211 | } else { | |
212 | TObjLink* lnk=fListDependencies.FirstLink(); | |
213 | while (lnk && iResult==0) { | |
214 | pDep=(AliHLTTask*)lnk->GetObject(); | |
215 | if (pDep) { | |
216 | if ((iResult=pDep->FollowDependency(id, pTgtList))>0) { | |
217 | if (pTgtList) pTgtList->AddFirst(pDep); | |
218 | iResult++; | |
219 | } | |
220 | } else { | |
221 | iResult=-EFAULT; | |
222 | } | |
223 | lnk=lnk->Next(); | |
224 | } | |
225 | } | |
226 | } else { | |
227 | iResult=-EINVAL; | |
228 | } | |
229 | return iResult; | |
230 | } | |
231 | ||
232 | void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration) | |
233 | { | |
234 | // see header file for function documentation | |
235 | HLTLogKeyword("task dependencies"); | |
236 | int iResult=0; | |
237 | TList tgtList; | |
238 | if (bFromConfiguration) { | |
239 | if (fpConfiguration) | |
240 | iResult=fpConfiguration->FollowDependency(id, &tgtList); | |
241 | else | |
242 | iResult=-EFAULT; | |
243 | } else | |
244 | iResult=FollowDependency(id, &tgtList); | |
245 | if (iResult>0) { | |
246 | HLTMessage(" task \"%s\": dependency level %d ", GetName(), iResult); | |
247 | TObjLink* lnk=tgtList.FirstLink(); | |
248 | int i=iResult; | |
249 | char* pSpace = new char[iResult+1]; | |
250 | if (pSpace) { | |
251 | memset(pSpace, 32, iResult); | |
252 | pSpace[i]=0; | |
253 | while (lnk) { | |
254 | TObject* obj=lnk->GetObject(); | |
255 | HLTMessage(" %s^-- %s ", &pSpace[i--], obj->GetName()); | |
256 | lnk=lnk->Next(); | |
257 | } | |
258 | delete [] pSpace; | |
259 | } else { | |
260 | iResult=-ENOMEM; | |
261 | } | |
262 | } | |
263 | } | |
264 | ||
265 | int AliHLTTask::SetDependency(AliHLTTask* pDep) | |
266 | { | |
267 | // see header file for function documentation | |
268 | int iResult=0; | |
269 | if (pDep) { | |
270 | if (FindDependency(pDep->GetName())==NULL) { | |
271 | fListDependencies.Add(pDep); | |
272 | } else { | |
273 | iResult=-EEXIST; | |
274 | } | |
275 | } else { | |
276 | iResult=-EINVAL; | |
277 | } | |
278 | return iResult; | |
279 | } | |
280 | ||
281 | int AliHLTTask::UnsetDependency(AliHLTTask* pDep) | |
282 | { | |
283 | // see header file for function documentation | |
284 | fListDependencies.Remove(pDep); | |
285 | if (fpConfiguration) { | |
286 | fpConfiguration->InvalidateSources(); | |
287 | } | |
288 | return 0; | |
289 | } | |
290 | ||
291 | int AliHLTTask::CheckDependencies() | |
292 | { | |
293 | // see header file for function documentation | |
294 | int iResult=0; | |
295 | AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource(); | |
296 | while (pSrc) { | |
297 | if (FindDependency(pSrc->GetName())==NULL) { | |
298 | //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName()); | |
299 | iResult++; | |
300 | } | |
301 | pSrc=fpConfiguration->GetNextSource(); | |
302 | } | |
303 | return iResult; | |
304 | } | |
305 | ||
306 | ||
307 | int AliHLTTask::Depends(AliHLTTask* pTask) | |
308 | { | |
309 | // see header file for function documentation | |
310 | int iResult=0; | |
311 | if (pTask) { | |
312 | if (fpConfiguration) { | |
313 | iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL; | |
314 | if (iResult>0) { | |
315 | //HLTDebug("task \"%s\" depends on \"%s\"", GetName(), pTask->GetName()); | |
316 | } else { | |
317 | //HLTDebug("task \"%s\" independend of \"%s\"", GetName(), pTask->GetName()); | |
318 | } | |
319 | } else { | |
320 | iResult=-EFAULT; | |
321 | } | |
322 | } else { | |
323 | iResult=-EINVAL; | |
324 | } | |
325 | return iResult; | |
326 | } | |
327 | ||
328 | AliHLTTask* AliHLTTask::FindTarget(const char* id) | |
329 | { | |
330 | // see header file for function documentation | |
331 | AliHLTTask* pTask=NULL; | |
332 | if (id) { | |
333 | pTask=(AliHLTTask*)fListTargets.FindObject(id); | |
334 | } | |
335 | return pTask; | |
336 | } | |
337 | ||
338 | int AliHLTTask::SetTarget(AliHLTTask* pTgt) | |
339 | { | |
340 | // see header file for function documentation | |
341 | int iResult=0; | |
342 | if (pTgt) { | |
343 | if (FindTarget(pTgt->GetName())==NULL) { | |
344 | fListTargets.Add(pTgt); | |
345 | } else { | |
346 | iResult=-EEXIST; | |
347 | } | |
348 | } else { | |
349 | iResult=-EINVAL; | |
350 | } | |
351 | return iResult; | |
352 | } | |
353 | ||
354 | int AliHLTTask::UnsetTarget(AliHLTTask* pTarget) | |
355 | { | |
356 | // see header file for function documentation | |
357 | fListTargets.Remove(pTarget); | |
358 | return 0; | |
359 | } | |
360 | ||
361 | int AliHLTTask::StartRun() | |
362 | { | |
363 | // see header file for function documentation | |
364 | int iResult=0; | |
365 | int iNofInputDataBlocks=0; | |
366 | AliHLTComponent* pComponent=GetComponent(); | |
367 | if (pComponent) { | |
368 | // determine the number of input data blocks provided from the source tasks | |
f7561f8d | 369 | { // set scope for lnk as a local variable |
7a436c89 | 370 | TObjLink* lnk=fListDependencies.FirstLink(); |
371 | while (lnk && iResult>=0) { | |
372 | AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject(); | |
373 | if (pSrcTask) { | |
374 | if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) { | |
375 | iNofInputDataBlocks+=iResult; | |
376 | } else if (iResult==0) { | |
377 | HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this); | |
378 | } else { | |
379 | HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask); | |
380 | iResult=-EFAULT; | |
381 | } | |
382 | } | |
383 | lnk=lnk->Next(); | |
384 | } | |
f7561f8d | 385 | } |
7a436c89 | 386 | if (iResult>=0) { |
387 | if (fBlockDataArray.size()>0) { | |
388 | HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this); | |
457ec821 | 389 | fBlockDataArray.clear(); |
7a436c89 | 390 | } |
391 | ||
392 | // component init | |
393 | // the initialization of the component is done by the ComponentHandler after creation | |
394 | // of the component. | |
a3c9b745 | 395 | //iResult=Init( AliHLTAnalysisEnvironment* environ, void* environ_param, int argc, const char** argv ); |
7a436c89 | 396 | |
7a436c89 | 397 | // allocate the data buffer, which controls the output buffer and subscriptions |
398 | if (iResult>=0) { | |
399 | fpDataBuffer=new AliHLTDataBuffer; | |
400 | if (fpDataBuffer!=NULL) { | |
dba03d72 | 401 | fpDataBuffer->SetLocalLoggingLevel(GetLocalLoggingLevel()); |
7a436c89 | 402 | HLTDebug("created data buffer %p for task %s (%p)", fpDataBuffer, GetName(), this); |
403 | TObjLink* lnk=fListTargets.FirstLink(); | |
404 | while (lnk && iResult>=0) { | |
405 | AliHLTTask* pTgtTask=(AliHLTTask*)lnk->GetObject(); | |
406 | if (pTgtTask) { | |
407 | if ((iResult=fpDataBuffer->SetConsumer(pTgtTask->GetComponent()))>=0) { | |
408 | } | |
409 | } else { | |
410 | break; | |
411 | iResult=-EFAULT; | |
412 | } | |
413 | lnk=lnk->Next(); | |
414 | } | |
415 | } else { | |
416 | HLTFatal("can not create data buffer object, memory allocation failed"); | |
417 | iResult=-ENOMEM; | |
418 | } | |
419 | } | |
420 | } | |
457ec821 | 421 | if (iResult>=0) { |
422 | // send the SOR event | |
423 | ||
424 | } | |
7a436c89 | 425 | } else { |
426 | HLTError("task %s (%p) does not have a component", GetName(), this); | |
427 | iResult=-EFAULT; | |
428 | } | |
429 | return iResult; | |
430 | } | |
431 | ||
432 | int AliHLTTask::EndRun() | |
433 | { | |
434 | // see header file for function documentation | |
435 | int iResult=0; | |
436 | if (fBlockDataArray.size()>0) { | |
457ec821 | 437 | fBlockDataArray.clear(); |
7a436c89 | 438 | } |
439 | if (fpDataBuffer) { | |
440 | AliHLTDataBuffer* pBuffer=fpDataBuffer; | |
441 | fpDataBuffer=NULL; | |
442 | delete pBuffer; | |
443 | } | |
444 | return iResult; | |
445 | } | |
446 | ||
48abe484 | 447 | int AliHLTTask::ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType) |
7a436c89 | 448 | { |
449 | // see header file for function documentation | |
450 | int iResult=0; | |
451 | AliHLTComponent* pComponent=GetComponent(); | |
452 | if (pComponent && fpDataBuffer) { | |
453 | HLTDebug("Processing task %s (%p) fpDataBuffer %p", GetName(), this, fpDataBuffer); | |
454 | fpDataBuffer->Reset(); | |
455 | int iSourceDataBlock=0; | |
456 | int iInputDataVolume=0; | |
457 | ||
458 | AliHLTTask* pSrcTask=NULL; | |
b46ca65e | 459 | AliHLTTaskPList subscribedTaskList; |
7a436c89 | 460 | TObjLink* lnk=fListDependencies.FirstLink(); |
461 | ||
457ec821 | 462 | // instances of SOR and EOR events to be kept |
463 | int iSOR=-1; | |
464 | int iEOR=-1; | |
465 | ||
7a436c89 | 466 | // subscribe to all source tasks |
457ec821 | 467 | fBlockDataArray.clear(); |
7a436c89 | 468 | while (lnk && iResult>=0) { |
469 | pSrcTask=(AliHLTTask*)lnk->GetObject(); | |
470 | if (pSrcTask) { | |
471 | int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this); | |
457ec821 | 472 | if (iMatchingDB<0) { |
473 | HLTError("task %s (%p): error getting no of matching data blocks from task %s (%p), error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iMatchingDB); | |
474 | iResult=iMatchingDB; | |
475 | break; | |
476 | } else if (iMatchingDB==0) { | |
477 | HLTDebug("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this); | |
7a436c89 | 478 | } |
457ec821 | 479 | if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) { |
480 | iSOR=iEOR=-1; | |
481 | AliHLTComponentBlockDataList::iterator block=fBlockDataArray.begin(); | |
482 | for (int i=0; block!=fBlockDataArray.end(); i++) { | |
483 | bool bRemove=0; | |
484 | bRemove|=(*block).fDataType==kAliHLTDataTypeSOR && !(iSOR<0 && (iSOR=i)>=0); | |
485 | bRemove|=(*block).fDataType==kAliHLTDataTypeEOR && !(iEOR<0 && (iEOR=i)>=0); | |
486 | //HLTInfo("block %d, iSOR=%d iEOR=%d remove=%d", i, iSOR, iEOR, bRemove); | |
487 | if (i<iSourceDataBlock) { | |
488 | assert(!bRemove); | |
489 | } else if (bRemove) { | |
490 | HLTDebug("remove duplicated event %s (%d)", AliHLTComponent::DataType2Text((*block).fDataType).c_str(), i); | |
491 | pSrcTask->Release(&(*block), this); | |
492 | block=fBlockDataArray.erase(block); | |
493 | continue; | |
494 | } else { | |
495 | iInputDataVolume+=(*block).fSize; | |
7a436c89 | 496 | // put the source task as many times into the list as it provides data blocks |
497 | // makes the bookkeeping for the data release easier | |
b46ca65e | 498 | subscribedTaskList.push_back(pSrcTask); |
457ec821 | 499 | } |
500 | block++; | |
7a436c89 | 501 | } |
502 | HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask); | |
457ec821 | 503 | iSourceDataBlock=fBlockDataArray.size(); |
7a436c89 | 504 | iResult=0; |
505 | } else { | |
506 | HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult); | |
507 | iResult=-EFAULT; | |
508 | } | |
509 | } else { | |
510 | HLTFatal("fatal internal error in ROOT list handling"); | |
511 | iResult=-EFAULT; | |
512 | } | |
513 | lnk=lnk->Next(); | |
457ec821 | 514 | } |
7a436c89 | 515 | |
516 | // process the event | |
517 | int iNofTrial=0; // repeat processing if component returns -ENOSPC | |
518 | AliHLTUInt32_t size=0; | |
519 | if (iResult>=0) { | |
520 | do { | |
032c5e5e | 521 | long unsigned int iOutputDataSize=0; |
522 | AliHLTConfiguration* pConf=GetConf(); | |
032c5e5e | 523 | // check if there was a buffer size specified, query output size |
524 | // estimator from component otherwize | |
525 | if (pConf && pConf->GetOutputBufferSize()>=0) { | |
526 | iOutputDataSize=pConf->GetOutputBufferSize(); | |
527 | } else { | |
7a436c89 | 528 | long unsigned int iConstBase=0; |
529 | double fInputMultiplier=0; | |
53f79557 | 530 | if (pComponent->GetComponentType()!=AliHLTComponent::kSink) { |
7a436c89 | 531 | pComponent->GetOutputDataSize(iConstBase, fInputMultiplier); |
53f79557 | 532 | // add a small margin to the buffer to allow optional component |
533 | // statistics | |
534 | iConstBase+=100; | |
535 | } | |
7a436c89 | 536 | if (fInputMultiplier<0) { |
537 | HLTWarning("ignoring negative input multiplier"); | |
538 | fInputMultiplier=0; | |
539 | } | |
032c5e5e | 540 | iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase; |
7a436c89 | 541 | //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize); |
032c5e5e | 542 | } |
7a436c89 | 543 | if (iNofTrial>0) { |
544 | // dont process again if the buffer size is the same | |
545 | if (size==iOutputDataSize) break; | |
546 | HLTInfo("processing task %s again with buffer size %d", GetName(), iOutputDataSize); | |
547 | } | |
548 | AliHLTUInt8_t* pTgtBuffer=NULL; | |
549 | if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize); | |
550 | //HLTDebug("provided raw buffer %p", pTgtBuffer); | |
551 | AliHLTComponentEventData evtData; | |
552 | AliHLTComponent::FillEventData(evtData); | |
48abe484 | 553 | if (eventNo>=0) |
554 | evtData.fEventID=(AliHLTEventID_t)eventNo; | |
7a436c89 | 555 | AliHLTComponentTriggerData trigData; |
804007a6 | 556 | trigData.fStructSize=sizeof(trigData); |
557 | trigData.fDataSize=0; | |
558 | trigData.fData=NULL; | |
7a436c89 | 559 | size=iOutputDataSize; |
560 | AliHLTUInt32_t outputBlockCnt=0; | |
561 | AliHLTComponentBlockData* outputBlocks=NULL; | |
a0aeb701 | 562 | AliHLTComponentEventDoneData* edd=NULL; |
7a436c89 | 563 | if (pTgtBuffer!=NULL || iOutputDataSize==0) { |
48abe484 | 564 | // add event type data block |
7e81df35 | 565 | // the block is removed immediately after processing from the list |
48abe484 | 566 | AliHLTComponentBlockData eventTypeBlock; |
567 | AliHLTComponent::FillBlockData(eventTypeBlock); | |
568 | // Note: no payload! | |
569 | eventTypeBlock.fDataType=kAliHLTDataTypeEvent; | |
570 | eventTypeBlock.fSpecification=eventType; | |
571 | fBlockDataArray.push_back(eventTypeBlock); | |
572 | ||
573 | // process | |
574 | evtData.fBlockCnt=fBlockDataArray.size(); | |
7a436c89 | 575 | iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd); |
576 | HLTDebug("task %s: component %s ProcessEvent finnished (%d): size=%d blocks=%d", GetName(), pComponent->GetComponentID(), iResult, size, outputBlockCnt); | |
48abe484 | 577 | |
578 | // remove event data block | |
579 | fBlockDataArray.pop_back(); | |
580 | ||
7e81df35 | 581 | // check for forwarded blocks. |
582 | // loop over all output blocks and check | |
583 | // 1. for duplicate blocks (pointing to same location in output buffer | |
584 | // or to the same buffer) | |
585 | // 2. for blocks forwarded from the input. | |
b46ca65e | 586 | if (iResult>=0 && outputBlocks) { |
457ec821 | 587 | if (fListTargets.First()!=NULL) { |
588 | AliHLTComponentBlockDataList segments; | |
589 | for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) { | |
7e81df35 | 590 | // consistency check for data reference |
591 | if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fOffset!=0) { | |
592 | HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: " | |
593 | "for new blocks use offset only, forwarded blocks have fPtr set only", | |
594 | AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(), | |
595 | outputBlocks[oblock].fSpecification, | |
596 | outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset); | |
597 | } | |
598 | ||
599 | // check for duplicates in the output | |
600 | AliHLTUInt32_t checkblock=0; | |
601 | for (; checkblock<oblock; checkblock++) { | |
602 | if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) { | |
603 | if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize || | |
604 | outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) { | |
605 | HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p " | |
606 | "but differ in data type and/or size: %d vs. %d", | |
607 | oblock, | |
608 | AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(), | |
609 | outputBlocks[oblock].fSpecification, | |
610 | checkblock, | |
611 | AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(), | |
612 | outputBlocks[checkblock].fSpecification, | |
613 | outputBlocks[oblock].fPtr, | |
614 | outputBlocks[oblock].fSize, | |
615 | outputBlocks[checkblock].fSize); | |
616 | } | |
617 | // ignore from the second copy | |
618 | break; | |
619 | } | |
620 | } | |
621 | if (checkblock<oblock) continue; | |
622 | ||
623 | // search for the forwarded data blocks | |
624 | // new data blocks are announced to the data buffer, forwarded data blocks | |
625 | // to the publisher task. The publisher task of a forwarded data block is | |
626 | // removed from the list in order to keep the buffer open. It will be releases | |
627 | // when the subscribing task releases it | |
457ec821 | 628 | AliHLTUInt32_t iblock=0; |
48abe484 | 629 | for (; iblock<fBlockDataArray.size(); iblock++) { |
457ec821 | 630 | if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) { |
631 | assert(subscribedTaskList[iblock]!=NULL); | |
632 | if (subscribedTaskList[iblock]==NULL) continue; | |
633 | HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer); | |
634 | fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]); | |
635 | subscribedTaskList[iblock]=NULL; // not to be released in the loop further down | |
636 | break; | |
637 | } | |
638 | } | |
48abe484 | 639 | if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]); |
042b7a5d | 640 | } |
641 | if (pTgtBuffer && segments.size()>0) { | |
642 | iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size()); | |
b46ca65e | 643 | } |
457ec821 | 644 | } else { |
645 | // no forwarding, actually we dont even need to keep the data, this is a | |
646 | // dead end (fListTargets empty) | |
647 | //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt); | |
b46ca65e | 648 | } |
7a436c89 | 649 | delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0; |
650 | } else { | |
651 | fpDataBuffer->Reset(); | |
652 | } | |
457ec821 | 653 | if (fListTargets.First()!=NULL) { |
654 | if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) { | |
655 | HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer); | |
656 | fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]); | |
657 | subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down | |
658 | } | |
659 | if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) { | |
660 | HLTDebug("forward EOR event (%s) segment %d (source task %s %p) to data buffer %p", AliHLTComponent::DataType2Text(fBlockDataArray[iEOR].fDataType).c_str(), iEOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer); | |
661 | fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]); | |
662 | subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down | |
663 | } | |
664 | } | |
7a436c89 | 665 | } else { |
666 | HLTError("task %s: no target buffer available", GetName()); | |
667 | iResult=-EFAULT; | |
668 | } | |
669 | } while (iResult==-ENOSPC && iNofTrial++<1); | |
670 | } | |
671 | ||
672 | // now release all buffers which we have subscribed to | |
673 | iSourceDataBlock=0; | |
b46ca65e | 674 | AliHLTTaskPList::iterator element; |
675 | while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) { | |
676 | pSrcTask=*element; | |
7a436c89 | 677 | if (pSrcTask) { |
678 | int iTempRes=0; | |
679 | if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) { | |
680 | HLTDebug("Task %s (%p) successfully released segment of task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask); | |
681 | } else { | |
682 | HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes); | |
683 | } | |
7a436c89 | 684 | } |
b46ca65e | 685 | subscribedTaskList.erase(element); |
7a436c89 | 686 | iSourceDataBlock++; |
687 | } | |
b46ca65e | 688 | if (subscribedTaskList.size()>0) { |
7a436c89 | 689 | HLTError("task %s (%p): could not release all data buffers", GetName(), this); |
690 | } | |
691 | } else { | |
692 | HLTError("task %s (%p): internal failure (not initialized component %p, data buffer %p)", GetName(), this, fpComponent, fpDataBuffer); | |
693 | iResult=-EFAULT; | |
694 | } | |
695 | return iResult; | |
696 | } | |
697 | ||
698 | int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const | |
699 | { | |
700 | // see header file for function documentation | |
701 | int iResult=0; | |
702 | if (pConsumerTask) { | |
703 | if (fpDataBuffer) { | |
704 | iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL); | |
705 | } else { | |
706 | HLTFatal("internal data buffer missing"); | |
707 | iResult=-EFAULT; | |
708 | } | |
709 | } else { | |
710 | iResult=-EINVAL; | |
711 | } | |
712 | return iResult; | |
713 | } | |
714 | ||
715 | int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const | |
716 | { | |
717 | // see header file for function documentation | |
718 | int iResult=0; | |
719 | if (pConsumerTask) { | |
720 | AliHLTComponent* pComponent=GetComponent(); | |
721 | if (!pComponent) { | |
722 | // init ? | |
723 | HLTError("component not initialized"); | |
724 | iResult=-EFAULT; | |
725 | } | |
726 | if (pComponent) { | |
727 | iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL); | |
728 | } else { | |
729 | HLTFatal("task initialization failed"); | |
730 | iResult=-EFAULT; | |
731 | } | |
732 | } else { | |
733 | iResult=-EINVAL; | |
734 | } | |
735 | return iResult; | |
736 | } | |
737 | ||
457ec821 | 738 | int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList) |
7a436c89 | 739 | { |
740 | // see header file for function documentation | |
741 | int iResult=0; | |
742 | if (pConsumerTask) { | |
743 | if (fpDataBuffer) { | |
457ec821 | 744 | iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList); |
7a436c89 | 745 | } else { |
746 | HLTFatal("internal data buffer missing"); | |
747 | iResult=-EFAULT; | |
748 | } | |
749 | } else { | |
750 | iResult=-EINVAL; | |
751 | } | |
752 | return iResult; | |
753 | } | |
754 | ||
755 | int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask) | |
756 | { | |
757 | // see header file for function documentation | |
758 | int iResult=0; | |
759 | if (pConsumerTask && pBlockDesc) { | |
760 | if (fpDataBuffer) { | |
b46ca65e | 761 | iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this); |
7a436c89 | 762 | } else { |
763 | HLTFatal("internal data buffer missing"); | |
764 | iResult=-EFAULT; | |
765 | } | |
766 | } else { | |
767 | iResult=-EINVAL; | |
768 | } | |
769 | return iResult; | |
770 | } | |
771 | ||
772 | void AliHLTTask::PrintStatus() | |
773 | { | |
774 | // see header file for function documentation | |
775 | HLTLogKeyword("task properties"); | |
776 | AliHLTComponent* pComponent=GetComponent(); | |
777 | if (pComponent) { | |
778 | HLTMessage(" component: %s (%p)", pComponent->GetComponentID(), pComponent); | |
779 | } else { | |
780 | HLTMessage(" no component set!"); | |
781 | } | |
782 | if (fpConfiguration) { | |
783 | AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource(); | |
784 | while (pSrc) { | |
785 | const char* pQualifier="unresolved"; | |
786 | if (FindDependency(pSrc->GetName())) | |
787 | pQualifier="resolved"; | |
788 | HLTMessage(" source: %s (%s)", pSrc->GetName(), pQualifier); | |
789 | pSrc=fpConfiguration->GetNextSource(); | |
790 | } | |
791 | TObjLink* lnk = fListTargets.FirstLink(); | |
792 | while (lnk) { | |
793 | TObject *obj = lnk->GetObject(); | |
794 | HLTMessage(" target: %s", obj->GetName()); | |
795 | lnk = lnk->Next(); | |
796 | } | |
797 | } else { | |
798 | HLTMessage(" task \"%s\" not initialized", GetName()); | |
799 | } | |
800 | } | |
7131ea63 | 801 | |
802 | int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/) | |
803 | { | |
804 | // default implementation nothing to do | |
805 | return 0; | |
806 | } | |
807 | ||
808 | int AliHLTTask::CustomCleanup() | |
809 | { | |
810 | // default implementation nothing to do | |
811 | return 0; | |
812 | } |