]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTTask.cxx
- moving AliHLTGlobalBarrelTrack to libAliHLTUtil to make it commonly
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTTask.cxx
CommitLineData
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
32using 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 */
46ClassImp(AliHLTTask)
47
48AliHLTTask::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
64AliHLTTask::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
76AliHLTTask::~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
98int 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) {
97d2b87a 103 HLTWarning("overriding existing reference to configuration object %p by %p",
104 fpConfiguration, pConf);
7a436c89 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
114int 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
155int 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 {
97d2b87a 167 HLTWarning("task doesn't seem to be in initialized");
7a436c89 168 }
169 return iResult;
170}
171
172const 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
180AliHLTConfiguration* AliHLTTask::GetConf() const
181{
182 // see header file for function documentation
183 return fpConfiguration;
184}
185
186AliHLTComponent* AliHLTTask::GetComponent() const
187{
188 // see header file for function documentation
189 return fpComponent;
190}
191
192AliHLTTask* 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
202int 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
232void 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) {
97d2b87a 246 HLTMessage(" dependency level %d ", iResult);
7a436c89 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
265int 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
281int 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
291int 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
307int 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
328AliHLTTask* 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
338int 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
354int AliHLTTask::UnsetTarget(AliHLTTask* pTarget)
355{
356 // see header file for function documentation
357 fListTargets.Remove(pTarget);
358 return 0;
359}
360
361int 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
432int 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 447int 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
3ee8781a 518 AliHLTUInt32_t iLastOutputDataSize=0;
7a436c89 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;
ae962989 535#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
536 for (AliHLTComponentBlockDataList::iterator element=fBlockDataArray.begin();
537 element!=fBlockDataArray.end(); element++) {
538 if (element->fDataType==kAliHLTDataTypeComponentStatistics) {
539 iConstBase+=element->fSize;
540 }
541 }
542#endif
53f79557 543 }
7a436c89 544 if (fInputMultiplier<0) {
545 HLTWarning("ignoring negative input multiplier");
546 fInputMultiplier=0;
547 }
032c5e5e 548 iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
7a436c89 549 //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
032c5e5e 550 }
7a436c89 551 if (iNofTrial>0) {
552 // dont process again if the buffer size is the same
3ee8781a 553 if (iLastOutputDataSize==iOutputDataSize) break;
97d2b87a 554 HLTImportant("processing event %d again with buffer size %d", eventNo, iOutputDataSize);
7a436c89 555 }
556 AliHLTUInt8_t* pTgtBuffer=NULL;
557 if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
558 //HLTDebug("provided raw buffer %p", pTgtBuffer);
559 AliHLTComponentEventData evtData;
560 AliHLTComponent::FillEventData(evtData);
48abe484 561 if (eventNo>=0)
562 evtData.fEventID=(AliHLTEventID_t)eventNo;
7a436c89 563 AliHLTComponentTriggerData trigData;
804007a6 564 trigData.fStructSize=sizeof(trigData);
565 trigData.fDataSize=0;
566 trigData.fData=NULL;
3ee8781a 567 iLastOutputDataSize=iOutputDataSize;
568 AliHLTUInt32_t size=iOutputDataSize;
7a436c89 569 AliHLTUInt32_t outputBlockCnt=0;
570 AliHLTComponentBlockData* outputBlocks=NULL;
a0aeb701 571 AliHLTComponentEventDoneData* edd=NULL;
7a436c89 572 if (pTgtBuffer!=NULL || iOutputDataSize==0) {
48abe484 573 // add event type data block
7e81df35 574 // the block is removed immediately after processing from the list
48abe484 575 AliHLTComponentBlockData eventTypeBlock;
576 AliHLTComponent::FillBlockData(eventTypeBlock);
577 // Note: no payload!
578 eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
579 eventTypeBlock.fSpecification=eventType;
580 fBlockDataArray.push_back(eventTypeBlock);
581
582 // process
583 evtData.fBlockCnt=fBlockDataArray.size();
7a436c89 584 iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
97d2b87a 585 HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt);
48abe484 586
587 // remove event data block
588 fBlockDataArray.pop_back();
589
7e81df35 590 // check for forwarded blocks.
591 // loop over all output blocks and check
592 // 1. for duplicate blocks (pointing to same location in output buffer
593 // or to the same buffer)
594 // 2. for blocks forwarded from the input.
b46ca65e 595 if (iResult>=0 && outputBlocks) {
457ec821 596 if (fListTargets.First()!=NULL) {
597 AliHLTComponentBlockDataList segments;
598 for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
7e81df35 599 // consistency check for data reference
0ad4ebd1 600 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
601 outputBlocks[oblock].fOffset!=0) {
7e81df35 602 HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: "
603 "for new blocks use offset only, forwarded blocks have fPtr set only",
604 AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
605 outputBlocks[oblock].fSpecification,
606 outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset);
607 }
608
609 // check for duplicates in the output
610 AliHLTUInt32_t checkblock=0;
611 for (; checkblock<oblock; checkblock++) {
0ad4ebd1 612 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
613 outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) {
7e81df35 614 if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize ||
615 outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) {
616 HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p "
617 "but differ in data type and/or size: %d vs. %d",
618 oblock,
619 AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
620 outputBlocks[oblock].fSpecification,
621 checkblock,
622 AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(),
623 outputBlocks[checkblock].fSpecification,
624 outputBlocks[oblock].fPtr,
625 outputBlocks[oblock].fSize,
626 outputBlocks[checkblock].fSize);
627 }
628 // ignore from the second copy
629 break;
630 }
631 }
632 if (checkblock<oblock) continue;
633
634 // search for the forwarded data blocks
635 // new data blocks are announced to the data buffer, forwarded data blocks
636 // to the publisher task. The publisher task of a forwarded data block is
637 // removed from the list in order to keep the buffer open. It will be releases
638 // when the subscribing task releases it
457ec821 639 AliHLTUInt32_t iblock=0;
48abe484 640 for (; iblock<fBlockDataArray.size(); iblock++) {
0ad4ebd1 641 if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) {
642 // the event type data block is ignored if it was forwarded
0925276e 643 break;
0ad4ebd1 644 }
457ec821 645 if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
646 assert(subscribedTaskList[iblock]!=NULL);
647 if (subscribedTaskList[iblock]==NULL) continue;
648 HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
649 fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
650 subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
651 break;
652 }
653 }
48abe484 654 if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
042b7a5d 655 }
656 if (pTgtBuffer && segments.size()>0) {
657 iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
b46ca65e 658 }
457ec821 659 } else {
660 // no forwarding, actually we dont even need to keep the data, this is a
661 // dead end (fListTargets empty)
662 //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
b46ca65e 663 }
7a436c89 664 delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
665 } else {
666 fpDataBuffer->Reset();
667 }
457ec821 668 if (fListTargets.First()!=NULL) {
669 if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
670 HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
671 fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
672 subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
673 }
674 if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
675 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);
676 fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
677 subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
678 }
679 }
7a436c89 680 } else {
97d2b87a 681 HLTError("no target buffer available");
7a436c89 682 iResult=-EFAULT;
683 }
684 } while (iResult==-ENOSPC && iNofTrial++<1);
685 }
686
687 // now release all buffers which we have subscribed to
688 iSourceDataBlock=0;
b46ca65e 689 AliHLTTaskPList::iterator element;
690 while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
691 pSrcTask=*element;
7a436c89 692 if (pSrcTask) {
693 int iTempRes=0;
694 if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
97d2b87a 695 HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
7a436c89 696 } else {
97d2b87a 697 HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes);
7a436c89 698 }
7a436c89 699 }
b46ca65e 700 subscribedTaskList.erase(element);
7a436c89 701 iSourceDataBlock++;
702 }
b46ca65e 703 if (subscribedTaskList.size()>0) {
97d2b87a 704 HLTError("could not release all data buffers");
7a436c89 705 }
706 } else {
97d2b87a 707 HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer);
7a436c89 708 iResult=-EFAULT;
709 }
710 return iResult;
711}
712
713int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
714{
715 // see header file for function documentation
716 int iResult=0;
717 if (pConsumerTask) {
718 if (fpDataBuffer) {
719 iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
720 } else {
721 HLTFatal("internal data buffer missing");
722 iResult=-EFAULT;
723 }
724 } else {
725 iResult=-EINVAL;
726 }
727 return iResult;
728}
729
730int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
731{
732 // see header file for function documentation
733 int iResult=0;
734 if (pConsumerTask) {
735 AliHLTComponent* pComponent=GetComponent();
736 if (!pComponent) {
737 // init ?
738 HLTError("component not initialized");
739 iResult=-EFAULT;
740 }
741 if (pComponent) {
742 iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
743 } else {
744 HLTFatal("task initialization failed");
745 iResult=-EFAULT;
746 }
747 } else {
748 iResult=-EINVAL;
749 }
750 return iResult;
751}
752
457ec821 753int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
7a436c89 754{
755 // see header file for function documentation
756 int iResult=0;
757 if (pConsumerTask) {
758 if (fpDataBuffer) {
457ec821 759 iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
7a436c89 760 } else {
761 HLTFatal("internal data buffer missing");
762 iResult=-EFAULT;
763 }
764 } else {
765 iResult=-EINVAL;
766 }
767 return iResult;
768}
769
770int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
771{
772 // see header file for function documentation
773 int iResult=0;
774 if (pConsumerTask && pBlockDesc) {
775 if (fpDataBuffer) {
b46ca65e 776 iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
7a436c89 777 } else {
778 HLTFatal("internal data buffer missing");
779 iResult=-EFAULT;
780 }
781 } else {
782 iResult=-EINVAL;
783 }
784 return iResult;
785}
786
787void AliHLTTask::PrintStatus()
788{
789 // see header file for function documentation
790 HLTLogKeyword("task properties");
791 AliHLTComponent* pComponent=GetComponent();
792 if (pComponent) {
793 HLTMessage(" component: %s (%p)", pComponent->GetComponentID(), pComponent);
794 } else {
795 HLTMessage(" no component set!");
796 }
797 if (fpConfiguration) {
798 AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
799 while (pSrc) {
800 const char* pQualifier="unresolved";
801 if (FindDependency(pSrc->GetName()))
802 pQualifier="resolved";
803 HLTMessage(" source: %s (%s)", pSrc->GetName(), pQualifier);
804 pSrc=fpConfiguration->GetNextSource();
805 }
806 TObjLink* lnk = fListTargets.FirstLink();
807 while (lnk) {
808 TObject *obj = lnk->GetObject();
809 HLTMessage(" target: %s", obj->GetName());
810 lnk = lnk->Next();
811 }
812 } else {
97d2b87a 813 HLTMessage(" task not initialized");
7a436c89 814 }
815}
7131ea63 816
817int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
818{
819 // default implementation nothing to do
820 return 0;
821}
822
823int AliHLTTask::CustomCleanup()
824{
825 // default implementation nothing to do
826 return 0;
827}
97d2b87a 828
829int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity,
830 const char* originClass, const char* originFunc,
831 const char* file, int line, ... ) const
832{
833 // see header file for function documentation
834 int iResult=0;
835
836 va_list args;
837 va_start(args, line);
838
839 AliHLTLogging::SetLogString("%s (%p): ", GetName(), this);
840 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
841 va_end(args);
842
843 return iResult;
844}