]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
bugfixes, code cleanup and docu
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
1 // $Id$
2
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   AliHLTSystem.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Implementation of HLT module management.
23 */
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28
29 #include <cassert>
30 #include "AliHLTStdIncludes.h"
31 #include "AliHLTSystem.h"
32 #include "AliHLTComponentHandler.h"
33 #include "AliHLTComponent.h"
34 #include "AliHLTConfiguration.h"
35 #include "AliHLTConfigurationHandler.h"
36 #include "AliHLTTask.h"
37 #include "AliHLTModuleAgent.h"
38 #include "AliHLTOfflineInterface.h"
39 #include "AliHLTDataSource.h"
40 #include "AliHLTOUT.h"
41 #include "AliHLTOUTHandler.h"
42 #include <TObjArray.h>
43 #include <TObjString.h>
44 #include <TStopwatch.h>
45 //#include <TSystem.h>
46 #include <TROOT.h>
47 //#include <TInterpreter.h>
48
49 /** HLT default component libraries */
50 const char* AliHLTSystem::fgkHLTDefaultLibs[]= {
51   "libAliHLTUtil.so", 
52   "libAliHLTRCU.so", 
53   "libAliHLTTPC.so", 
54   //  "libAliHLTSample.so",
55   //"libAliHLTPHOS.so",
56   "libAliHLTMUON.so",
57   "libAliHLTTRD.so",
58   "libAliHLTTrigger.so",
59   NULL
60 };
61
62 /** ROOT macro for the implementation of ROOT specific class methods */
63 ClassImp(AliHLTSystem)
64
65 AliHLTSystem::AliHLTSystem(AliHLTComponentLogSeverity loglevel)
66   :
67   fpComponentHandler(AliHLTComponentHandler::CreateHandler()),
68   fpConfigurationHandler(AliHLTConfigurationHandler::CreateHandler()),
69   fTaskList(),
70   fState(0),
71   fChains(),
72   fStopwatches(new TObjArray),
73   fEventCount(-1),
74   fGoodEvents(-1),
75   fpChainHandlers(NULL),
76   fpEsdHandlers(NULL),
77   fpProprietaryHandlers(NULL)
78 {
79   // see header file for class documentation
80   // or
81   // refer to README to build package
82   // or
83   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
84
85   if (fgNofInstances++>0) {
86     // July 2008: multiple instances are now allowed
87     // AliHLTSystem is used in multiple instances for the kChain HLTOUT handler
88     //HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
89   }
90
91   SetGlobalLoggingLevel(loglevel);
92   SetFrameworkLog(loglevel);
93   if (fpComponentHandler) {
94     AliHLTComponentEnvironment env;
95     memset(&env, 0, sizeof(AliHLTComponentEnvironment));
96     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
97     env.fLoggingFunc=NULL;
98     fpComponentHandler->SetEnvironment(&env);
99     InitAliLogFunc(fpComponentHandler);
100     if (fgNofInstances==1) {
101     fpComponentHandler->AnnounceVersion();
102     }
103   } else {
104     HLTFatal("can not create Component Handler");
105   }
106   if (fpConfigurationHandler) {
107     AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
108   } else {
109     HLTFatal("can not create Configuration Handler");
110   }
111 }
112
113 AliHLTSystem::~AliHLTSystem()
114 {
115   // see header file for class documentation
116   fgNofInstances--;
117   CleanTaskList();
118   AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
119   if (fpConfigurationHandler) {
120     fpConfigurationHandler->Destroy();
121   }
122   fpConfigurationHandler=NULL;
123   
124   if (fpComponentHandler) {
125     fpComponentHandler->Destroy();
126   }
127   fpComponentHandler=NULL;
128 }
129
130 int AliHLTSystem::fgNofInstances=0;
131
132 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
133 {
134   // see header file for class documentation
135   HLTLogKeyword("configuration handling");
136   int iResult=0;
137   if (pConf) {
138     HLTError("function not yet implemented");
139     iResult=-ENOSYS;
140   } else {
141     iResult=-EINVAL;
142   }
143   return iResult;
144 }
145
146 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
147 {
148   // see header file for class documentation
149   HLTLogKeyword("configuration handling");
150   int iResult=0;
151   if (pConf) {
152     if (pPrec) {
153       // find the position
154       HLTError("function not yet implemented");
155       iResult=-ENOSYS;
156     }
157   } else {
158     iResult=-EINVAL;
159   }
160   return iResult;
161 }
162
163 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
164 {
165   // see header file for class documentation
166   HLTLogKeyword("configuration handling");
167   int iResult=0;
168   if (pConf) {
169     HLTError("function not yet implemented");
170     iResult=-ENOSYS;
171   } else {
172     iResult=-EINVAL;
173   }
174   return iResult;
175 }
176
177 int AliHLTSystem::BuildTaskList(const char* id)
178 {
179   // see header file for class documentation
180   int iResult=0;
181   if (id) {
182     if (fpConfigurationHandler) {
183       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(id);
184       if (pConf) {
185         iResult=BuildTaskList(pConf);
186       } else {
187         HLTError("unknown configuration \"%s\"", id);
188         iResult=-EEXIST;
189       }
190     } else {
191       iResult=-EFAULT;
192     }
193   } else {
194     iResult=-EINVAL;
195   }
196   return iResult;
197 }
198
199 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
200 {
201   // see header file for class documentation
202   int iResult=0;
203   if (pConf) {
204     AliHLTTask* pTask=NULL;
205     if ((pTask=FindTask(pConf->GetName()))!=NULL) {
206       if (pTask->GetConf()!=pConf) {
207         HLTError("configuration mismatch, there is already a task with configuration name \"%s\", but it is different. Most likely configuration %p is not registered properly", pConf->GetName(), pConf);
208         iResult=-EEXIST;
209       }
210       // task for this configuration exists, terminate
211       pTask=NULL;
212     } else if (pConf->SourcesResolved(1)!=1) {
213         HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
214         iResult=-ENOLINK;
215     } else {
216       pTask=new AliHLTTask(pConf);
217       if (pTask==NULL) {
218         iResult=-ENOMEM;
219       } else {
220         pTask->SetLocalLoggingLevel(GetLocalLoggingLevel());
221       }
222     }
223     static int iterationLevel=0;
224     if (pTask && iResult>=0) {
225       // check for circular dependencies
226       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
227         HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
228         pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
229         HLTError("aborted ...");
230         iResult=-ELOOP;
231       }
232       if (iResult>=0) {
233         // check whether all dependencies are already in the task list
234         // create the missing ones
235         // this step is an iterative process which calls this function again for the missing
236         // configurations, in order to avoid the currently processed task to be created
237         // again it is added to the list temporarily and removed afterwards
238         // This is of high importance to preserve the order of the tasks. Furthermore, the
239         // InsertTask method has to be used in order to set all the cross links right 
240         fTaskList.Add(pTask);
241         AliHLTConfiguration* pDep=pConf->GetFirstSource();
242         while (pDep!=NULL && iResult>=0) {
243           HLTDebug("iteration %d: checking dependency %s (%p)", iterationLevel, pDep->GetName(), pDep);
244           if (FindTask(pDep->GetName())==NULL) {
245             HLTDebug("iteration %d: building task list for configuration %s (%p)", iterationLevel, pDep->GetName(), pDep);
246             iterationLevel++;
247             iResult=BuildTaskList(pDep);
248             iterationLevel--;
249           }
250           pDep=pConf->GetNextSource();
251         }
252         // remove the temporarily added task
253         fTaskList.Remove(pTask);
254
255         // insert the task and set the cross-links
256         if (iResult>=0) {
257           HLTDebug("iteration %d: inserting task %s (%p)", iterationLevel, pTask->GetName(), pTask);
258           iResult=InsertTask(pTask);
259         }
260       } else {
261         delete pTask;
262         pTask=NULL;
263       }
264     }
265   } else {
266     iResult=-EINVAL;
267   }
268   return iResult;
269 }
270
271 int AliHLTSystem::CleanTaskList()
272 {
273   // see header file for class documentation
274   int iResult=0;
275   TObjLink* lnk=NULL;
276   while ((lnk=fTaskList.LastLink())!=NULL) {
277     delete (lnk->GetObject());
278     fTaskList.Remove(lnk);
279   }
280   return iResult;
281 }
282
283 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
284 {
285   // see header file for class documentation
286   int iResult=0;
287   TObjLink *lnk = NULL;
288   if ((iResult=pTask->CheckDependencies())>0)
289     lnk=fTaskList.FirstLink();
290   while (lnk && iResult>0) {
291     AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
292     //HLTDebug("checking  \"%s\"", pCurr->GetName());
293     iResult=pTask->Depends(pCurr);
294     if (iResult>0) {
295       iResult=pTask->SetDependency(pCurr);
296       pCurr->SetTarget(pTask);
297       HLTDebug("set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
298     }
299     if (pCurr->Depends(pTask)) {
300       // circular dependency
301       HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
302       iResult=-ELOOP;
303     } else if ((iResult=pTask->CheckDependencies())>0) {
304       lnk = lnk->Next();
305     }
306   }
307   if (iResult==0) {
308       if (lnk) {
309         fTaskList.AddAfter(lnk, pTask);
310       } else {
311         fTaskList.AddFirst(pTask);
312       }
313       HLTDebug("task \"%s\" (%p) inserted (size %d)", pTask->GetName(), pTask, sizeof(AliHLTTask));
314   } else if (iResult>0) {
315     HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
316     iResult=-ENOLINK;
317   }
318   return iResult;
319 }
320
321 AliHLTTask* AliHLTSystem::FindTask(const char* id)
322 {
323   // see header file for class documentation
324   AliHLTTask* pTask=NULL;
325   if (id) {
326     pTask=dynamic_cast<AliHLTTask*>(fTaskList.FindObject(id)); 
327   }
328   return pTask;
329 }
330
331 void AliHLTSystem::PrintTaskList()
332 {
333   // see header file for class documentation
334   HLTLogKeyword("task list");
335   TObjLink *lnk = NULL;
336   HLTMessage("Task List");
337   lnk=fTaskList.FirstLink();
338   while (lnk) {
339     TObject* obj=lnk->GetObject();
340     if (obj) {
341       HLTMessage("  %s - status:", obj->GetName());
342       AliHLTTask* pTask=(AliHLTTask*)obj;
343       pTask->PrintStatus();
344     } else {
345     }
346     lnk = lnk->Next();
347   }
348 }
349
350 int AliHLTSystem::Run(Int_t iNofEvents, int bStop)
351 {
352   // see header file for class documentation
353   int iResult=0;
354   int iCount=0;
355   SetStatusFlags(kRunning);
356   if (fEventCount>=0 || (iResult=InitTasks())>=0) {
357     if (fEventCount>=0 || (iResult=StartTasks())>=0) {
358       if (fEventCount==0) {
359         InitBenchmarking(fStopwatches);
360       } else {
361         ResumeBenchmarking(fStopwatches);    
362       }
363       for (int i=fEventCount; i<fEventCount+iNofEvents && iResult>=0; i++) {
364         if ((iResult=ProcessTasks(i))>=0) {
365           fGoodEvents++;
366           iCount++;
367         } else {
368           // TODO: define different running modes to either ignore errors in
369           // event processing or not
370           // currently ignored 
371           iResult=0;
372         }
373       }
374       fEventCount+=iNofEvents;
375       if (bStop) StopTasks();
376       else PauseBenchmarking(fStopwatches);
377     }
378     if (bStop) DeinitTasks();
379   }
380   if (iResult>=0) {
381     iResult=iCount;
382   } else  if (iResult==-126 /*ENOKEY*/) {
383     iResult=0; // do not propagate the error
384   }
385   ClearStatusFlags(kRunning);
386   return iResult;
387 }
388
389 int AliHLTSystem::InitTasks()
390 {
391   // see header file for class documentation
392   int iResult=0;
393   TObjLink *lnk=fTaskList.FirstLink();
394
395   if (lnk==NULL) {
396     HLTWarning("Task list is empty, skipping HLT");
397     return -126 /*ENOKEY*/;
398   }
399   while (lnk && iResult>=0) {
400     TObject* obj=lnk->GetObject();
401     if (obj) {
402       AliHLTTask* pTask=(AliHLTTask*)obj;
403       iResult=pTask->Init(NULL, fpComponentHandler);
404 //       ProcInfo_t ProcInfo;
405 //       gSystem->GetProcInfo(&ProcInfo);
406 //       HLTInfo("task %s initialized (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
407     } else {
408     }
409     lnk = lnk->Next();
410   }
411   if (iResult<0) {
412     HLTError("can not initialize task list, error %d", iResult);
413   }
414
415   return iResult;
416 }
417
418 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
419 {
420   // see header file for class documentation
421   int iResult=0;
422   if (pStopwatches==NULL) return 0;
423
424   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
425     TStopwatch* pStopwatch= new TStopwatch;
426     if (pStopwatch) {
427       pStopwatch->Reset();
428       pStopwatches->AddAt(pStopwatch, i);
429     } else {
430       iResult=-ENOMEM;
431       break;
432     }
433   }
434
435   TObjLink *lnk=fTaskList.FirstLink();
436   while (lnk && iResult>=0) {
437     TObject* obj=lnk->GetObject();
438     if (obj) {
439       AliHLTTask* pTask=(AliHLTTask*)obj;
440       AliHLTComponent* pComp=NULL;
441       if (iResult>=0 && (pComp=pTask->GetComponent())!=NULL) {
442         switch (pComp->GetComponentType()) {
443         case AliHLTComponent::kProcessor:
444           pComp->SetStopwatches(pStopwatches);
445           break;
446         case AliHLTComponent::kSource:
447           {
448             // this switch determines whether the time consumption of the
449             // AliHLTComponent base methods should be counted to the input
450             // stopwatch or base stopwatch.
451             //int inputBase=(int)AliHLTComponent::kSWBase;
452             int inputBase=(int)AliHLTComponent::kSWInput;
453             pComp->SetStopwatch(pStopwatches->At(inputBase), AliHLTComponent::kSWBase);
454             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWInput), AliHLTComponent::kSWDA);
455           }
456           break;
457         case AliHLTComponent::kSink:
458           {
459             // this switch determines whether the time consumption of the
460             // AliHLTComponent base methods should be counted to the output
461             // stopwatch or base stopwatch.
462             //int outputBase=(int)AliHLTComponent::kSWBase;
463             int outputBase=(int)AliHLTComponent::kSWOutput;
464             pComp->SetStopwatch(pStopwatches->At(outputBase), AliHLTComponent::kSWBase);
465             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWOutput), AliHLTComponent::kSWDA);
466           }
467           break;
468         default:
469           HLTWarning("unknown component type %d", (int)pComp->GetComponentType());
470         }
471       }
472     } else {
473     }
474     lnk = lnk->Next();
475   }
476   return iResult;
477 }
478
479 int AliHLTSystem::PauseBenchmarking(TObjArray* pStopwatches) const
480 {
481   // see header file for class documentation
482   if (pStopwatches==NULL) return 0;
483
484   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
485     if (!pStopwatches->At(i)) continue;
486     TStopwatch* pSw=dynamic_cast<TStopwatch*>(pStopwatches->At(i));
487     if (pSw) pSw->Stop();
488   }
489   return 0;
490 }
491
492 int AliHLTSystem::ResumeBenchmarking(TObjArray* pStopwatches) const
493 {
494   // see header file for class documentation
495   if (pStopwatches==NULL) return 0;
496
497   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
498     if (!pStopwatches->At(i)) continue;
499     TStopwatch* pSw=dynamic_cast<TStopwatch*>(pStopwatches->At(i));
500     if (pSw) pSw->Continue();
501   }
502   return 0;
503 }
504
505 int AliHLTSystem::PrintBenchmarking(TObjArray* pStopwatches, int bClean) const
506 {
507   // see header file for class documentation
508   int iInitialized=1;
509   if (pStopwatches==NULL) return 0;
510
511   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
512     if (!dynamic_cast<TStopwatch*>(pStopwatches->At(i))) {
513       iInitialized=0;
514       break;
515     }
516   }
517
518   if (iInitialized!=0) {
519     HLTImportant("HLT statistics:\n"
520             "    base:              R:%.3fs C:%.3fs\n"
521             "    input:             R:%.3fs C:%.3fs\n"
522             "    output:            R:%.3fs C:%.3fs\n"
523             "    event processing : R:%.3fs C:%.3fs"
524             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->RealTime()
525             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->CpuTime()
526             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->RealTime()
527             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->CpuTime()
528             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->RealTime()
529             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->CpuTime()
530             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->RealTime()
531             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->CpuTime()
532             );
533   }
534
535   if (bClean) {
536     for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
537       TObject* pObj=pStopwatches->RemoveAt(i);
538       if (pObj) delete pObj;
539     }
540   }
541   return 0;
542 }
543
544 int AliHLTSystem::StartTasks()
545 {
546   // see header file for class documentation
547   int iResult=0;
548   TObjLink *lnk=fTaskList.FirstLink();
549   while (lnk && iResult>=0) {
550     TObject* obj=lnk->GetObject();
551     if (obj) {
552       AliHLTTask* pTask=(AliHLTTask*)obj;
553       iResult=pTask->StartRun();
554 //       ProcInfo_t ProcInfo;
555 //       gSystem->GetProcInfo(&ProcInfo);
556 //       HLTInfo("task %s started (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
557     } else {
558     }
559     lnk = lnk->Next();
560   }
561   if (iResult<0) {
562     HLTError("can not start task list, error %d", iResult);
563   } else {
564     SetStatusFlags(kStarted);
565     fEventCount=0;
566     fGoodEvents=0;
567     if ((iResult=SendControlEvent(kAliHLTDataTypeSOR))<0) {
568       HLTError("can not send SOR event");
569     }
570   }
571   return iResult;
572 }
573
574 int AliHLTSystem::ProcessTasks(Int_t eventNo)
575 {
576   // see header file for class documentation
577   int iResult=0;
578   HLTDebug("processing event no %d", eventNo);
579   TObjLink *lnk=fTaskList.FirstLink();
580   while (lnk && iResult>=0) {
581     TObject* obj=lnk->GetObject();
582     if (obj) {
583       AliHLTTask* pTask=(AliHLTTask*)obj;
584       iResult=pTask->ProcessTask(eventNo);
585 //       ProcInfo_t ProcInfo;
586 //       gSystem->GetProcInfo(&ProcInfo);
587 //       HLTInfo("task %s processed (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
588     } else {
589     }
590     lnk = lnk->Next();
591   }
592
593   if (iResult>=0) {
594     HLTImportant("Event %d successfully finished (%d)", eventNo, iResult);
595     iResult=0;
596   } else {
597     HLTError("Processing of event %d failed (%d)", eventNo, iResult);
598   }
599
600   return iResult;
601 }
602
603 int AliHLTSystem::StopTasks()
604 {
605   // see header file for class documentation
606   int iResult=0;
607   if ((iResult=SendControlEvent(kAliHLTDataTypeEOR))<0) {
608     HLTError("can not send EOR event");
609   }
610   TObjLink *lnk=fTaskList.FirstLink();
611   while (lnk) {
612     TObject* obj=lnk->GetObject();
613     if (obj) {
614       AliHLTTask* pTask=(AliHLTTask*)obj;
615       int locResult=pTask->EndRun();
616       if (iResult>=0 && locResult<0) iResult=locResult;
617 //       ProcInfo_t ProcInfo;
618 //       gSystem->GetProcInfo(&ProcInfo);
619 //       HLTInfo("task %s stopped (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
620     } else {
621     }
622     lnk = lnk->Next();
623   }
624   PrintBenchmarking(fStopwatches, 1 /*clean*/);
625   ClearStatusFlags(kStarted);
626   return iResult;
627 }
628
629 int AliHLTSystem::SendControlEvent(AliHLTComponentDataType dt)
630 {
631   // see header file for class documentation
632
633   // disabled for the moment
634   return 0;
635
636   int iResult=0;
637   AliHLTRunDesc runDesc;
638   memset(&runDesc, 0, sizeof(AliHLTRunDesc));
639   runDesc.fStructSize=sizeof(AliHLTRunDesc);
640   AliHLTDataSource::AliSpecialEventGuard g(&runDesc, dt, kAliHLTVoidDataSpec);
641   HLTDebug("sending event %s, run descriptor %p", AliHLTComponent::DataType2Text(dt).c_str(), &runDesc);
642   TObjLink *lnk=fTaskList.FirstLink();
643   while (lnk && iResult>=0) {
644     TObject* obj=lnk->GetObject();
645     if (obj) {
646       AliHLTTask* pTask=(AliHLTTask*)obj;
647       iResult=pTask->ProcessTask(-1);
648     } else {
649     }
650     lnk = lnk->Next();
651   }
652   HLTDebug("event %s done (%d)", AliHLTComponent::DataType2Text(dt).c_str(), iResult);
653   return iResult;
654 }
655
656 int AliHLTSystem::DeinitTasks()
657 {
658   // see header file for class documentation
659   int iResult=0;
660   TObjLink *lnk=fTaskList.FirstLink();
661   while (lnk && iResult>=0) {
662     TObject* obj=lnk->GetObject();
663     if (obj) {
664       AliHLTTask* pTask=(AliHLTTask*)obj;
665       iResult=pTask->Deinit();
666 //       ProcInfo_t ProcInfo;
667 //       gSystem->GetProcInfo(&ProcInfo);
668 //       HLTInfo("task %s cleaned (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
669     } else {
670     }
671     lnk = lnk->Next();
672   }
673   fEventCount=-1;
674   fGoodEvents=-1;
675
676   return iResult;
677 }
678
679 void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
680 {
681   // see header file for class documentation
682   void* p=NULL;
683   try {
684     p=(void*)new char[size];
685   }
686   catch (...) {
687     AliHLTLogging log;
688     log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
689   }
690   return p;
691 }
692
693 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
694                               AliRawReader* rawReader)
695 {
696   // see header file for class documentation
697   int iResult=0;
698   if (runLoader || rawReader || nofEvents==0) {
699     if (nofEvents>0) {HLTInfo("Run Loader %p, Raw Reader %p , %d event(s)", runLoader, rawReader, nofEvents);}
700     if (CheckStatus(kReady)) {
701       if (nofEvents==0) {
702         // special case to close the reconstruction
703         if (!CheckStatus(kError)) {
704         StopTasks();
705         DeinitTasks();
706         }
707       } else {
708       if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
709         // the system always remains started after event processing, a specific
710         // call with nofEvents==0 is needed to execute the stop sequence
711         if ((iResult=Run(nofEvents, 0))<0) SetStatusFlags(kError);
712       }
713       }
714     } else {
715       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
716     }
717   } else {
718     HLTError("missing RunLoader (%p)/RawReader (%p) instance", runLoader, rawReader);
719     iResult=-EINVAL;
720   }
721   return iResult;
722 }
723
724 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
725 {
726   // see header file for class documentation
727   int iResult=0;
728   if (runLoader || esd) {
729     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
730     iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
731   } else {
732     HLTError("missing run loader/ESD instance(s)");
733     iResult=-EINVAL;
734   }
735   return iResult;
736 }
737
738 int AliHLTSystem::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd)
739 {
740   // see header file for class documentation
741   int iResult=0;
742   if (!pHLTOUT) return -EINVAL;
743   HLTDebug("processing %d HLT data blocks", pHLTOUT->GetNofDataBlocks());
744
745   //
746   // process all kChain handlers first
747   //
748   if ((iResult=ProcessHLTOUTkChain(pHLTOUT))<0) {
749     HLTWarning("Processing of kChain-type data blocks failed with error code %d", iResult);
750     iResult=0;
751   } 
752
753   if (!fpEsdHandlers)
754     fpEsdHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
755   if (!fpProprietaryHandlers)
756     fpProprietaryHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
757
758   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pEsdHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpEsdHandlers);
759   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pProprietaryHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpProprietaryHandlers);
760   if (!pEsdHandlers || !pProprietaryHandlers) return -ENOMEM;
761
762   // invalidate all blocks
763   AliHLTOUT::InvalidateBlocks(*pEsdHandlers);
764   AliHLTOUT::InvalidateBlocks(*pProprietaryHandlers);
765
766   // first come first serve: the ESD of the first handler is also filled into
767   // the main ESD. Has to be changed later.
768   // currently, merging to the provided ESDs crashes at the level of the
769   // TTree::Fill in AliReconstruction, furthermore, the wrong ESD is passed
770   // by the framework
771   AliESDEvent* pMasterESD=NULL;
772   pMasterESD=esd;
773
774   AliHLTComponentDataTypeList esdBlocks;
775
776   for (iResult=pHLTOUT->SelectFirstDataBlock();
777        iResult>=0;
778        iResult=pHLTOUT->SelectNextDataBlock()) {
779     AliHLTComponentDataType dt=kAliHLTVoidDataType;
780     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
781     pHLTOUT->GetDataBlockDescription(dt, spec);
782     AliHLTOUTHandler* pHandler=pHLTOUT->GetHandler();
783     AliHLTModuleAgent::AliHLTOUTHandlerType handlerType=pHLTOUT->GetDataBlockHandlerType();
784
785     // default handling for ESD data blocks does not require an explicite handler
786     if (!pHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
787       handlerType=AliHLTModuleAgent::kEsd;
788     }
789     const char* pMsg="invalid";
790     switch (handlerType) {
791     case AliHLTModuleAgent::kEsd:
792       {
793         if (pHandler) {
794           // schedule for later processing
795           pHLTOUT->InsertHandler(*pEsdHandlers, pHLTOUT->GetDataBlockHandlerDesc());
796         } else {
797           AliHLTComponentDataTypeList::iterator element=esdBlocks.begin();
798           for (; element!=esdBlocks.end(); element++) {
799             if (*element==dt) {
800               HLTWarning("multiple ESDs of identical data type %s, please add appropriate handler to merge ESDs", AliHLTComponent::DataType2Text(dt).c_str());
801               break;
802             }
803           }
804           if (element==esdBlocks.end()) esdBlocks.push_back(dt);
805
806           // write directly
807           const AliHLTUInt8_t* pBuffer=NULL;
808           AliHLTUInt32_t size=0;
809           if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
810             pHLTOUT->WriteESD(pBuffer, size, dt);
811             if (pMasterESD) {
812               pHLTOUT->WriteESD(pBuffer, size, dt, pMasterESD);
813               pMasterESD=NULL;
814             }
815             pHLTOUT->ReleaseDataBuffer(pBuffer);
816           }
817           pHLTOUT->MarkDataBlockProcessed();
818         }
819       }
820       break;
821     case AliHLTModuleAgent::kRawReader:
822       // handled in the AliRawReaderHLT
823       break;
824     case AliHLTModuleAgent::kRawStream:
825       HLTWarning("HLTOUT handler type 'kRawStream' not yet implemented: agent %s, data type %s, specification %#x",
826                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
827                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
828       break;
829     case AliHLTModuleAgent::kChain:
830       HLTWarning("HLTOUT handler type 'kChain' has already been processed: agent %s, data type %s, specification %#x\n"
831                  "New block of this type added by the chain? Skipping data block ...",
832                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
833                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
834       break;
835     case AliHLTModuleAgent::kProprietary:
836       HLTDebug("processing proprietary data: agent %s, data type %s, specification %#x",
837                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
838                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
839       if (pHandler) {
840         AliHLTOUT::AliHLTOUTLockGuard g(pHLTOUT);
841         int res=pHandler->ProcessData(pHLTOUT);
842         if (res<0) {
843           HLTWarning("processing proprietary data failed (%d): agent %s, data type %s, specification %#x",
844                      res, pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
845                      AliHLTComponent::DataType2Text(dt).c_str(), spec);
846         }
847       }
848       break;
849     case AliHLTModuleAgent::kUnknownOutput:
850       pMsg="unknown";
851       // fall trough intended
852     default:
853       HLTWarning("%s handler type: agent %s, data type %s, specification %#x, ... skipping data block",
854                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
855                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
856     }
857   }
858   // TODO: the return value of SelectFirst/NextDataBlock must be
859   // changed in order to avoid this check
860   if (iResult==-ENOENT) iResult=0;
861
862   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator handler;
863
864   // process and write all esd data blocks
865   for (handler=pEsdHandlers->begin(); handler!=pEsdHandlers->end() && iResult>=0; handler++) {
866     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*handler));     
867     AliHLTOUTHandler* pHandler=*handler;
868     const AliHLTUInt8_t* pBuffer=NULL;
869     AliHLTUInt32_t size=0;
870     pHandler->ProcessData(pHLTOUT);
871     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
872       AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*handler;
873       AliHLTComponentDataType dt=desc;
874       pHLTOUT->WriteESD(pBuffer, size, dt);
875       if (pMasterESD) {
876         pHLTOUT->WriteESD(pBuffer, size, dt, pMasterESD);
877         pMasterESD=NULL;
878       }
879       pHandler->ReleaseProcessedData(pBuffer, size);
880     }
881     pHLTOUT->MarkDataBlocksProcessed(&(*handler));
882   }
883
884   // process all kProprietary data blocks
885   for (handler=pProprietaryHandlers->begin(); handler!=pProprietaryHandlers->end() && iResult>=0; handler++) {
886     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*handler));     
887     AliHLTOUTHandler* pHandler=*handler;
888     const AliHLTUInt8_t* pBuffer=NULL;
889     AliHLTUInt32_t size=0;
890     pHandler->ProcessData(pHLTOUT);
891     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
892       HLTWarning("data produced by kProprietary handler ignored");
893       pHandler->ReleaseProcessedData(pBuffer, size);
894     }
895     pHLTOUT->MarkDataBlocksProcessed(&(*handler));
896   }
897
898   // remove all empty handlers form the list (handlers which did not get a block this time)
899   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pEsdHandlers);
900   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pProprietaryHandlers);
901
902   return iResult;
903 }
904
905 int AliHLTSystem::ProcessHLTOUTkChain(AliHLTOUT* pHLTOUT)
906 {
907   // see header file for class documentation
908   int iResult=0;
909   if (!pHLTOUT) return -EINVAL;
910
911   if (!fpChainHandlers)
912     fpChainHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
913
914   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pChainHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpChainHandlers);
915   if (!pChainHandlers) return -ENOMEM;
916
917   // invalidate all blocks
918   AliHLTOUT::InvalidateBlocks(*pChainHandlers);
919
920   // fill the list
921   pHLTOUT->FillHandlerList(*pChainHandlers, AliHLTModuleAgent::kChain);
922
923   // process all defined chain handlers
924   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator chainHandler;
925   for (chainHandler=pChainHandlers->begin(); chainHandler!=pChainHandlers->end() && iResult>=0; chainHandler++) {
926     if (chainHandler->IsEmpty()) continue;
927     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*chainHandler));        
928     AliHLTOUTHandler* pHandler=*chainHandler;
929     const AliHLTUInt8_t* pBuffer=NULL;
930     AliHLTUInt32_t size=0;
931     pHandler->ProcessData(pHLTOUT);
932     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
933       AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*chainHandler;
934       AliHLTComponentDataType dt=desc;
935
936       pHandler->ReleaseProcessedData(pBuffer, size);
937     }
938     pHLTOUT->MarkDataBlocksProcessed(&(*chainHandler));
939   }
940
941   // remove all empty handlers form the list (handlers which did not get a block this time)
942   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pChainHandlers);
943
944   return iResult;
945 }
946
947 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
948 {
949   // see header file for class documentation
950   int iResult=0;
951   if (libraries) {
952     if (fpComponentHandler) {
953       TString libs(libraries);
954       TObjArray* pTokens=libs.Tokenize(" ");
955       if (pTokens) {
956         int iEntries=pTokens->GetEntries();
957         for (int i=0; i<iEntries && iResult>=0; i++) {
958           iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
959         }
960         delete pTokens;
961       }
962       if (iResult>=0) {
963         SetStatusFlags(kLibrariesLoaded);
964       } else {
965         // lets see if we need this, probably not
966         //fpComponentHandler->UnloadLibraries();
967         ClearStatusFlags(kLibrariesLoaded);
968       }
969     } else {
970       iResult=-EFAULT;
971       HLTFatal("no component handler available");
972     }
973   } else {
974     iResult=-EINVAL;
975   }
976   return iResult;
977 }
978
979 int AliHLTSystem::Configure(AliRunLoader* runloader)
980 {
981   // see header file for class documentation
982   return Configure(NULL, runloader);
983 }
984
985 int AliHLTSystem::Configure(AliRawReader* rawReader, AliRunLoader* runloader)
986 {
987   // see header file for class documentation
988   int iResult=0;
989   if (CheckStatus(kRunning)) {
990     HLTError("HLT system in running state, can not configure");
991     return -EBUSY;
992   }
993   ClearStatusFlags(kTaskListCreated);
994   if (CheckFilter(kHLTLogDebug))
995     AliHLTModuleAgent::PrintStatus();
996   if (CheckStatus(kConfigurationLoaded)==0) {
997     iResult=LoadConfigurations(rawReader, runloader);
998   } else {
999     if (fChains.Length()==0) {
1000       HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'chains=<chain,...>\' option");
1001       iResult=-ENOENT;
1002     }
1003   }
1004   if (iResult>=0) {
1005     SetStatusFlags(kConfigurationLoaded);
1006     if (CheckFilter(kHLTLogDebug))
1007       fpConfigurationHandler->PrintConfigurations();
1008     iResult=BuildTaskListsFromReconstructionChains(rawReader, runloader);
1009     if (iResult>=0) {
1010       SetStatusFlags(kTaskListCreated);
1011     }
1012   }
1013   if (iResult<0) SetStatusFlags(kError);
1014   
1015   return iResult;
1016 }
1017
1018 int AliHLTSystem::ScanOptions(const char* options)
1019 {
1020   // see header file for class documentation
1021   int iResult=0;
1022   if (options) {
1023     //AliHLTComponentHandler::TLibraryMode libMode=AliHLTComponentHandler::kDynamic;
1024     TString libs("");
1025     TString alloptions(options);
1026     TObjArray* pTokens=alloptions.Tokenize(" ");
1027     if (pTokens) {
1028       int iEntries=pTokens->GetEntries();
1029       for (int i=0; i<iEntries; i++) {
1030         TString token=(((TObjString*)pTokens->At(i))->GetString());
1031         if (token.Contains("loglevel=")) {
1032           TString param=token.ReplaceAll("loglevel=", "");
1033           if (param.IsDigit()) {
1034             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
1035           } else if (param.BeginsWith("0x") &&
1036                      param.Replace(0,2,"",0).IsHex()) {
1037             int severity=0;
1038             sscanf(param.Data(),"%x", &severity);
1039             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
1040           } else {
1041             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
1042           }
1043         } else if (token.Contains("frameworklog=")) {
1044           TString param=token.ReplaceAll("frameworklog=", "");
1045           if (param.IsDigit()) {
1046             SetFrameworkLog((AliHLTComponentLogSeverity)param.Atoi());
1047           } else if (param.BeginsWith("0x") &&
1048                      param.Replace(0,2,"",0).IsHex()) {
1049             int severity=0;
1050             sscanf(param.Data(),"%x", &severity);
1051             SetFrameworkLog((AliHLTComponentLogSeverity)severity);
1052           } else {
1053             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
1054           }
1055         } else if (token.Contains("alilog=off")) {
1056           SwitchAliLog(0);
1057         } else if (token.Contains("config=")) {
1058           TString param=token.ReplaceAll("config=", "");
1059           Int_t error=0;
1060           gROOT->Macro(param.Data(), &error);
1061           if (error==0) {
1062             SetStatusFlags(kConfigurationLoaded);
1063           } else {
1064             HLTError("can not execute macro \'%s\'", param.Data());
1065             iResult=-EBADF;
1066           }
1067         } else if (token.Contains("chains=")) {
1068           TString param=token.ReplaceAll("chains=", "");
1069           fChains=param.ReplaceAll(",", " ");
1070           if (fChains.IsNull()) fChains=" "; // disable all chains
1071         } else if (token.Contains("libmode=")) {
1072           TString param=token.ReplaceAll("libmode=", "");
1073           param.ReplaceAll(",", " ");
1074           if (fpComponentHandler) {
1075             if (param.CompareTo("static")==0) {
1076               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kStatic);
1077             } else if (param.CompareTo("dynamic")==0) {
1078               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kDynamic);
1079             } else {
1080               HLTWarning("wrong argument for option \'libmode=\', use \'static\' or \'dynamic\'");
1081             }
1082           }
1083         } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
1084           libs+=token;
1085           libs+=" ";
1086         } else {
1087           HLTWarning("unknown option \'%s\'", token.Data());
1088         }
1089       }
1090       delete pTokens;
1091     }
1092
1093     if (iResult>=0) {
1094       if (libs.IsNull()) {
1095         const char** deflib=fgkHLTDefaultLibs;
1096         while (*deflib) {
1097           libs+=*deflib++;
1098           libs+=" ";
1099         }
1100       }
1101       if ((!CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
1102           (LoadComponentLibraries(libs.Data())<0)) {
1103         HLTError("error while loading HLT libraries");
1104         iResult=-EFAULT;
1105       }
1106     }
1107   }
1108   return iResult;
1109 }
1110
1111 int AliHLTSystem::Reset(int bForce)
1112 {
1113   // see header file for class documentation
1114   int iResult=0;
1115   if (!bForce && CheckStatus(kRunning)) {
1116     HLTError("HLT system in running state, can not configure");
1117     return -EBUSY;
1118   }
1119   CleanTaskList();
1120   ClearStatusFlags(~kUninitialized);
1121   return iResult;
1122 }
1123
1124 int AliHLTSystem::LoadConfigurations(AliRawReader* rawReader, AliRunLoader* runloader)
1125 {
1126   // see header file for class documentation
1127   if (CheckStatus(kRunning)) {
1128     HLTError("HLT system in running state, can not configure");
1129     return -EBUSY;
1130   }
1131   int iResult=0;
1132   AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
1133   TString extralibs;
1134   while (pAgent && iResult>=0) {
1135     const char* deplibs=pAgent->GetRequiredComponentLibraries();
1136     if (deplibs) {
1137       HLTDebug("required libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
1138       extralibs+=deplibs;
1139     }
1140     if (iResult>=0) {
1141       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
1142       pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
1143       pAgent=AliHLTModuleAgent::GetNextAgent();
1144     }
1145   }
1146   if (iResult>=0) {
1147     iResult=LoadComponentLibraries(extralibs.Data());
1148   }
1149
1150   return iResult;
1151 }
1152
1153 int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
1154 {
1155   // see header file for class documentation
1156   if (CheckStatus(kRunning)) {
1157     HLTError("HLT system in running state, can not configure");
1158     return -EBUSY;
1159   }
1160   if (!CheckStatus(kConfigurationLoaded)) {
1161     HLTWarning("configurations not yet loaded");
1162     return 0;
1163   }
1164
1165   int iResult=0;
1166   int bHaveOutput=0;
1167
1168   // query chains
1169   TString chains;
1170   if (fChains.Length()>0) {
1171     chains=fChains;
1172     HLTImportant("custom reconstruction chain: %s", chains.Data());
1173   } else {
1174     AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
1175     while ((pAgent || fChains.Length()>0) && iResult>=0) {
1176       const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
1177       if (agentchains) {
1178         if (!chains.IsNull()) chains+=" ";
1179         chains+=agentchains;
1180         HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
1181       }
1182       pAgent=AliHLTModuleAgent::GetNextAgent();
1183     }
1184   }
1185
1186   // build task list for chains
1187   TObjArray* pTokens=chains.Tokenize(" ");
1188   if (pTokens) {
1189     int iEntries=pTokens->GetEntries();
1190     for (int i=0; i<iEntries && iResult>=0; i++) {
1191       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
1192       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
1193       if (pConf) {
1194         iResult=BuildTaskList(pConf);
1195         if (runloader) {
1196           assert(fpComponentHandler!=NULL);
1197           TString cid=pConf->GetComponentID();
1198           if (cid.CompareTo("HLTOUT")==0) {
1199             // remove from the input of a global HLTOUT configuration
1200             chains.ReplaceAll(pCID, "");
1201           } else if (bHaveOutput==0) {
1202             // check whether this configuration produces data output
1203             if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
1204               bHaveOutput=0;
1205               chains.ReplaceAll(pCID, "");
1206             }
1207           }
1208         }
1209       } else {
1210         HLTWarning("can not find configuration %s", pCID);
1211       }
1212     }
1213     delete pTokens;
1214   }
1215
1216   // build HLTOUT for simulation
1217   if (iResult>=0 && runloader) {
1218     if (bHaveOutput) {
1219       // there are components in the chain which produce data which need to be
1220       // piped to an HLTOUT
1221       if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
1222           fpComponentHandler->LoadLibrary("libHLTsim.so")>=0) {
1223         AliHLTConfiguration globalout("_globalout_", "HLTOUT", chains.Data(), NULL);
1224         iResult=BuildTaskList("_globalout_");
1225       } else {
1226         HLTError("can not load libHLTsim.so and HLTOUT component");
1227         iResult=-EFAULT;
1228       }
1229     }
1230   }
1231
1232   if (iResult>=0) SetStatusFlags(kTaskListCreated);
1233
1234   return iResult;
1235 }
1236
1237 int AliHLTSystem::CheckStatus(int flag)
1238 {
1239   // see header file for class documentation
1240   if (flag==kUninitialized && flag==fState) return 1;
1241   if ((fState&flag)==flag) return 1;
1242   return 0;
1243 }
1244
1245 int AliHLTSystem::GetStatusFlags()
1246 {
1247   // see header file for class documentation
1248   return fState;
1249 }
1250
1251 int AliHLTSystem::SetStatusFlags(int flags)
1252 {
1253   // see header file for class documentation
1254   fState|=flags;
1255   return fState;
1256 }
1257
1258 int AliHLTSystem::ClearStatusFlags(int flags)
1259 {
1260   // see header file for class documentation
1261   fState&=~flags;
1262   return fState;
1263 }
1264
1265 void* AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
1266 {
1267   // see header file for class documentation
1268   if (fpComponentHandler==NULL) return NULL;
1269   return fpComponentHandler->FindSymbol(library, symbol);
1270 }
1271
1272 void AliHLTSystem::SetFrameworkLog(AliHLTComponentLogSeverity level) 
1273 {
1274   // see header file for class documentation
1275   SetLocalLoggingLevel(level);
1276   if (fpComponentHandler) fpComponentHandler->SetLocalLoggingLevel(level);
1277   if (fpConfigurationHandler) fpConfigurationHandler->SetLocalLoggingLevel(level);
1278 }