]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTConfiguration.cxx
- AliHLTFileWriter added
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTConfiguration.cxx
1 // $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          for The ALICE Off-line 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   AliHLTConfiguration.cxx
19     @author Matthias Richter
20     @date   
21     @brief  Implementation of HLT configuration handler.
22 */
23
24 #if __GNUC__>= 3
25 using namespace std;
26 #endif
27
28 #include <cerrno>
29 #include "AliHLTConfiguration.h"
30 #include "AliHLTConfigurationHandler.h"
31 #include "AliHLTTask.h"
32 #include "AliHLTComponent.h"
33 #include "AliHLTComponentHandler.h"
34 #include <iostream>
35 #include <string>
36
37 /** ROOT macro for the implementation of ROOT specific class methods */
38 ClassImp(AliHLTConfiguration)
39
40 AliHLTConfiguration::AliHLTConfiguration()
41   :
42   fID(NULL),
43   fComponent(NULL),
44   fStringSources(NULL),
45   fNofSources(-1),
46   fListSources(),
47   fListSrcElement(),
48   fArguments(NULL),
49   fArgc(-1),
50   fArgv(NULL)
51
52   fListSrcElement=fListSources.begin();
53 }
54
55 AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
56   :
57   fID(id),
58   fComponent(component),
59   fStringSources(sources),
60   fNofSources(-1),
61   fListSources(),
62   fListSrcElement(),
63   fArguments(arguments),
64   fArgc(-1),
65   fArgv(NULL)
66 {
67   fListSrcElement=fListSources.begin();
68   if (id && component) {
69     if (fConfigurationHandler) {
70       fConfigurationHandler->RegisterConfiguration(this);
71     } else {
72       HLTError("no configuration handler set, abort registration");
73     }
74   }
75 }
76
77 AliHLTConfiguration::AliHLTConfiguration(const AliHLTConfiguration&)
78   :
79   TObject(),
80   AliHLTLogging(),
81   fID(NULL),
82   fComponent(NULL),
83   fStringSources(NULL),
84   fNofSources(-1),
85   fListSources(),
86   fListSrcElement(),
87   fArguments(NULL),
88   fArgc(-1),
89   fArgv(NULL)
90
91   fListSrcElement=fListSources.begin();
92   HLTFatal("copy constructor untested");
93 }
94
95 AliHLTConfiguration& AliHLTConfiguration::operator=(const AliHLTConfiguration&)
96
97   HLTFatal("assignment operator untested");
98   return *this;
99 }
100
101 AliHLTConfiguration::~AliHLTConfiguration()
102 {
103   if (fConfigurationHandler) {
104     if (fConfigurationHandler->FindConfiguration(fID)!=NULL) {
105       fConfigurationHandler->RemoveConfiguration(this);
106     }
107   }
108   if (fArgv != NULL) {
109     if (fArgc>0) {
110       for (int i=0; i<fArgc; i++) {
111         delete[] fArgv[i];
112       }
113     }
114     delete[] fArgv;
115     fArgv=NULL;
116   }
117 }
118
119 /* the global configuration handler which is used to automatically register the configuration
120  */
121 AliHLTConfigurationHandler* AliHLTConfiguration::fConfigurationHandler=NULL;
122
123 int AliHLTConfiguration::GlobalInit(AliHLTConfigurationHandler* pHandler)
124 {
125   int iResult=0;
126   if (fConfigurationHandler!=NULL) {
127     fConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalInit", HLT_DEFAULT_LOG_KEYWORD, "configuration handler already initialized, overriding object %p", fConfigurationHandler);
128   }
129   fConfigurationHandler=pHandler;
130   return iResult;
131 }
132
133 int AliHLTConfiguration::GlobalDeinit()
134 {
135   int iResult=0;
136   fConfigurationHandler=NULL;
137   return iResult;
138 }
139
140 const char* AliHLTConfiguration::GetName() const {
141   if (fID)
142     return fID;
143   return TObject::GetName();
144 }
145
146 AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
147 {
148   AliHLTConfiguration* pSrc=NULL;
149   if (id) {
150     // first check the current element
151     if (fListSrcElement!=fListSources.end() && strcmp(id, (*fListSrcElement)->GetName())==0) {
152       pSrc=*fListSrcElement;
153       } else {
154       // check the list
155
156       pSrc=GetFirstSource();
157       while (pSrc) {
158         if (strcmp(id, pSrc->GetName())==0)
159           break;
160         pSrc=GetNextSource();
161       }
162     }
163   }
164   return pSrc;
165 }
166
167 AliHLTConfiguration* AliHLTConfiguration::GetFirstSource()
168 {
169   AliHLTConfiguration* pSrc=NULL;
170   if (fNofSources>=0 || ExtractSources()) {
171     fListSrcElement=fListSources.begin();
172     if (fListSrcElement!=fListSources.end()) pSrc=*fListSrcElement;
173   } 
174   return pSrc;
175 }
176
177 AliHLTConfiguration* AliHLTConfiguration::GetNextSource()
178 {
179   AliHLTConfiguration* pSrc=NULL;
180   if (fNofSources>0) {
181     if (fListSrcElement!=fListSources.end() && (++fListSrcElement)!=fListSources.end()) 
182       pSrc=*fListSrcElement;
183   } 
184   return pSrc;
185 }
186
187 int AliHLTConfiguration::SourcesResolved(int bAuto) 
188 {
189   int iResult=0;
190   if (fNofSources>=0 || bAuto && (iResult=ExtractSources())>=0) {
191     //HLTDebug("fNofSources=%d", fNofSources);
192     //HLTDebug("list size = %d", fListSources.size());
193     iResult=fNofSources==(int)fListSources.size();
194   }
195   return iResult;
196 }
197
198 int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
199 {
200   int iResult=0;
201   if (pConf) {
202     vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
203     while (element!=fListSources.end()) {
204       if (*element==pConf) {
205         fListSources.erase(element);
206         fListSrcElement=fListSources.end();
207         // there is no need to re-evaluate until there was a new configuration registered
208         // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
209         //InvalidateSources();
210         break;
211       }
212       element++;
213     }
214   } else {
215     iResult=-EINVAL;
216   }
217   return iResult;
218 }
219
220 void AliHLTConfiguration::PrintStatus()
221 {
222   HLTLogKeyword("configuration status");
223   HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
224   if (fComponent) HLTMessage("  - component: \"%s\"", fComponent);
225   else HLTMessage("  - component string invalid");
226   if (fStringSources) HLTMessage("  - sources: \"%s\"", fStringSources);
227   else HLTMessage("  - no sources");
228   if (SourcesResolved(1)<=0)
229     HLTMessage("    there are unresolved sources");
230   AliHLTConfiguration* pSrc=GetFirstSource();
231   while (pSrc) {
232     HLTMessage("    source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
233     pSrc=GetNextSource();
234   }
235 }
236
237 int AliHLTConfiguration::GetArguments(const char*** pArgv)
238 {
239   int iResult=0;
240   if (pArgv) {
241     if (fArgc==-1) {
242       if ((iResult=ExtractArguments())<0) {
243         HLTError("error extracting arguments for configuration %s", GetName());
244         fArgc=-EINVAL;
245       }
246     } else if (fArgc<0) {
247       HLTError("previous argument extraction failed");
248     }
249     //HLTDebug("%s fArgc %d", GetName(), fArgc);
250     iResult=fArgc;
251     *pArgv=(const char**)fArgv;
252   } else {
253     HLTError("invalid parameter");
254     iResult=-EINVAL;
255   }
256   return iResult;
257 }
258
259
260 int AliHLTConfiguration::ExtractSources()
261 {
262   int iResult=0;
263   fNofSources=0;
264   if (fStringSources!=NULL) {
265     vector<char*> tgtList;
266     fListSources.clear();
267     if ((iResult=InterpreteString(fStringSources, tgtList))>=0) {
268       fNofSources=tgtList.size();
269       vector<char*>::iterator element=tgtList.begin();
270       while ((element=tgtList.begin())!=tgtList.end()) {
271         if (fConfigurationHandler) {
272           AliHLTConfiguration* pConf=fConfigurationHandler->FindConfiguration(*element);
273           if (pConf) {
274             HLTDebug("source \"%s\" inserted", pConf->GetName());
275             fListSources.push_back(pConf);
276           } else {
277             HLTError("can not find source \"%s\"", (*element));
278             iResult=-ENOENT;
279           }
280         } else if (iResult>=0) {
281           iResult=-EFAULT;
282           HLTFatal("global configuration handler not initialized, can not resolve sources");
283         }
284         delete[] (*element);
285         tgtList.erase(element);
286       }
287       fListSrcElement=fListSources.begin();
288     }
289   }
290   return iResult;
291 }
292
293 int AliHLTConfiguration::ExtractArguments()
294 {
295   int iResult=0;
296   if (fArguments!=NULL) {
297     vector<char*> tgtList;
298     if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
299       fArgc=tgtList.size();
300       //HLTDebug("configuration %s: extracted %d arguments from \"%s\"", GetName(), fArgc, fArguments);
301       if (fArgc>0) {
302         fArgv = new char*[fArgc];
303         if (fArgv) {
304           vector<char*>::iterator element=tgtList.begin();
305           int i=0;
306           while (element!=tgtList.end()) {
307             //HLTDebug("assign arguments %d (%s)", i, *element);
308             fArgv[i++]=(*element);
309             element++;
310           }
311         } else {
312           iResult=-ENOMEM;
313         }
314       }
315     }
316   } else {
317     // there are zero arguments
318     fArgc=0;
319   }
320   return iResult;
321 }
322
323 int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
324 {
325   int iResult=0;
326   if (arg) {
327     //HLTDebug("interprete \"%s\"", arg);
328     int i=0;
329     int prec=-1;
330     do {
331       if (arg[i]==0 || arg[i]==' ') {
332         if (prec>=0) {
333           char* pEntry= new char[i-prec+1];
334           if (pEntry) {
335             strncpy(pEntry, &arg[prec], i-prec);
336             pEntry[i-prec]=0; // terminate string
337             //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
338             argList.push_back(pEntry);
339           } else 
340             iResult=-ENOMEM;
341           prec=-1;
342         }
343       } else if (prec==-1) prec=i;
344     } while (arg[i++]!=0 && iResult>=0); 
345   } else {
346     iResult=-EINVAL;
347   }
348   return iResult;
349 }
350
351 int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
352 {
353   int iResult=0;
354   if (id) {
355     AliHLTConfiguration* pDep=NULL;
356     if ((pDep=GetSource(id))!=NULL) {
357       if (pTgtList) pTgtList->Add(pDep);
358       iResult++;
359     } else {
360       pDep=GetFirstSource();
361       while (pDep && iResult==0) {
362         if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
363           if (pTgtList) pTgtList->AddFirst(pDep);
364           iResult++;
365         }
366         pDep=GetNextSource();
367       }
368     }
369   } else {
370     iResult=-EINVAL;
371   }
372   return iResult;
373 }
374
375 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
376
377 /** ROOT macro for the implementation of ROOT specific class methods */
378 ClassImp(AliHLTTask)
379
380 AliHLTTask::AliHLTTask()
381   :
382   fpConfiguration(NULL),
383   fpComponent(NULL),
384   fpDataBuffer(NULL),
385   fListTargets(),
386   fListDependencies(),
387   fpBlockDataArray(NULL),
388   fBlockDataArraySize(0)
389 {
390 }
391
392 AliHLTTask::AliHLTTask(AliHLTConfiguration* pConf)
393   :
394   fpConfiguration(pConf),
395   fpComponent(NULL),
396   fpDataBuffer(NULL),
397   fListTargets(),
398   fListDependencies(),
399   fpBlockDataArray(NULL),
400   fBlockDataArraySize(0)
401 {
402 }
403
404 AliHLTTask::AliHLTTask(const AliHLTTask&)
405   :
406   TObject(),
407   AliHLTLogging(),
408   fpConfiguration(NULL),
409   fpComponent(NULL),
410   fpDataBuffer(NULL),
411   fListTargets(),
412   fListDependencies(),
413   fpBlockDataArray(NULL),
414   fBlockDataArraySize(0)
415 {
416   HLTFatal("copy constructor untested");
417 }
418
419 AliHLTTask& AliHLTTask::operator=(const AliHLTTask&)
420
421   HLTFatal("assignment operator untested");
422   return *this;
423 }
424
425 AliHLTTask::~AliHLTTask()
426 {
427   if (fpComponent) delete fpComponent;
428   fpComponent=NULL;
429   if (fpBlockDataArray) delete[] fpBlockDataArray;
430   fpBlockDataArray=NULL;
431 }
432
433 int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH)
434 {
435   int iResult=0;
436   if (fpConfiguration!=NULL && pConf!=NULL && fpConfiguration!=pConf) {
437     HLTWarning("overriding existing reference to configuration object %p (%s) by %p",
438                fpConfiguration, GetName(), pConf);
439   }
440   if (pConf!=NULL) fpConfiguration=pConf;
441   if (fpConfiguration) {
442     if (pCH) {
443       int argc=0;
444       const char** argv=NULL;
445       if ((iResult=fpConfiguration->GetArguments(&argv))>=0) {
446         argc=iResult; // just to make it clear
447         // TODO: we have to think about the optional environment parameter,
448         // currently just set to NULL. 
449         iResult=pCH->CreateComponent(fpConfiguration->GetComponentID(), NULL, argc, argv, fpComponent);
450         if (fpComponent || iResult<=0) {
451         } else {
452           HLTError("can not find component \"%s\" (%d)", fpConfiguration->GetComponentID(), iResult);
453         }
454       } else {
455         HLTError("can not get argument list for configuration %s (%s)", fpConfiguration->GetName(), fpConfiguration->GetComponentID());
456         iResult=-EINVAL;
457       }
458     } else {
459       HLTError("component handler instance needed for task initialization");
460       iResult=-EINVAL;
461     }
462   } else {
463     HLTError("configuration object instance needed for task initialization");
464     iResult=-EINVAL;
465   }
466   return iResult;
467 }
468
469 int AliHLTTask::Deinit()
470 {
471   int iResult=0;
472   AliHLTComponent* pComponent=GetComponent();
473   fpComponent=NULL;
474   if (pComponent) {
475     pComponent->Deinit();
476     delete pComponent;
477   } else {
478     HLTWarning("task %s (%p) doesn't seem to be in initialized", GetName(), this);
479   }
480   return iResult;
481 }
482
483 const char *AliHLTTask::GetName() const
484 {
485   if (fpConfiguration)
486     return fpConfiguration->GetName();
487   return TObject::GetName();
488 }
489
490 AliHLTConfiguration* AliHLTTask::GetConf() const
491 {
492   return fpConfiguration;
493 }
494
495 AliHLTComponent* AliHLTTask::GetComponent() const
496 {
497   return fpComponent;
498 }
499
500 AliHLTTask* AliHLTTask::FindDependency(const char* id)
501 {
502   AliHLTTask* pTask=NULL;
503   if (id) {
504     pTask=(AliHLTTask*)fListDependencies.FindObject(id);
505   }
506   return pTask;
507 }
508
509 int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
510 {
511   int iResult=0;
512   if (id) {
513     AliHLTTask* pDep=NULL;
514     if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
515       if (pTgtList) pTgtList->Add(pDep);
516       iResult++;
517     } else {
518       TObjLink* lnk=fListDependencies.FirstLink();
519       while (lnk && iResult==0) {
520         pDep=(AliHLTTask*)lnk->GetObject();
521         if (pDep) {
522           if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
523             if (pTgtList) pTgtList->AddFirst(pDep);
524             iResult++;
525           }
526         } else {
527           iResult=-EFAULT;
528         }
529         lnk=lnk->Next();
530       }
531     }
532   } else {
533     iResult=-EINVAL;
534   }
535   return iResult;
536 }
537
538 void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
539 {
540   HLTLogKeyword("task dependencies");
541   int iResult=0;
542   TList tgtList;
543   if (bFromConfiguration) {
544     if (fpConfiguration)
545       iResult=fpConfiguration->FollowDependency(id, &tgtList);
546     else
547       iResult=-EFAULT;
548   } else
549     iResult=FollowDependency(id, &tgtList);
550   if (iResult>0) {
551     HLTMessage("     task \"%s\": dependency level %d ", GetName(), iResult);
552     TObjLink* lnk=tgtList.FirstLink();
553     int i=iResult;
554     char* pSpace = new char[iResult+1];
555     if (pSpace) {
556       memset(pSpace, 32, iResult);
557       pSpace[i]=0;
558       while (lnk) {
559         TObject* obj=lnk->GetObject();
560         HLTMessage("     %s^-- %s ", &pSpace[i--], obj->GetName());
561         lnk=lnk->Next();
562       }
563       delete [] pSpace;
564     } else {
565       iResult=-ENOMEM;
566     }
567   }
568 }
569
570 int AliHLTTask::SetDependency(AliHLTTask* pDep)
571 {
572   int iResult=0;
573   if (pDep) {
574     if (FindDependency(pDep->GetName())==NULL) {
575       fListDependencies.Add(pDep);
576     } else {
577       iResult=-EEXIST;
578     }
579   } else {
580     iResult=-EINVAL;
581   }
582   return iResult;
583 }
584
585 int AliHLTTask::CheckDependencies()
586 {
587   int iResult=0;
588   AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
589   while (pSrc) {
590     if (FindDependency(pSrc->GetName())==NULL) {
591       //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
592       iResult++;
593     }
594     pSrc=fpConfiguration->GetNextSource();
595   }
596   return iResult;
597 }
598
599
600 int AliHLTTask::Depends(AliHLTTask* pTask)
601 {
602   int iResult=0;
603   if (pTask) {
604     if (fpConfiguration) {
605       iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
606       if (iResult>0) {
607         //HLTDebug("task  \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
608       } else {
609         //HLTDebug("task  \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
610       }
611     } else {
612       iResult=-EFAULT;
613     }
614   } else {
615     iResult=-EINVAL;
616   }
617   return iResult;
618 }
619
620 AliHLTTask* AliHLTTask::FindTarget(const char* id)
621 {
622   AliHLTTask* pTask=NULL;
623   if (id) {
624     pTask=(AliHLTTask*)fListTargets.FindObject(id);
625   }
626   return pTask;
627 }
628
629 int AliHLTTask::SetTarget(AliHLTTask* pTgt)
630 {
631   int iResult=0;
632   if (pTgt) {
633     if (FindTarget(pTgt->GetName())==NULL) {
634       fListTargets.Add(pTgt);
635     } else {
636       iResult=-EEXIST;
637     }
638   } else {
639     iResult=-EINVAL;
640   }
641   return iResult;
642 }
643
644 int AliHLTTask::StartRun()
645 {
646   int iResult=0;
647   int iNofInputDataBlocks=0;
648   AliHLTComponent* pComponent=GetComponent();
649   if (pComponent) {
650     // determine the number of input data blocks provided from the source tasks
651     TObjLink* lnk=fListDependencies.FirstLink();
652     while (lnk && iResult>=0) {
653       AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
654       if (pSrcTask) {
655         if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
656           iNofInputDataBlocks+=iResult;
657         } else if (iResult==0) {
658           HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
659         } else {
660           HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
661           iResult=-EFAULT;
662         }
663       }
664       lnk=lnk->Next();
665     }
666     if (iResult>=0) {
667       if (fpBlockDataArray) {
668         HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
669         delete [] fpBlockDataArray;
670         fpBlockDataArray=NULL;
671         fBlockDataArraySize=0;
672       }
673
674       // component init
675       // the initialization of the component is done by the ComponentHandler after creation
676       // of the component.
677       //iResult=Init( AliHLTComponentEnvironment* environ, void* environ_param, int argc, const char** argv );
678
679       // allocate internal task variables for bookkeeping aso.
680       // we allocate the BlockData array with at least one member
681       if (iNofInputDataBlocks==0) iNofInputDataBlocks=1;
682       fpBlockDataArray=new AliHLTComponentBlockData[iNofInputDataBlocks];
683       if (fpBlockDataArray) {
684         fBlockDataArraySize=iNofInputDataBlocks;
685       } else {
686         HLTError("memory allocation failed");
687         iResult=-ENOMEM;
688       }
689
690       // allocate the data buffer, which controls the output buffer and subscriptions
691       if (iResult>=0) {
692         fpDataBuffer=new AliHLTDataBuffer;
693         if (fpDataBuffer!=NULL) {
694           HLTDebug("created data buffer %p for task %s (%p)", fpDataBuffer, GetName(), this);
695           TObjLink* lnk=fListTargets.FirstLink();
696           while (lnk && iResult>=0) {
697             AliHLTTask* pTgtTask=(AliHLTTask*)lnk->GetObject();
698             if (pTgtTask) {
699               if ((iResult=fpDataBuffer->SetConsumer(pTgtTask->GetComponent()))>=0) {
700               }
701             } else {
702               break;
703               iResult=-EFAULT;
704             }
705             lnk=lnk->Next();
706           }
707         } else {
708           HLTFatal("can not create data buffer object, memory allocation failed");
709           iResult=-ENOMEM;
710         }
711       }
712     }
713   } else {
714     HLTError("task %s (%p) does not have a component", GetName(), this);
715     iResult=-EFAULT;
716   }
717   return iResult;
718 }
719
720 int AliHLTTask::EndRun()
721 {
722   int iResult=0;
723   if (fpBlockDataArray) {
724     fBlockDataArraySize=0;
725     delete [] fpBlockDataArray;
726     fpBlockDataArray=0;
727   } else {
728     HLTWarning("task %s (%p) doesn't seem to be in running mode", GetName(), this);
729   }
730   if (fpDataBuffer) {
731     AliHLTDataBuffer* pBuffer=fpDataBuffer;
732     fpDataBuffer=NULL;
733     delete pBuffer;
734   }
735   return iResult;
736 }
737
738 int AliHLTTask::ProcessTask(Int_t eventNo)
739 {
740   int iResult=0;
741   AliHLTComponent* pComponent=GetComponent();
742   if (pComponent && fpDataBuffer) {
743     HLTDebug("Processing task %s (%p) fpDataBuffer %p", GetName(), this, fpDataBuffer);
744     fpDataBuffer->Reset();
745     int iSourceDataBlock=0;
746     int iInputDataVolume=0;
747
748     int iNofInputDataBlocks=0;
749     /* TODO: the assumption of only one output data type per component is the current constraint
750      * later it should be checked how many output blocks of the source component match the input
751      * data types of the consumer component (GetNofMatchingDataBlocks). If one assumes that a
752      * certain output block is always been produced, the initialization could be done in the
753      * StartRun. Otherwise the fpBlockDataArray has to be adapted each time.
754      */
755     iNofInputDataBlocks=fListDependencies.GetSize(); // one block per source
756     // is not been used since the allocation was done in StartRun, but check the size
757     if (iNofInputDataBlocks>fBlockDataArraySize) {
758       HLTError("block data array too small");
759     }
760
761     AliHLTTask* pSrcTask=NULL;
762     TList subscribedTaskList;
763     TObjLink* lnk=fListDependencies.FirstLink();
764
765     // subscribe to all source tasks
766     while (lnk && iResult>=0) {
767       pSrcTask=(AliHLTTask*)lnk->GetObject();
768       if (pSrcTask) {
769         int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
770         if (iMatchingDB<=fBlockDataArraySize-iSourceDataBlock) {
771           if (fpBlockDataArray) {
772           if ((iResult=pSrcTask->Subscribe(this, &fpBlockDataArray[iSourceDataBlock],fBlockDataArraySize-iSourceDataBlock))>0) {
773             for (int i=0; i<iResult; i++) {
774               iInputDataVolume+=fpBlockDataArray[i+iSourceDataBlock].fSize;
775               // put the source task as many times into the list as it provides data blocks
776               // makes the bookkeeping for the data release easier
777               subscribedTaskList.Add(pSrcTask);
778             }
779             iSourceDataBlock+=iResult;
780             HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
781             iResult=0;
782           } else {
783             HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
784             iResult=-EFAULT;
785           }
786           } else {
787             HLTFatal("Task %s (%p): BlockData array not allocated", GetName(), this);
788             iResult=-EFAULT;
789           }
790         } else {
791           HLTFatal("Task %s (%p): too little space in data block array for subscription to task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
792           HLTDebug("#data types=%d, array size=%d, current index=%d", iMatchingDB, fBlockDataArraySize, iSourceDataBlock);
793           iResult=-EFAULT;
794         }
795       } else {
796         HLTFatal("fatal internal error in ROOT list handling");
797         iResult=-EFAULT;
798       }
799       lnk=lnk->Next();
800     }
801
802     // process the event
803     if (iResult>=0) {
804       long unsigned int iConstBase=0;
805       double fInputMultiplier=0;
806       if (pComponent->GetComponentType()!=AliHLTComponent::kSink)
807         pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
808       int iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
809       //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
810       AliHLTUInt8_t* pTgtBuffer=NULL;
811       if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
812       //HLTDebug("provided raw buffer %p", pTgtBuffer);
813       AliHLTComponentEventData evtData;
814       AliHLTComponent::FillEventData(evtData);
815       evtData.fEventID=(AliHLTEventID_t)eventNo;
816       evtData.fBlockCnt=iSourceDataBlock;
817       AliHLTComponentTriggerData trigData;
818       AliHLTUInt32_t size=iOutputDataSize;
819       AliHLTUInt32_t outputBlockCnt=0;
820       AliHLTComponentBlockData* outputBlocks=NULL;
821       AliHLTComponentEventDoneData* edd;
822       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
823         iResult=pComponent->ProcessEvent(evtData, fpBlockDataArray, trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
824         HLTDebug("task %s: component %s ProcessEvent finnished (%d): size=%d blocks=%d", GetName(), pComponent->GetComponentID(), iResult, size, outputBlockCnt);
825         if (iResult>=0 && pTgtBuffer) {
826           iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
827         }
828       } else {
829         HLTError("task %s: no target buffer available", GetName());
830         iResult=-EFAULT;
831       }
832     }
833
834     // now release all buffers which we have subscribed to
835     iSourceDataBlock=0;
836     lnk=subscribedTaskList.FirstLink();
837     while (lnk) {
838       pSrcTask=(AliHLTTask*)lnk->GetObject();
839       if (pSrcTask) {
840         int iTempRes=0;
841         if ((iTempRes=pSrcTask->Release(&fpBlockDataArray[iSourceDataBlock], this))>=0) {
842           HLTDebug("Task %s (%p) successfully released task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
843         } else {
844           HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
845         }
846       } else {
847         HLTFatal("task %s (%p): internal error in ROOT list handling", GetName(), this);
848         if (iResult>=0) iResult=-EFAULT;
849       }
850       subscribedTaskList.Remove(lnk);
851       lnk=subscribedTaskList.FirstLink();
852       iSourceDataBlock++;
853     }
854     if (subscribedTaskList.GetSize()>0) {
855       HLTError("task %s (%p): could not release all data buffers", GetName(), this);
856     }
857   } else {
858     HLTError("task %s (%p): internal failure (not initialized component %p, data buffer %p)", GetName(), this, fpComponent, fpDataBuffer);
859     iResult=-EFAULT;
860   }
861   return iResult;
862 }
863
864 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
865 {
866   int iResult=0;
867   if (pConsumerTask) {
868     if (fpDataBuffer) {
869       iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
870     } else {
871       HLTFatal("internal data buffer missing");
872       iResult=-EFAULT;
873     }
874   } else {
875     iResult=-EINVAL;
876   }
877   return iResult;
878 }
879
880 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
881 {
882   int iResult=0;
883   if (pConsumerTask) {
884     AliHLTComponent* pComponent=GetComponent();
885     if (!pComponent) {
886       // init
887     }
888     if (pComponent) {
889       iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
890     } else {
891       HLTFatal("task initialization failed");
892       iResult=-EFAULT;
893     }
894   } else {
895     iResult=-EINVAL;
896   }
897   return iResult;
898 }
899
900 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockData* pBlockDesc, int iArraySize)
901 {
902   int iResult=0;
903   if (pConsumerTask) {
904     if (fpDataBuffer) {
905       iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), pBlockDesc, iArraySize);
906     } else {
907       HLTFatal("internal data buffer missing");
908       iResult=-EFAULT;
909     }
910   } else {
911     iResult=-EINVAL;
912   }
913   return iResult;
914 }
915
916 int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
917 {
918   int iResult=0;
919   if (pConsumerTask && pBlockDesc) {
920     if (fpDataBuffer) {
921       iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent());
922     } else {
923       HLTFatal("internal data buffer missing");
924       iResult=-EFAULT;
925     }
926   } else {
927     iResult=-EINVAL;
928   }
929   return iResult;
930 }
931
932 /* this function is most likely depricated
933 int AliHLTTask::ClearSourceBlocks()
934 {
935   int iResult=0;
936   return iResult;
937 }
938 */
939
940 void AliHLTTask::PrintStatus()
941 {
942   HLTLogKeyword("task properties");
943   AliHLTComponent* pComponent=GetComponent();
944   if (pComponent) {
945     HLTMessage("     component: %s (%p)", pComponent->GetComponentID(), pComponent);
946   } else {
947     HLTMessage("     no component set!");
948   }
949   if (fpConfiguration) {
950     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
951     while (pSrc) {
952       const char* pQualifier="unresolved";
953       if (FindDependency(pSrc->GetName()))
954         pQualifier="resolved";
955       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
956       pSrc=fpConfiguration->GetNextSource();
957     }
958     TObjLink* lnk = fListTargets.FirstLink();
959     while (lnk) {
960       TObject *obj = lnk->GetObject();
961       HLTMessage("     target: %s", obj->GetName());
962       lnk = lnk->Next();
963     }
964   } else {
965     HLTMessage("     task \"%s\" not initialized", GetName());
966   }
967 }
968
969 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
970
971 TList AliHLTConfigurationHandler::fListConfigurations;
972 TList AliHLTConfigurationHandler::fListDynamicConfigurations;
973
974 /** ROOT macro for the implementation of ROOT specific class methods */
975 ClassImp(AliHLTConfigurationHandler)
976
977 AliHLTConfigurationHandler::AliHLTConfigurationHandler()
978 {
979 }
980
981 AliHLTConfigurationHandler::~AliHLTConfigurationHandler()
982 {
983   TObjLink* lnk=fListDynamicConfigurations.FirstLink();
984   while (lnk) {
985     TObject* obj=lnk->GetObject();
986     if (fListConfigurations.FindObject(obj->GetName())==NULL) {
987       HLTDebug("delete dynamic configuration \"%s\"", obj->GetName());
988       delete obj;
989     }
990     lnk=lnk->Next();
991   }
992 }
993
994 int AliHLTConfigurationHandler::RegisterConfiguration(AliHLTConfiguration* pConf)
995 {
996   int iResult=0;
997   if (pConf) {
998     if (FindConfiguration(pConf->GetName()) == NULL) {
999       fListConfigurations.Add(pConf);
1000       //HLTDebug("configuration \"%s\" registered", pConf->GetName());
1001
1002       // mark all configurations with unresolved dependencies for re-evaluation
1003       TObjLink* lnk=fListConfigurations.FirstLink();
1004       while (lnk) {
1005         AliHLTConfiguration* pSrc=(AliHLTConfiguration*)lnk->GetObject();
1006         if (pSrc && pSrc!=pConf && pSrc->SourcesResolved()!=1) {
1007           pSrc->InvalidateSources();
1008         }
1009         lnk=lnk->Next();
1010       }
1011     } else {
1012       iResult=-EEXIST;
1013       HLTWarning("configuration \"%s\" already registered", pConf->GetName());
1014     }
1015   } else {
1016     iResult=-EINVAL;
1017   }
1018   return iResult;
1019 }
1020
1021 int AliHLTConfigurationHandler::CreateConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
1022 {
1023   int iResult=0;
1024   AliHLTConfiguration* pConf= new AliHLTConfiguration(id, component, sources, arguments);
1025   if (pConf) {
1026     // the configuration will be registered automatically, if this failes the configuration
1027     // is missing -> delete it
1028     if (FindConfiguration(id)==NULL) {
1029       delete pConf;
1030       pConf=NULL;
1031       iResult=-EEXIST;
1032     } else {
1033       fListDynamicConfigurations.Add(pConf);
1034     }
1035   } else {
1036     HLTError("system error: object allocation failed");
1037     iResult=-ENOMEM;
1038   }
1039   return iResult;
1040 }
1041
1042 void AliHLTConfigurationHandler::PrintConfigurations()
1043 {
1044   HLTLogKeyword("configuration listing");
1045   HLTMessage("registered configurations:");
1046   TObjLink *lnk = fListConfigurations.FirstLink();
1047   while (lnk) {
1048     TObject *obj = lnk->GetObject();
1049     HLTMessage("  %s", obj->GetName());
1050     lnk = lnk->Next();
1051   }
1052 }
1053
1054 int AliHLTConfigurationHandler::RemoveConfiguration(const char* id)
1055 {
1056   int iResult=0;
1057   if (id) {
1058     AliHLTConfiguration* pConf=NULL;
1059     if ((pConf=FindConfiguration(id))!=NULL) {
1060       iResult=RemoveConfiguration(pConf);
1061     } else {
1062       HLTWarning("can not find configuration \"%s\"", id);
1063       iResult=-ENOENT;
1064     }
1065   } else {
1066     iResult=-EINVAL;
1067   }
1068   return iResult;
1069 }
1070
1071 int AliHLTConfigurationHandler::RemoveConfiguration(AliHLTConfiguration* pConf)
1072 {
1073   int iResult=0;
1074   if (pConf) {
1075     // remove the configuration from the list
1076     HLTDebug("remove configuration \"%s\"", pConf->GetName());
1077     fListConfigurations.Remove(pConf);
1078     // remove cross links in the remaining configurations
1079     TObjLink* lnk=fListConfigurations.FirstLink();
1080     while (lnk && iResult>=0) {
1081       AliHLTConfiguration* pRem=(AliHLTConfiguration*)lnk->GetObject();
1082       if (pRem) {
1083         pRem->InvalidateSource(pConf);
1084       } else {
1085         iResult=-EFAULT;
1086       }
1087       lnk=lnk->Next();
1088     }
1089   }
1090   return iResult;
1091 }
1092
1093 AliHLTConfiguration* AliHLTConfigurationHandler::FindConfiguration(const char* id)
1094 {
1095   AliHLTConfiguration* pConf=NULL;
1096   if (id) {
1097     pConf=(AliHLTConfiguration*)fListConfigurations.FindObject(id); 
1098   }
1099   return pConf;
1100 }
1101