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