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