]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTTask.cxx
adding common functionality for the magnetic field to the component interface
[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
c4ffab2c 448int AliHLTTask::ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType, AliHLTUInt64_t trgMask)
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;
3baf1595 466 // TODO 2009-09-30
467 // generalize handling of the special blocks to be forwarded on SOR and EOR
468 // just adding a new specific handling for the ECS parameter block as a quick
469 // solution
470 int iECS=-1;
457ec821 471
7a436c89 472 // subscribe to all source tasks
457ec821 473 fBlockDataArray.clear();
7a436c89 474 while (lnk && iResult>=0) {
475 pSrcTask=(AliHLTTask*)lnk->GetObject();
476 if (pSrcTask) {
477 int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
457ec821 478 if (iMatchingDB<0) {
479 HLTError("task %s (%p): error getting no of matching data blocks from task %s (%p), error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iMatchingDB);
480 iResult=iMatchingDB;
481 break;
482 } else if (iMatchingDB==0) {
483 HLTDebug("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
7a436c89 484 }
457ec821 485 if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) {
3baf1595 486 iSOR=iEOR=iECS=-1;
457ec821 487 AliHLTComponentBlockDataList::iterator block=fBlockDataArray.begin();
488 for (int i=0; block!=fBlockDataArray.end(); i++) {
489 bool bRemove=0;
490 bRemove|=(*block).fDataType==kAliHLTDataTypeSOR && !(iSOR<0 && (iSOR=i)>=0);
491 bRemove|=(*block).fDataType==kAliHLTDataTypeEOR && !(iEOR<0 && (iEOR=i)>=0);
3baf1595 492 bRemove|=(*block).fDataType==kAliHLTDataTypeECSParam && !(iECS<0 && (iECS=i)>=0);
457ec821 493 //HLTInfo("block %d, iSOR=%d iEOR=%d remove=%d", i, iSOR, iEOR, bRemove);
494 if (i<iSourceDataBlock) {
495 assert(!bRemove);
496 } else if (bRemove) {
497 HLTDebug("remove duplicated event %s (%d)", AliHLTComponent::DataType2Text((*block).fDataType).c_str(), i);
498 pSrcTask->Release(&(*block), this);
499 block=fBlockDataArray.erase(block);
500 continue;
501 } else {
502 iInputDataVolume+=(*block).fSize;
7a436c89 503 // put the source task as many times into the list as it provides data blocks
504 // makes the bookkeeping for the data release easier
b46ca65e 505 subscribedTaskList.push_back(pSrcTask);
457ec821 506 }
507 block++;
7a436c89 508 }
509 HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
457ec821 510 iSourceDataBlock=fBlockDataArray.size();
7a436c89 511 iResult=0;
512 } else {
513 HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
514 iResult=-EFAULT;
515 }
516 } else {
517 HLTFatal("fatal internal error in ROOT list handling");
518 iResult=-EFAULT;
519 }
520 lnk=lnk->Next();
457ec821 521 }
7a436c89 522
523 // process the event
524 int iNofTrial=0; // repeat processing if component returns -ENOSPC
3ee8781a 525 AliHLTUInt32_t iLastOutputDataSize=0;
7a436c89 526 if (iResult>=0) {
527 do {
032c5e5e 528 long unsigned int iOutputDataSize=0;
529 AliHLTConfiguration* pConf=GetConf();
032c5e5e 530 // check if there was a buffer size specified, query output size
531 // estimator from component otherwize
532 if (pConf && pConf->GetOutputBufferSize()>=0) {
533 iOutputDataSize=pConf->GetOutputBufferSize();
534 } else {
7a436c89 535 long unsigned int iConstBase=0;
536 double fInputMultiplier=0;
53f79557 537 if (pComponent->GetComponentType()!=AliHLTComponent::kSink) {
7a436c89 538 pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
53f79557 539 // add a small margin to the buffer to allow optional component
540 // statistics
541 iConstBase+=100;
ae962989 542#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
543 for (AliHLTComponentBlockDataList::iterator element=fBlockDataArray.begin();
544 element!=fBlockDataArray.end(); element++) {
545 if (element->fDataType==kAliHLTDataTypeComponentStatistics) {
546 iConstBase+=element->fSize;
547 }
548 }
549#endif
53f79557 550 }
7a436c89 551 if (fInputMultiplier<0) {
552 HLTWarning("ignoring negative input multiplier");
553 fInputMultiplier=0;
554 }
032c5e5e 555 iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
7a436c89 556 //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
032c5e5e 557 }
7a436c89 558 if (iNofTrial>0) {
559 // dont process again if the buffer size is the same
3ee8781a 560 if (iLastOutputDataSize==iOutputDataSize) break;
97d2b87a 561 HLTImportant("processing event %d again with buffer size %d", eventNo, iOutputDataSize);
7a436c89 562 }
563 AliHLTUInt8_t* pTgtBuffer=NULL;
564 if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
565 //HLTDebug("provided raw buffer %p", pTgtBuffer);
566 AliHLTComponentEventData evtData;
567 AliHLTComponent::FillEventData(evtData);
48abe484 568 if (eventNo>=0)
569 evtData.fEventID=(AliHLTEventID_t)eventNo;
dd5b6088 570 evtData.fEventCreation_s=static_cast<AliHLTUInt32_t>(time(NULL));
7a436c89 571 AliHLTComponentTriggerData trigData;
a0dec225 572 AliHLTEventTriggerData evtTrigData;
804007a6 573 trigData.fStructSize=sizeof(trigData);
a0dec225 574 trigData.fDataSize=sizeof(AliHLTEventTriggerData);
575 memset(&evtTrigData, 0, trigData.fDataSize);
576 evtTrigData.fCommonHeaderWordCnt=gkAliHLTCommonHeaderCount;
c4ffab2c 577 evtTrigData.fCommonHeader[5]=trgMask&0xffffffff;
578 trgMask>>=32;
579 evtTrigData.fCommonHeader[6]=trgMask&0xfffffff;
a0dec225 580 trigData.fData=&evtTrigData;
3ee8781a 581 iLastOutputDataSize=iOutputDataSize;
582 AliHLTUInt32_t size=iOutputDataSize;
7a436c89 583 AliHLTUInt32_t outputBlockCnt=0;
584 AliHLTComponentBlockData* outputBlocks=NULL;
a0aeb701 585 AliHLTComponentEventDoneData* edd=NULL;
7a436c89 586 if (pTgtBuffer!=NULL || iOutputDataSize==0) {
48abe484 587 // add event type data block
7e81df35 588 // the block is removed immediately after processing from the list
48abe484 589 AliHLTComponentBlockData eventTypeBlock;
590 AliHLTComponent::FillBlockData(eventTypeBlock);
591 // Note: no payload!
592 eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
593 eventTypeBlock.fSpecification=eventType;
594 fBlockDataArray.push_back(eventTypeBlock);
595
596 // process
597 evtData.fBlockCnt=fBlockDataArray.size();
7a436c89 598 iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
97d2b87a 599 HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt);
48abe484 600
324ca3b4 601 // EventDoneData is for the moment ignored in AliHLTSystem
602 if (edd) {
603 HLTDebug("got EventDoneData size %d", edd->fDataSize);
604 delete [] reinterpret_cast<char*>(edd);
605 edd=NULL;
606 }
607
48abe484 608 // remove event data block
609 fBlockDataArray.pop_back();
610
7e81df35 611 // check for forwarded blocks.
612 // loop over all output blocks and check
613 // 1. for duplicate blocks (pointing to same location in output buffer
614 // or to the same buffer)
615 // 2. for blocks forwarded from the input.
b46ca65e 616 if (iResult>=0 && outputBlocks) {
457ec821 617 if (fListTargets.First()!=NULL) {
618 AliHLTComponentBlockDataList segments;
619 for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
7e81df35 620 // consistency check for data reference
0ad4ebd1 621 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
622 outputBlocks[oblock].fOffset!=0) {
7e81df35 623 HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: "
624 "for new blocks use offset only, forwarded blocks have fPtr set only",
625 AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
626 outputBlocks[oblock].fSpecification,
627 outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset);
628 }
629
630 // check for duplicates in the output
631 AliHLTUInt32_t checkblock=0;
632 for (; checkblock<oblock; checkblock++) {
0ad4ebd1 633 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
634 outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) {
7e81df35 635 if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize ||
636 outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) {
637 HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p "
638 "but differ in data type and/or size: %d vs. %d",
639 oblock,
640 AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
641 outputBlocks[oblock].fSpecification,
642 checkblock,
643 AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(),
644 outputBlocks[checkblock].fSpecification,
645 outputBlocks[oblock].fPtr,
646 outputBlocks[oblock].fSize,
647 outputBlocks[checkblock].fSize);
648 }
649 // ignore from the second copy
650 break;
651 }
652 }
653 if (checkblock<oblock) continue;
654
655 // search for the forwarded data blocks
656 // new data blocks are announced to the data buffer, forwarded data blocks
657 // to the publisher task. The publisher task of a forwarded data block is
658 // removed from the list in order to keep the buffer open. It will be releases
659 // when the subscribing task releases it
457ec821 660 AliHLTUInt32_t iblock=0;
48abe484 661 for (; iblock<fBlockDataArray.size(); iblock++) {
0ad4ebd1 662 if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) {
663 // the event type data block is ignored if it was forwarded
0925276e 664 break;
0ad4ebd1 665 }
457ec821 666 if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
667 assert(subscribedTaskList[iblock]!=NULL);
668 if (subscribedTaskList[iblock]==NULL) continue;
669 HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
670 fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
671 subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
672 break;
673 }
674 }
48abe484 675 if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
042b7a5d 676 }
677 if (pTgtBuffer && segments.size()>0) {
678 iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
b46ca65e 679 }
457ec821 680 } else {
681 // no forwarding, actually we dont even need to keep the data, this is a
682 // dead end (fListTargets empty)
683 //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
b46ca65e 684 }
7a436c89 685 delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
686 } else {
687 fpDataBuffer->Reset();
688 }
457ec821 689 if (fListTargets.First()!=NULL) {
690 if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
691 HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
692 fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
693 subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
694 }
695 if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
696 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);
697 fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
698 subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
699 }
3baf1595 700 if (iECS>=0 && subscribedTaskList[iECS]!=NULL) {
701 HLTDebug("forward EOR event (%s) segment %d (source task %s %p) to data buffer %p", AliHLTComponent::DataType2Text(fBlockDataArray[iECS].fDataType).c_str(), iECS, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
702 fpDataBuffer->Forward(subscribedTaskList[iECS], &fBlockDataArray[iECS]);
703 subscribedTaskList[iECS]=NULL; // not to be released in the loop further down
704 }
457ec821 705 }
7a436c89 706 } else {
97d2b87a 707 HLTError("no target buffer available");
7a436c89 708 iResult=-EFAULT;
709 }
710 } while (iResult==-ENOSPC && iNofTrial++<1);
711 }
712
713 // now release all buffers which we have subscribed to
714 iSourceDataBlock=0;
b46ca65e 715 AliHLTTaskPList::iterator element;
716 while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
717 pSrcTask=*element;
7a436c89 718 if (pSrcTask) {
719 int iTempRes=0;
720 if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
97d2b87a 721 HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
7a436c89 722 } else {
97d2b87a 723 HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes);
7a436c89 724 }
7a436c89 725 }
b46ca65e 726 subscribedTaskList.erase(element);
7a436c89 727 iSourceDataBlock++;
728 }
b46ca65e 729 if (subscribedTaskList.size()>0) {
97d2b87a 730 HLTError("could not release all data buffers");
7a436c89 731 }
732 } else {
97d2b87a 733 HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer);
7a436c89 734 iResult=-EFAULT;
735 }
736 return iResult;
737}
738
739int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
740{
741 // see header file for function documentation
742 int iResult=0;
743 if (pConsumerTask) {
744 if (fpDataBuffer) {
745 iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
746 } else {
747 HLTFatal("internal data buffer missing");
748 iResult=-EFAULT;
749 }
750 } else {
751 iResult=-EINVAL;
752 }
753 return iResult;
754}
755
756int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
757{
758 // see header file for function documentation
759 int iResult=0;
760 if (pConsumerTask) {
761 AliHLTComponent* pComponent=GetComponent();
762 if (!pComponent) {
763 // init ?
764 HLTError("component not initialized");
765 iResult=-EFAULT;
766 }
767 if (pComponent) {
768 iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
769 } else {
770 HLTFatal("task initialization failed");
771 iResult=-EFAULT;
772 }
773 } else {
774 iResult=-EINVAL;
775 }
776 return iResult;
777}
778
457ec821 779int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
7a436c89 780{
781 // see header file for function documentation
782 int iResult=0;
783 if (pConsumerTask) {
784 if (fpDataBuffer) {
457ec821 785 iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
7a436c89 786 } else {
787 HLTFatal("internal data buffer missing");
788 iResult=-EFAULT;
789 }
790 } else {
791 iResult=-EINVAL;
792 }
793 return iResult;
794}
795
796int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
797{
798 // see header file for function documentation
799 int iResult=0;
800 if (pConsumerTask && pBlockDesc) {
801 if (fpDataBuffer) {
b46ca65e 802 iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
7a436c89 803 } else {
804 HLTFatal("internal data buffer missing");
805 iResult=-EFAULT;
806 }
807 } else {
808 iResult=-EINVAL;
809 }
810 return iResult;
811}
812
813void AliHLTTask::PrintStatus()
814{
815 // see header file for function documentation
816 HLTLogKeyword("task properties");
817 AliHLTComponent* pComponent=GetComponent();
818 if (pComponent) {
819 HLTMessage(" component: %s (%p)", pComponent->GetComponentID(), pComponent);
820 } else {
821 HLTMessage(" no component set!");
822 }
823 if (fpConfiguration) {
824 AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
825 while (pSrc) {
826 const char* pQualifier="unresolved";
827 if (FindDependency(pSrc->GetName()))
828 pQualifier="resolved";
829 HLTMessage(" source: %s (%s)", pSrc->GetName(), pQualifier);
830 pSrc=fpConfiguration->GetNextSource();
831 }
832 TObjLink* lnk = fListTargets.FirstLink();
833 while (lnk) {
834 TObject *obj = lnk->GetObject();
835 HLTMessage(" target: %s", obj->GetName());
836 lnk = lnk->Next();
837 }
838 } else {
97d2b87a 839 HLTMessage(" task not initialized");
7a436c89 840 }
841}
7131ea63 842
843int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
844{
845 // default implementation nothing to do
846 return 0;
847}
848
849int AliHLTTask::CustomCleanup()
850{
851 // default implementation nothing to do
852 return 0;
853}
97d2b87a 854
855int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity,
856 const char* originClass, const char* originFunc,
857 const char* file, int line, ... ) const
858{
859 // see header file for function documentation
860 int iResult=0;
861
862 va_list args;
863 va_start(args, line);
864
7efb6418 865 AliHLTLogging::SetLogString(this, " (%p)", "%s_pfmt_: ", GetName());
97d2b87a 866 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
867 va_end(args);
868
869 return iResult;
870}