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