]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTTask.cxx
Cosmetics. Fixed bug preventing creation of async block list
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTTask.cxx
1 // $Id$
2 //**************************************************************************
3 //* This file is property of and copyright by the ALICE HLT Project        * 
4 //* ALICE Experiment at CERN, All rights reserved.                         *
5 //*                                                                        *
6 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
7 //*                  for The ALICE HLT Project.                            *
8 //*                                                                        *
9 //* Permission to use, copy, modify and distribute this software and its   *
10 //* documentation strictly for non-commercial purposes is hereby granted   *
11 //* without fee, provided that the above copyright notice appears in all   *
12 //* copies and that both the copyright notice and this permission notice   *
13 //* appear in the supporting documentation. The authors make no claims     *
14 //* about the suitability of this software for any purpose. It is          *
15 //* provided "as is" without express or implied warranty.                  *
16 //**************************************************************************
17
18 /// @file   AliHLTTask.cxx
19 /// @author Matthias Richter
20 /// @date   
21 /// @brief  Implementation of HLT tasks.
22 ///
23
24 // see header file for class documentation
25 // or
26 // refer to README to build package
27 // or
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
29
30 #if __GNUC__>= 3
31 using namespace std;
32 #endif
33
34 #include <cerrno>
35 #include <cassert>
36 #include <iostream>
37 #include <string>
38 #include <ctime>
39 #include "AliHLTTask.h"
40 #include "AliHLTConfiguration.h"
41 #include "AliHLTConfigurationHandler.h"
42 #include "AliHLTComponent.h"
43 #include "AliHLTComponentHandler.h"
44 #include "TList.h"
45 #include "AliHLTErrorGuard.h"
46
47 /** ROOT macro for the implementation of ROOT specific class methods */
48 ClassImp(AliHLTTask)
49
50 AliHLTTask::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
66 AliHLTTask::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
78 AliHLTTask::~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
100 int 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) {
105     HLTWarning("overriding existing reference to configuration object %p by %p",
106                fpConfiguration, pConf);
107   }
108   if (pConf!=NULL) fpConfiguration=pConf;
109   iResult=CreateComponent(fpConfiguration, pCH, fpComponent);
110   if (iResult>=0) {
111     iResult=CustomInit(pCH);
112   }
113   return iResult;
114 }
115
116 int AliHLTTask::CreateComponent(AliHLTConfiguration* pConfiguration, AliHLTComponentHandler* pCH, AliHLTComponent*& pComponent) const
117 {
118   // see header file for class documentation
119   int iResult=0;
120   if (!pConfiguration) return -EINVAL;
121
122   const AliHLTConfiguration* pConf=AliHLTConfigurationHandler::FindSubstitution(*pConfiguration);
123   if (!pConf) pConf=pConfiguration;
124   if (pConf) {
125     if (pCH) {
126       int argc=0;
127       const char** argv=NULL;
128       if ((iResult=pConf->GetArguments(&argv))>=0) {
129         argc=iResult; // just to make it clear
130         // TODO: we have to think about the optional environment parameter,
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           }
143         } else {
144           //HLTError("can not find component \"%s\" (%d)", pConf->GetComponentID(), iResult);
145         }
146       } else {
147         HLTError("can not get argument list for configuration %s (%s)", pConf->GetName(), pConf->GetComponentID());
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
161 int AliHLTTask::Deinit()
162 {
163   // see header file for function documentation
164   int iResult=0;
165   CustomCleanup();
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 {
173     HLTWarning("task doesn't seem to be in initialized");
174   }
175   return iResult;
176 }
177
178 const 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
186 AliHLTConfiguration* AliHLTTask::GetConf() const
187 {
188   // see header file for function documentation
189   return fpConfiguration;
190 }
191
192 AliHLTComponent* AliHLTTask::GetComponent() const
193 {
194   // see header file for function documentation
195   return fpComponent;
196 }
197
198 AliHLTTask* 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
208 int 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
238 void 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) {
252     HLTMessage("     dependency level %d ", iResult);
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
271 int 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
287 int 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
297 int 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
313 int 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
334 AliHLTTask* 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
344 int 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
360 int AliHLTTask::UnsetTarget(AliHLTTask* pTarget)
361 {
362   // see header file for function documentation
363   fListTargets.Remove(pTarget);
364   return 0;
365 }
366
367 int 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
375     { // set scope for lnk as a local variable
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     }
391     }
392     if (iResult>=0) {
393       if (fBlockDataArray.size()>0) {
394         HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
395         fBlockDataArray.clear();
396       }
397
398       // component init
399       // the initialization of the component is done by the ComponentHandler after creation
400       // of the component.
401       //iResult=Init( AliHLTAnalysisEnvironment* environ, void* environ_param, int argc, const char** argv );
402
403       // allocate the data buffer, which controls the output buffer and subscriptions
404       if (iResult>=0) {
405         fpDataBuffer=new AliHLTDataBuffer;
406         if (fpDataBuffer!=NULL) {
407           fpDataBuffer->SetLocalLoggingLevel(GetLocalLoggingLevel());
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     }
427     if (iResult>=0) {
428       // send the SOR event
429       
430     }
431   } else {
432     HLTError("task %s (%p) does not have a component", GetName(), this);
433     iResult=-EFAULT;
434   }
435   return iResult;
436 }
437
438 int AliHLTTask::EndRun()
439 {
440   // see header file for function documentation
441   int iResult=0;
442   if (fBlockDataArray.size()>0) {
443     fBlockDataArray.clear();
444   }
445   if (fpDataBuffer) {
446     AliHLTDataBuffer* pBuffer=fpDataBuffer;
447     fpDataBuffer=NULL;
448     delete pBuffer;
449   }
450   return iResult;
451 }
452
453 int AliHLTTask::ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType, AliHLTUInt64_t trgMask,
454                             AliHLTUInt32_t timestamp, AliHLTUInt32_t participatingDetectors)
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;
466     AliHLTTaskPList subscribedTaskList;
467     TObjLink* lnk=fListDependencies.FirstLink();
468
469     // instances of SOR and EOR events to be kept
470     int iSOR=-1;
471     int iEOR=-1;
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;
477
478     // subscribe to all source tasks
479     fBlockDataArray.clear();
480     while (lnk && iResult>=0) {
481       pSrcTask=(AliHLTTask*)lnk->GetObject();
482       if (pSrcTask) {
483         int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
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);
490         }
491         if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) {
492           iSOR=iEOR=iECS=-1;
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);
498             bRemove|=(*block).fDataType==kAliHLTDataTypeECSParam && !(iECS<0 && (iECS=i)>=0);
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;
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
511             subscribedTaskList.push_back(pSrcTask);
512             }
513             block++;
514           }
515           HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
516           iSourceDataBlock=fBlockDataArray.size();        
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();
527     }    
528
529     // process the event
530     int iNofTrial=0; // repeat processing if component returns -ENOSPC
531     AliHLTUInt32_t iLastOutputDataSize=0;
532     if (iResult>=0) {
533     do {
534       long unsigned int iOutputDataSize=0;
535       AliHLTConfiguration* pConf=GetConf();
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 {
541       long unsigned int iConstBase=0;
542       double fInputMultiplier=0;
543       if (pComponent->GetComponentType()!=AliHLTComponent::kSink) {
544         pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
545         // add a small margin to the buffer to allow optional component
546         // statistics
547         iConstBase+=100;
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
556       }
557       if (fInputMultiplier<0) {
558         HLTWarning("ignoring negative input multiplier");
559         fInputMultiplier=0;
560       }
561       iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
562       //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
563       }
564       if (iNofTrial>0) {
565         // dont process again if the buffer size is the same
566         if (iLastOutputDataSize==iOutputDataSize) break;
567         HLTImportant("processing event %d again with buffer size %d", eventNo, iOutputDataSize);
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);
574       if (eventNo>=0)
575         evtData.fEventID=(AliHLTEventID_t)eventNo;
576       if (timestamp) evtData.fEventCreation_s=timestamp;
577       else
578       evtData.fEventCreation_s=static_cast<AliHLTUInt32_t>(time(NULL));
579       AliHLTComponentTriggerData trigData;
580       AliHLTEventTriggerData evtTrigData;
581       trigData.fStructSize=sizeof(trigData);
582       trigData.fDataSize=sizeof(AliHLTEventTriggerData);
583       memset(&evtTrigData, 0, trigData.fDataSize);
584       // Setup the CDH in the trigger data, based on the event type, CTP trigger
585       // mask and participating detectors.
586       evtTrigData.fCommonHeaderWordCnt=gkAliHLTCommonHeaderCount;
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;
598       evtTrigData.fCommonHeader[3] = ((l1msg & 0x1) == 0x1) ? (participatingDetectors & 0xFFFFFF) : 0x0;
599       evtTrigData.fCommonHeader[5]=trgMask&0xffffffff;
600       evtTrigData.fCommonHeader[6]=(trgMask>>32)&0x3ffff;
601       trigData.fData=&evtTrigData;
602       iLastOutputDataSize=iOutputDataSize;
603       AliHLTUInt32_t size=iOutputDataSize;
604       AliHLTUInt32_t outputBlockCnt=0;
605       AliHLTComponentBlockData* outputBlocks=NULL;
606       AliHLTComponentEventDoneData* edd=NULL;
607       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
608         // add event type data block
609         // the block is removed immediately after processing from the list
610         AliHLTComponentBlockData eventTypeBlock;
611         AliHLTComponent::FillBlockData(eventTypeBlock);
612         // Note: no payload!
613         eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
614         eventTypeBlock.fSpecification=eventType;
615         fBlockDataArray.push_back(eventTypeBlock);
616
617         if (CheckFilter(kHLTLogDebug)) Print("proc");
618
619         AliHLTUInt32_t iblock=0;
620         // check input and output buffers for consistency
621         // to be enabled after fixing bug with DataBuffer and forwarded SOR/EOR
622         //for (iblock=0; iblock<fBlockDataArray.size(); iblock++) {
623         //  if ((AliHLTUInt8_t*)fBlockDataArray[iblock].fPtr >= pTgtBuffer+size) continue;
624         //  if (pTgtBuffer >= (AliHLTUInt8_t*)fBlockDataArray[iblock].fPtr+fBlockDataArray[iblock].fSize) continue;
625         //  HLTFatal("input and output buffer overlap for block descriptor %d (ptr %p size %d): output buffer %p %d",
626         //         iblock, fBlockDataArray[iblock].fPtr, fBlockDataArray[iblock].fSize,
627         //         pTgtBuffer, size);
628         //}     
629
630         // process
631         evtData.fBlockCnt=fBlockDataArray.size();
632         iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
633         HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt);
634
635         // EventDoneData is for the moment ignored in AliHLTSystem
636         if (edd) {
637           HLTDebug("got EventDoneData size %d", edd->fDataSize);
638           delete [] reinterpret_cast<char*>(edd);
639           edd=NULL;
640         }
641
642         // remove event data block
643         fBlockDataArray.pop_back();
644
645         // check for forwarded blocks.
646         // loop over all output blocks and check
647         // 1. for duplicate blocks (pointing to same location in output buffer
648         //    or to the same buffer)
649         // 2. for blocks forwarded from the input.
650         if (iResult>=0 && outputBlocks) {
651           if (fListTargets.First()!=NULL) {
652             AliHLTComponentBlockDataList segments;
653             for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
654               // consistency check for data reference
655               if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
656                   outputBlocks[oblock].fOffset!=0) {
657                 HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: "
658                            "for new blocks use offset only, forwarded blocks have fPtr set only",
659                            AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
660                            outputBlocks[oblock].fSpecification,
661                            outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset);
662               }
663
664               // check for duplicates in the output
665               // this check applies for forwarded data blocks where
666               // the ptr is not inside the target buffer
667               AliHLTUInt32_t checkblock=0;
668               for (; checkblock<oblock; checkblock++) {
669                 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
670                     outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) {
671                   if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize ||
672                       outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) {
673                     HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p "
674                                "but differ in data type and/or size: %d vs. %d, ignoring block %d",
675                                oblock,
676                                AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
677                                outputBlocks[oblock].fSpecification,
678                                checkblock,
679                                AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(),
680                                outputBlocks[checkblock].fSpecification,
681                                outputBlocks[oblock].fPtr,
682                                outputBlocks[oblock].fSize,
683                                outputBlocks[checkblock].fSize,
684                                checkblock);
685                   }
686                   // ignore from the second copy
687                   break;
688                 }
689               }
690               if (checkblock<oblock) continue;
691
692               // search for the forwarded data blocks
693               // new data blocks are announced to the data buffer, forwarded data blocks
694               // to the publisher task. The publisher task of a forwarded data block is
695               // removed from the list in order to keep the buffer open. It will be releases
696               // when the subscribing task releases it
697               iblock=0;
698               for (; iblock<fBlockDataArray.size(); iblock++) {
699                 if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) {
700                   // the event type data block is an artificial data block
701                   // ignore if it was forwarded
702                   break;
703                 }
704                 if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
705                   assert(subscribedTaskList[iblock]!=NULL);
706                   if (subscribedTaskList[iblock]==NULL) {
707                     ALIHLTERRORGUARD(1, "missing parent task for forwarded data block %s 0x%08x, original data block %s 0x%08x, subsequent errors are suppressed",
708                                      AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
709                                      outputBlocks[oblock].fSpecification,
710                                      AliHLTComponent::DataType2Text(outputBlocks[iblock].fDataType).c_str(),
711                                      outputBlocks[iblock].fSpecification);
712                     continue;
713                   }
714                   HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
715                   fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
716                   subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
717                   break;
718                 }
719               }
720               if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
721             }
722             if (pTgtBuffer && segments.size()>0) {
723               iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
724             }
725           } else {
726             // no forwarding, actually we dont even need to keep the data, this is a
727             // dead end (fListTargets empty)
728             //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
729           }
730           delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
731         } else {
732           fpDataBuffer->Reset();
733         }
734         if (fListTargets.First()!=NULL) {
735           if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
736             HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
737             fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
738             subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
739           }
740           if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
741             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);
742             fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
743             subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
744           }
745           if (iECS>=0 && subscribedTaskList[iECS]!=NULL) {
746             HLTDebug("forward ECS event (%s) segment %d (source task %s %p) to data buffer %p", AliHLTComponent::DataType2Text(fBlockDataArray[iECS].fDataType).c_str(), iECS, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
747             fpDataBuffer->Forward(subscribedTaskList[iECS], &fBlockDataArray[iECS]);
748             subscribedTaskList[iECS]=NULL; // not to be released in the loop further down
749           }
750         }
751       } else {
752         HLTError("no target buffer available");
753         iResult=-EFAULT;
754       }
755     } while (iResult==-ENOSPC && iNofTrial++<1);
756     }
757
758     fBlockDataArray.clear();
759     if (CheckFilter(kHLTLogDebug)) Print("proc");
760
761     // now release all buffers which we have subscribed to
762     iSourceDataBlock=0;
763     AliHLTTaskPList::iterator element;
764     while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
765       pSrcTask=*element;
766       if (pSrcTask) {
767         int iTempRes=0;
768         if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
769           HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
770         } else {
771           HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes);
772         }
773       }
774       subscribedTaskList.erase(element);
775       iSourceDataBlock++;
776     }
777     if (subscribedTaskList.size()>0) {
778       HLTError("could not release all data buffers");
779     }
780   } else {
781     HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer);
782     iResult=-EFAULT;
783   }
784   return iResult;
785 }
786
787 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
788 {
789   // see header file for function documentation
790   int iResult=0;
791   if (pConsumerTask) {
792     if (fpDataBuffer) {
793       iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
794     } else {
795       HLTFatal("internal data buffer missing");
796       iResult=-EFAULT;
797     }
798   } else {
799     iResult=-EINVAL;
800   }
801   return iResult;
802 }
803
804 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
805 {
806   // see header file for function documentation
807   int iResult=0;
808   if (pConsumerTask) {
809     AliHLTComponent* pComponent=GetComponent();
810     if (!pComponent) {
811       // init ?
812       HLTError("component not initialized");
813       iResult=-EFAULT;
814     }
815     if (pComponent) {
816       iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
817     } else {
818       HLTFatal("task initialization failed");
819       iResult=-EFAULT;
820     }
821   } else {
822     iResult=-EINVAL;
823   }
824   return iResult;
825 }
826
827 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
828 {
829   // see header file for function documentation
830   int iResult=0;
831   if (pConsumerTask) {
832     if (fpDataBuffer) {
833       iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
834     } else {
835       HLTFatal("internal data buffer missing");
836       iResult=-EFAULT;
837     }
838   } else {
839     iResult=-EINVAL;
840   }
841   return iResult;
842 }
843
844 int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
845 {
846   // see header file for function documentation
847   int iResult=0;
848   if (pConsumerTask && pBlockDesc) {
849     if (fpDataBuffer) {
850       iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
851     } else {
852       HLTFatal("internal data buffer missing");
853       iResult=-EFAULT;
854     }
855   } else {
856     iResult=-EINVAL;
857   }
858   return iResult;
859 }
860
861 void AliHLTTask::PrintStatus()
862 {
863   // see header file for function documentation
864   HLTLogKeyword("task properties");
865   AliHLTComponent* pComponent=GetComponent();
866   if (pComponent) {
867     HLTMessage("     component: %s (%p)", pComponent->GetComponentID(), pComponent);
868   } else {
869     HLTMessage("     no component set!");
870   }
871   if (fpConfiguration) {
872     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
873     while (pSrc) {
874       const char* pQualifier="unresolved";
875       if (FindDependency(pSrc->GetName()))
876         pQualifier="resolved";
877       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
878       pSrc=fpConfiguration->GetNextSource();
879     }
880     TObjLink* lnk = fListTargets.FirstLink();
881     while (lnk) {
882       TObject *obj = lnk->GetObject();
883       HLTMessage("     target: %s", obj->GetName());
884       lnk = lnk->Next();
885     }
886   } else {
887     HLTMessage("     task not initialized");
888   }
889 }
890
891 void AliHLTTask::Print(const char* options) const
892 {
893   // Overloaded from TObject
894   if (strcmp(options, "proc")==0) {
895     // print processing info
896     HLTMessage("**********************************************");
897     HLTMessage("******* AliHLTTask Processing info ***********");
898     HLTMessage(" component: %p %s", fpComponent, (fpComponent?fpComponent->GetComponentID():""));
899     HLTMessage(" data buffer: %p", fpDataBuffer);
900     if (fpDataBuffer) fpDataBuffer->Print("");
901     HLTMessage(" input block descriptors: %d", fBlockDataArray.size());
902     for (unsigned i=0; i<fBlockDataArray.size(); i++) {
903       HLTMessage("  %d: %s 0x%08x %p %d", i,
904                  AliHLTComponent::DataType2Text(fBlockDataArray[i].fDataType).c_str(),
905                  fBlockDataArray[i].fSpecification,
906                  fBlockDataArray[i].fPtr,
907                  fBlockDataArray[i].fSize
908                  );
909     }
910     HLTMessage("**** end of AliHLTTask Processing info *******");
911     HLTMessage("**********************************************");
912     return;
913   }
914
915   cout << "AliHLTTask " << GetName() << " " << this
916        << " component " << fpComponent << " "
917        << (fpComponent?fpComponent->GetComponentID():"")
918        << endl;
919 }
920
921
922 int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
923 {
924   // default implementation nothing to do
925   return 0;
926 }
927
928 int AliHLTTask::CustomCleanup()
929 {
930   // default implementation nothing to do
931   return 0;
932 }
933
934 int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity, 
935                                     const char* originClass, const char* originFunc,
936                                     const char* file, int line, ... ) const
937 {
938   // see header file for function documentation
939   int iResult=0;
940
941   va_list args;
942   va_start(args, line);
943
944   AliHLTLogging::SetLogString(this, " (%p)", "%s_pfmt_: ", GetName());
945   iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
946   va_end(args);
947
948   return iResult;
949 }