]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTTask.cxx
initializing the trigger data structure correctly before component data processing
[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;
a0dec225 566 AliHLTEventTriggerData evtTrigData;
804007a6 567 trigData.fStructSize=sizeof(trigData);
a0dec225 568 trigData.fDataSize=sizeof(AliHLTEventTriggerData);
569 memset(&evtTrigData, 0, trigData.fDataSize);
570 evtTrigData.fCommonHeaderWordCnt=gkAliHLTCommonHeaderCount;
571 trigData.fData=&evtTrigData;
3ee8781a 572 iLastOutputDataSize=iOutputDataSize;
573 AliHLTUInt32_t size=iOutputDataSize;
7a436c89 574 AliHLTUInt32_t outputBlockCnt=0;
575 AliHLTComponentBlockData* outputBlocks=NULL;
a0aeb701 576 AliHLTComponentEventDoneData* edd=NULL;
7a436c89 577 if (pTgtBuffer!=NULL || iOutputDataSize==0) {
48abe484 578 // add event type data block
7e81df35 579 // the block is removed immediately after processing from the list
48abe484 580 AliHLTComponentBlockData eventTypeBlock;
581 AliHLTComponent::FillBlockData(eventTypeBlock);
582 // Note: no payload!
583 eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
584 eventTypeBlock.fSpecification=eventType;
585 fBlockDataArray.push_back(eventTypeBlock);
586
587 // process
588 evtData.fBlockCnt=fBlockDataArray.size();
7a436c89 589 iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
97d2b87a 590 HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt);
48abe484 591
324ca3b4 592 // EventDoneData is for the moment ignored in AliHLTSystem
593 if (edd) {
594 HLTDebug("got EventDoneData size %d", edd->fDataSize);
595 delete [] reinterpret_cast<char*>(edd);
596 edd=NULL;
597 }
598
48abe484 599 // remove event data block
600 fBlockDataArray.pop_back();
601
7e81df35 602 // check for forwarded blocks.
603 // loop over all output blocks and check
604 // 1. for duplicate blocks (pointing to same location in output buffer
605 // or to the same buffer)
606 // 2. for blocks forwarded from the input.
b46ca65e 607 if (iResult>=0 && outputBlocks) {
457ec821 608 if (fListTargets.First()!=NULL) {
609 AliHLTComponentBlockDataList segments;
610 for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
7e81df35 611 // consistency check for data reference
0ad4ebd1 612 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
613 outputBlocks[oblock].fOffset!=0) {
7e81df35 614 HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: "
615 "for new blocks use offset only, forwarded blocks have fPtr set only",
616 AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
617 outputBlocks[oblock].fSpecification,
618 outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset);
619 }
620
621 // check for duplicates in the output
622 AliHLTUInt32_t checkblock=0;
623 for (; checkblock<oblock; checkblock++) {
0ad4ebd1 624 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
625 outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) {
7e81df35 626 if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize ||
627 outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) {
628 HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p "
629 "but differ in data type and/or size: %d vs. %d",
630 oblock,
631 AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
632 outputBlocks[oblock].fSpecification,
633 checkblock,
634 AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(),
635 outputBlocks[checkblock].fSpecification,
636 outputBlocks[oblock].fPtr,
637 outputBlocks[oblock].fSize,
638 outputBlocks[checkblock].fSize);
639 }
640 // ignore from the second copy
641 break;
642 }
643 }
644 if (checkblock<oblock) continue;
645
646 // search for the forwarded data blocks
647 // new data blocks are announced to the data buffer, forwarded data blocks
648 // to the publisher task. The publisher task of a forwarded data block is
649 // removed from the list in order to keep the buffer open. It will be releases
650 // when the subscribing task releases it
457ec821 651 AliHLTUInt32_t iblock=0;
48abe484 652 for (; iblock<fBlockDataArray.size(); iblock++) {
0ad4ebd1 653 if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) {
654 // the event type data block is ignored if it was forwarded
0925276e 655 break;
0ad4ebd1 656 }
457ec821 657 if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
658 assert(subscribedTaskList[iblock]!=NULL);
659 if (subscribedTaskList[iblock]==NULL) continue;
660 HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
661 fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
662 subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
663 break;
664 }
665 }
48abe484 666 if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
042b7a5d 667 }
668 if (pTgtBuffer && segments.size()>0) {
669 iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
b46ca65e 670 }
457ec821 671 } else {
672 // no forwarding, actually we dont even need to keep the data, this is a
673 // dead end (fListTargets empty)
674 //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
b46ca65e 675 }
7a436c89 676 delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
677 } else {
678 fpDataBuffer->Reset();
679 }
457ec821 680 if (fListTargets.First()!=NULL) {
681 if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
682 HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
683 fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
684 subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
685 }
686 if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
687 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);
688 fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
689 subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
690 }
691 }
7a436c89 692 } else {
97d2b87a 693 HLTError("no target buffer available");
7a436c89 694 iResult=-EFAULT;
695 }
696 } while (iResult==-ENOSPC && iNofTrial++<1);
697 }
698
699 // now release all buffers which we have subscribed to
700 iSourceDataBlock=0;
b46ca65e 701 AliHLTTaskPList::iterator element;
702 while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
703 pSrcTask=*element;
7a436c89 704 if (pSrcTask) {
705 int iTempRes=0;
706 if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
97d2b87a 707 HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
7a436c89 708 } else {
97d2b87a 709 HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes);
7a436c89 710 }
7a436c89 711 }
b46ca65e 712 subscribedTaskList.erase(element);
7a436c89 713 iSourceDataBlock++;
714 }
b46ca65e 715 if (subscribedTaskList.size()>0) {
97d2b87a 716 HLTError("could not release all data buffers");
7a436c89 717 }
718 } else {
97d2b87a 719 HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer);
7a436c89 720 iResult=-EFAULT;
721 }
722 return iResult;
723}
724
725int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
726{
727 // see header file for function documentation
728 int iResult=0;
729 if (pConsumerTask) {
730 if (fpDataBuffer) {
731 iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
732 } else {
733 HLTFatal("internal data buffer missing");
734 iResult=-EFAULT;
735 }
736 } else {
737 iResult=-EINVAL;
738 }
739 return iResult;
740}
741
742int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
743{
744 // see header file for function documentation
745 int iResult=0;
746 if (pConsumerTask) {
747 AliHLTComponent* pComponent=GetComponent();
748 if (!pComponent) {
749 // init ?
750 HLTError("component not initialized");
751 iResult=-EFAULT;
752 }
753 if (pComponent) {
754 iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
755 } else {
756 HLTFatal("task initialization failed");
757 iResult=-EFAULT;
758 }
759 } else {
760 iResult=-EINVAL;
761 }
762 return iResult;
763}
764
457ec821 765int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
7a436c89 766{
767 // see header file for function documentation
768 int iResult=0;
769 if (pConsumerTask) {
770 if (fpDataBuffer) {
457ec821 771 iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
7a436c89 772 } else {
773 HLTFatal("internal data buffer missing");
774 iResult=-EFAULT;
775 }
776 } else {
777 iResult=-EINVAL;
778 }
779 return iResult;
780}
781
782int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
783{
784 // see header file for function documentation
785 int iResult=0;
786 if (pConsumerTask && pBlockDesc) {
787 if (fpDataBuffer) {
b46ca65e 788 iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
7a436c89 789 } else {
790 HLTFatal("internal data buffer missing");
791 iResult=-EFAULT;
792 }
793 } else {
794 iResult=-EINVAL;
795 }
796 return iResult;
797}
798
799void AliHLTTask::PrintStatus()
800{
801 // see header file for function documentation
802 HLTLogKeyword("task properties");
803 AliHLTComponent* pComponent=GetComponent();
804 if (pComponent) {
805 HLTMessage(" component: %s (%p)", pComponent->GetComponentID(), pComponent);
806 } else {
807 HLTMessage(" no component set!");
808 }
809 if (fpConfiguration) {
810 AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
811 while (pSrc) {
812 const char* pQualifier="unresolved";
813 if (FindDependency(pSrc->GetName()))
814 pQualifier="resolved";
815 HLTMessage(" source: %s (%s)", pSrc->GetName(), pQualifier);
816 pSrc=fpConfiguration->GetNextSource();
817 }
818 TObjLink* lnk = fListTargets.FirstLink();
819 while (lnk) {
820 TObject *obj = lnk->GetObject();
821 HLTMessage(" target: %s", obj->GetName());
822 lnk = lnk->Next();
823 }
824 } else {
97d2b87a 825 HLTMessage(" task not initialized");
7a436c89 826 }
827}
7131ea63 828
829int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
830{
831 // default implementation nothing to do
832 return 0;
833}
834
835int AliHLTTask::CustomCleanup()
836{
837 // default implementation nothing to do
838 return 0;
839}
97d2b87a 840
841int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity,
842 const char* originClass, const char* originFunc,
843 const char* file, int line, ... ) const
844{
845 // see header file for function documentation
846 int iResult=0;
847
848 va_list args;
849 va_start(args, line);
850
851 AliHLTLogging::SetLogString("%s (%p): ", GetName(), this);
852 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
853 va_end(args);
854
855 return iResult;
856}