]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
222605ab231ef988f3b01dfe275ce6ccc6fffd17
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
1 // $Id$
2 //**************************************************************************
3 //* This file is property of and copyright by the                          * 
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   AliHLTSystem.cxx
19 /// @author Matthias Richter
20 /// @date   
21 /// @brief  Implementation of HLT module management.
22 ///
23
24 #include <cassert>
25 #include "AliHLTStdIncludes.h"
26 #include "AliHLTSystem.h"
27 #include "AliHLTComponentHandler.h"
28 #include "AliHLTComponent.h"
29 #include "AliHLTConfiguration.h"
30 #include "AliHLTConfigurationHandler.h"
31 #include "AliHLTOnlineConfiguration.h"
32 #include "AliHLTTask.h"
33 #include "AliHLTModuleAgent.h"
34 #include "AliHLTOfflineInterface.h"
35 #include "AliHLTDataSource.h"
36 #include "AliHLTOUT.h"
37 #include "AliHLTOUTHandler.h"
38 #include "AliHLTOUTTask.h"
39 #include "AliHLTControlTask.h"
40 #include "AliHLTDataBuffer.h"
41 #include "AliHLTMisc.h"
42 #include <TObjArray.h>
43 #include <TObjString.h>
44 #include <TStopwatch.h>
45 #include <TList.h>
46 //#include <TSystem.h>
47 #include <TROOT.h>
48 //#include <TInterpreter.h>
49
50 /** HLT default component libraries */
51 const char* AliHLTSystem::fgkHLTDefaultLibs[]= {
52   "libAliHLTUtil.so", 
53   "libAliHLTRCU.so", 
54   "libAliHLTTPC.so", 
55   //  "libAliHLTSample.so",
56   "libAliHLTCalo.so",
57   "libAliHLTEMCAL.so",
58   "libAliHLTPHOS.so",
59   "libAliHLTMUON.so",
60   "libAliHLTTRD.so",
61   "libAliHLTITS.so",
62   "libAliHLTVZERO.so",
63   "libAliHLTZDC.so",
64   "libAliHLTGlobal.so",
65   "libAliHLTTrigger.so",
66   NULL
67 };
68
69 /** ROOT macro for the implementation of ROOT specific class methods */
70 ClassImp(AliHLTSystem)
71
72 AliHLTSystem::AliHLTSystem(AliHLTComponentLogSeverity loglevel, const char* name,
73                            AliHLTComponentHandler* pCompHandler,
74                            AliHLTConfigurationHandler* pConfHandler
75                            )
76   : fpComponentHandler(pCompHandler==NULL?AliHLTComponentHandler::CreateHandler():pCompHandler)
77   , fpConfigurationHandler(pConfHandler==NULL?AliHLTConfigurationHandler::CreateHandler():pConfHandler),
78   fTaskList(),
79   fState(0),
80   fChains(),
81   fStopwatches(new TObjArray),
82   fEventCount(-1),
83   fGoodEvents(-1),
84   fpChainHandlers(NULL),
85   fpEsdHandlers(NULL),
86   fpProprietaryHandlers(NULL),
87   fpHLTOUTTask(NULL),
88   fpHLTOUT(NULL),
89   fHLTOUTUse(0),
90   fpControlTask(NULL),
91   fName(name)
92   , fECSParams()
93   , fUseHLTOUTComponentTypeGlobal(true)
94   , fDetMask(0)
95 {
96   // see header file for class documentation
97   // or
98   // refer to README to build package
99   // or
100   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
101
102   if (fgNofInstances++>0) {
103     // July 2008: multiple instances are now allowed
104     // AliHLTSystem is used in multiple instances for the kChain HLTOUT handler
105     //HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
106   }
107
108   SetGlobalLoggingLevel(loglevel);
109   SetFrameworkLog(loglevel);
110   if (fpComponentHandler) {
111     AliHLTAnalysisEnvironment env;
112     memset(&env, 0, sizeof(AliHLTAnalysisEnvironment));
113     env.fStructSize=sizeof(AliHLTAnalysisEnvironment);
114     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
115     env.fGetEventDoneDataFunc=AliHLTSystem::AllocEventDoneData;
116     env.fLoggingFunc=NULL;
117     fpComponentHandler->SetEnvironment(&env);
118     InitAliLogFunc(fpComponentHandler);
119     if (fgNofInstances==1) {
120     fpComponentHandler->AnnounceVersion();
121     }
122   } else {
123     HLTFatal("can not create Component Handler");
124   }
125   if (fpConfigurationHandler==NULL) {
126     HLTFatal("can not create Configuration Handler");
127   }
128 }
129
130 AliHLTSystem::~AliHLTSystem()
131 {
132   // see header file for class documentation
133   fgNofInstances--;
134   CleanupHLTOUTHandlers();
135   CleanTaskList();
136   if (fpConfigurationHandler) {
137     fpConfigurationHandler->Destroy();
138   }
139   fpConfigurationHandler=NULL;
140   
141   if (fpComponentHandler) {
142     fpComponentHandler->Destroy();
143   }
144   fpComponentHandler=NULL;
145   delete fStopwatches;
146
147   // note: fpHLTOUTTask and fpControlTask are deleted by
148   // CleanTaskList
149 }
150
151 int AliHLTSystem::fgNofInstances=0;
152
153 int AliHLTSystem::BuildTaskList(const char* id)
154 {
155   // see header file for class documentation
156   int iResult=0;
157   if (id) {
158     if (fpConfigurationHandler) {
159       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(id);
160       if (pConf) {
161         iResult=BuildTaskList(pConf);
162       } else {
163         HLTError("unknown configuration \"%s\"", id);
164         iResult=-EEXIST;
165       }
166     } else {
167       iResult=-EFAULT;
168     }
169   } else {
170     iResult=-EINVAL;
171   }
172   return iResult;
173 }
174
175 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
176 {
177   // see header file for class documentation
178   int iResult=0;
179   if (pConf) {
180     AliHLTTask* pTask=NULL;
181     if ((pTask=FindTask(pConf->GetName()))!=NULL) {
182       if (pTask->GetConf()!=pConf) {
183         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);
184         iResult=-EEXIST;
185       }
186       // task for this configuration exists, terminate
187       pTask=NULL;
188     // check first if the configuration has all sources resolved, try to extract otherwise
189     } else if (pConf->SourcesResolved()!=1 && pConf->ExtractSources(fpConfigurationHandler)!=1) {
190         HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
191         iResult=-ENOLINK;
192     } else {
193       pTask=new AliHLTTask(pConf);
194       if (pTask==NULL) {
195         iResult=-ENOMEM;
196       } else {
197         pTask->SetLocalLoggingLevel(GetLocalLoggingLevel());
198       }
199     }
200     static int iterationLevel=0;
201     if (pTask && iResult>=0) {
202       // check for circular dependencies
203       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
204         HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
205         pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
206         HLTError("aborted ...");
207         iResult=-ELOOP;
208       }
209       if (iResult>=0) {
210         // check whether all dependencies are already in the task list
211         // create the missing ones
212         // this step is an iterative process which calls this function again for the missing
213         // configurations, in order to avoid the currently processed task to be created
214         // again it is added to the list temporarily and removed afterwards
215         // This is of high importance to preserve the order of the tasks. Furthermore, the
216         // InsertTask method has to be used in order to set all the cross links right 
217         fTaskList.Add(pTask);
218         AliHLTConfiguration* pDep=pConf->GetFirstSource();
219         while (pDep!=NULL && iResult>=0) {
220           HLTDebug("iteration %d: checking dependency %s (%p)", iterationLevel, pDep->GetName(), pDep);
221           if (FindTask(pDep->GetName())==NULL) {
222             HLTDebug("iteration %d: building task list for configuration %s (%p)", iterationLevel, pDep->GetName(), pDep);
223             iterationLevel++;
224             iResult=BuildTaskList(pDep);
225             iterationLevel--;
226           }
227           pDep=pConf->GetNextSource();
228         }
229         // remove the temporarily added task
230         fTaskList.Remove(pTask);
231
232         // insert the task and set the cross-links
233         if (iResult>=0) {
234           HLTDebug("iteration %d: inserting task %s (%p)", iterationLevel, pTask->GetName(), pTask);
235           iResult=InsertTask(pTask);
236         }
237       } else {
238         delete pTask;
239         pTask=NULL;
240       }
241     }
242   } else {
243     iResult=-EINVAL;
244   }
245   return iResult;
246 }
247
248 int AliHLTSystem::CleanTaskList()
249 {
250   // see header file for class documentation
251   int iResult=0;
252   fpHLTOUTTask=NULL;
253   fpControlTask=NULL;
254   TObjLink* lnk=NULL;
255   while ((lnk=fTaskList.LastLink())!=NULL) {
256     delete (lnk->GetObject());
257     fTaskList.Remove(lnk);
258   }
259
260   return iResult;
261 }
262
263 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
264 {
265   // see header file for class documentation
266   int iResult=0;
267   if (fpControlTask==NULL) {
268     fpControlTask=new AliHLTControlTask;
269     if (!fpControlTask) return -ENOMEM;
270     fTaskList.AddFirst(fpControlTask);
271   }
272   TObjLink *controlLnk=NULL;
273   TObjLink *lnk = fTaskList.FirstLink();
274   assert(!lnk || lnk->GetObject()==fpControlTask || fpControlTask==NULL);
275   if (lnk && lnk->GetObject()==fpControlTask) {
276     if (pTask->GetConf() && pTask->GetConf()->GetFirstSource()==NULL) {
277       pTask->SetDependency(fpControlTask);
278       fpControlTask->SetTarget(pTask);
279     }
280     controlLnk=lnk;
281     lnk=lnk->Next();
282   }
283   if ((iResult=pTask->CheckDependencies())<=0)
284     lnk=NULL;
285   while (lnk && iResult>0) {
286     AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
287     //HLTDebug("checking  \"%s\"", pCurr->GetName());
288     iResult=pTask->Depends(pCurr);
289     if (iResult>0) {
290       iResult=pTask->SetDependency(pCurr);
291       pCurr->SetTarget(pTask);
292       HLTDebug("set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
293     }
294     if (pCurr->Depends(pTask)) {
295       // circular dependency
296       HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
297       iResult=-ELOOP;
298     } else if ((iResult=pTask->CheckDependencies())>0) {
299       lnk = lnk->Next();
300     }
301   }
302   if (iResult==0) {
303       if (lnk) {
304         fTaskList.AddAfter(lnk, pTask);
305       } else if (controlLnk) {
306         fTaskList.AddAfter(controlLnk, pTask);
307       } else {
308         fTaskList.AddFirst(pTask);
309       }
310       HLTDebug("task \"%s\" (%p) inserted (size %d)", pTask->GetName(), pTask, sizeof(AliHLTTask));
311   } else if (iResult>0) {
312     HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
313     iResult=-ENOLINK;
314   }
315   return iResult;
316 }
317
318 AliHLTTask* AliHLTSystem::FindTask(const char* id)
319 {
320   // see header file for class documentation
321   AliHLTTask* pTask=NULL;
322   if (id) {
323     pTask=dynamic_cast<AliHLTTask*>(fTaskList.FindObject(id)); 
324   }
325   return pTask;
326 }
327
328 void AliHLTSystem::PrintTaskList()
329 {
330   // see header file for class documentation
331   HLTLogKeyword("task list");
332   TObjLink *lnk = NULL;
333   HLTMessage("Task List");
334   lnk=fTaskList.FirstLink();
335   while (lnk) {
336     TObject* obj=lnk->GetObject();
337     if (obj) {
338       HLTMessage("  %s - status:", obj->GetName());
339       AliHLTTask* pTask=(AliHLTTask*)obj;
340       pTask->PrintStatus();
341     } else {
342     }
343     lnk = lnk->Next();
344   }
345 }
346
347 int AliHLTSystem::Run(Int_t iNofEvents, int bStop, AliHLTUInt64_t trgMask,
348                       AliHLTUInt32_t timestamp, AliHLTUInt32_t eventtype,
349                       AliHLTUInt32_t participatingDetectors)
350 {
351   return Run(iNofEvents, bStop, AliHLTTriggerMask_t(trgMask), 
352              timestamp, eventtype, participatingDetectors);
353 }
354
355 int AliHLTSystem::Run(Int_t iNofEvents, int bStop, AliHLTTriggerMask_t trgMask,
356                       AliHLTUInt32_t timestamp, AliHLTUInt32_t eventtype,
357                       AliHLTUInt32_t participatingDetectors)
358 {
359   // see header file for class documentation
360   int iResult=0;
361   int iCount=0;
362   SetStatusFlags(kRunning);
363   if (fEventCount>=0 || (iResult=InitTasks())>=0) {
364     if (fEventCount>=0 || (iResult=StartTasks())>=0) {
365       if (fEventCount==0) {
366         InitBenchmarking(fStopwatches);
367       } else {
368         // Matthias Oct 11 2008 this is a bug
369         // By resuming the stopwatches at this point, all continued counting, but the
370         // starting and stopping is controlled by the AliHLTStopwatchGuard
371         //ResumeBenchmarking(fStopwatches);    
372       }
373       for (int i=fEventCount; i<fEventCount+iNofEvents && iResult>=0; i++) {
374         if (fpHLTOUTTask) {
375           if (iNofEvents>1 && i==fEventCount) {
376             HLTWarning("can not add more than one event to the HLTOUT, skipping all but last block");
377           }
378           // reset and prepare for new data
379           fpHLTOUTTask->Reset();
380         }
381         if (eventtype == 0) {
382           eventtype = gkAliEventTypeData;
383           participatingDetectors = 0x0;
384         }
385         if ((iResult=ProcessTasks(i, trgMask, timestamp, eventtype, participatingDetectors))>=0) {
386           fGoodEvents++;
387           iCount++;
388         } else {
389           // TODO: define different running modes to either ignore errors in
390           // event processing or not
391           // currently ignored 
392           iResult=0;
393         }
394         AliHLTDataBuffer::SetGlobalEventCount(iCount);
395       }
396       fEventCount+=iNofEvents;
397       if (bStop) StopTasks();
398       else PauseBenchmarking(fStopwatches);
399     }
400     if (bStop) DeinitTasks();
401   }
402   if (iResult>=0) {
403     iResult=iCount;
404   } else  if (iResult==-126 /*ENOKEY*/) {
405     iResult=0; // do not propagate the error
406   }
407   ClearStatusFlags(kRunning);
408   AliHLTDataBuffer::PrintStatistics();
409   return iResult;
410 }
411
412 int AliHLTSystem::InitTasks()
413 {
414   // see header file for class documentation
415   int iResult=0;
416   TObjLink *lnk=fTaskList.FirstLink();
417
418   if (lnk==NULL) {
419     HLTInfo("Task list is empty, skipping HLT");
420     return -126 /*ENOKEY*/;
421   }
422   while (lnk && iResult>=0) {
423     TObject* obj=lnk->GetObject();
424     if (obj) {
425       AliHLTTask* pTask=(AliHLTTask*)obj;
426       iResult=pTask->Init(NULL, fpComponentHandler);
427 //       ProcInfo_t ProcInfo;
428 //       gSystem->GetProcInfo(&ProcInfo);
429 //       HLTInfo("task %s initialized (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
430     } else {
431     }
432     lnk = lnk->Next();
433   }
434   if (iResult<0) {
435     HLTError("can not initialize task list, error %d", iResult);
436   }
437
438   return iResult;
439 }
440
441 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
442 {
443   // see header file for class documentation
444   int iResult=0;
445   if (pStopwatches==NULL) return 0;
446
447   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
448     TStopwatch* pStopwatch= new TStopwatch;
449     if (pStopwatch) {
450       pStopwatch->Reset();
451       pStopwatches->AddAt(pStopwatch, i);
452     } else {
453       iResult=-ENOMEM;
454       break;
455     }
456   }
457
458   TObjLink *lnk=fTaskList.FirstLink();
459   while (lnk && iResult>=0) {
460     TObject* obj=lnk->GetObject();
461     if (obj) {
462       AliHLTTask* pTask=(AliHLTTask*)obj;
463       AliHLTComponent* pComp=NULL;
464       if (iResult>=0 && (pComp=pTask->GetComponent())!=NULL) {
465         switch (pComp->GetComponentType()) {
466         case AliHLTComponent::kProcessor:
467           pComp->SetStopwatches(pStopwatches);
468           break;
469         case AliHLTComponent::kSource:
470           {
471             // this switch determines whether the time consumption of the
472             // AliHLTComponent base methods should be counted to the input
473             // stopwatch or base stopwatch.
474             //int inputBase=(int)AliHLTComponent::kSWBase;
475             int inputBase=(int)AliHLTComponent::kSWInput;
476             pComp->SetStopwatch(pStopwatches->At(inputBase), AliHLTComponent::kSWBase);
477             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWInput), AliHLTComponent::kSWDA);
478           }
479           break;
480         case AliHLTComponent::kSink:
481           {
482             // this switch determines whether the time consumption of the
483             // AliHLTComponent base methods should be counted to the output
484             // stopwatch or base stopwatch.
485             //int outputBase=(int)AliHLTComponent::kSWBase;
486             int outputBase=(int)AliHLTComponent::kSWOutput;
487             pComp->SetStopwatch(pStopwatches->At(outputBase), AliHLTComponent::kSWBase);
488             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWOutput), AliHLTComponent::kSWDA);
489           }
490           break;
491         default:
492           HLTWarning("unknown component type %d", (int)pComp->GetComponentType());
493         }
494       }
495     } else {
496     }
497     lnk = lnk->Next();
498   }
499   return iResult;
500 }
501
502 int AliHLTSystem::PauseBenchmarking(TObjArray* pStopwatches) const
503 {
504   // see header file for class documentation
505   if (pStopwatches==NULL) return 0;
506
507   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
508     if (!pStopwatches->At(i)) continue;
509     TStopwatch* pSw=dynamic_cast<TStopwatch*>(pStopwatches->At(i));
510     if (pSw) pSw->Stop();
511   }
512   return 0;
513 }
514
515 int AliHLTSystem::ResumeBenchmarking(TObjArray* pStopwatches) const
516 {
517   // see header file for class documentation
518   if (pStopwatches==NULL) return 0;
519
520   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
521     if (!pStopwatches->At(i)) continue;
522     TStopwatch* pSw=dynamic_cast<TStopwatch*>(pStopwatches->At(i));
523     if (pSw) pSw->Continue();
524   }
525   return 0;
526 }
527
528 int AliHLTSystem::PrintBenchmarking(TObjArray* pStopwatches, int bClean) const
529 {
530   // see header file for class documentation
531   int iInitialized=1;
532   if (pStopwatches==NULL) return 0;
533
534   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
535     if (!dynamic_cast<TStopwatch*>(pStopwatches->At(i))) {
536       iInitialized=0;
537       break;
538     }
539   }
540
541   if (iInitialized!=0) {
542     HLTImportant("HLT statistics:\n"
543             "    base:              R:%.3fs C:%.3fs\n"
544             "    input:             R:%.3fs C:%.3fs\n"
545             "    output:            R:%.3fs C:%.3fs\n"
546             "    event processing : R:%.3fs C:%.3fs"
547             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->RealTime()
548             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->CpuTime()
549             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->RealTime()
550             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->CpuTime()
551             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->RealTime()
552             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->CpuTime()
553             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->RealTime()
554             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->CpuTime()
555             );
556   }
557
558   if (bClean) {
559     for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
560       TObject* pObj=pStopwatches->RemoveAt(i);
561       if (pObj) delete pObj;
562     }
563   }
564   return 0;
565 }
566
567 int AliHLTSystem::StartTasks()
568 {
569   // see header file for class documentation
570   int iResult=0;
571   TObjLink *lnk=fTaskList.FirstLink();
572   while (lnk && iResult>=0) {
573     TObject* obj=lnk->GetObject();
574     if (obj) {
575       AliHLTTask* pTask=(AliHLTTask*)obj;
576       iResult=pTask->StartRun();
577 //       ProcInfo_t ProcInfo;
578 //       gSystem->GetProcInfo(&ProcInfo);
579 //       HLTInfo("task %s started (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
580     } else {
581     }
582     lnk = lnk->Next();
583   }
584   if (iResult<0) {
585     HLTError("can not start task list, error %d", iResult);
586   } else {
587     SetStatusFlags(kStarted);
588     fEventCount=0;
589     fGoodEvents=0;
590     if ((iResult=SendControlEvent(kAliHLTDataTypeSOR))<0) {
591       HLTError("can not send SOR event: error %d", iResult);
592     }
593   }
594   return iResult;
595 }
596
597 int AliHLTSystem::ProcessTasks(Int_t eventNo, AliHLTTriggerMask_t trgMask,
598           AliHLTUInt32_t timestamp, AliHLTUInt32_t eventtype,
599           AliHLTUInt32_t participatingDetectors)
600 {
601   // see header file for class documentation
602   int iResult=0;
603   HLTDebug("processing event no %d", eventNo);
604   TObjLink *lnk=fTaskList.FirstLink();
605   while (lnk) {
606     TObject* obj=lnk->GetObject();
607     if (obj) {
608       AliHLTTask* pTask=(AliHLTTask*)obj;
609       if (iResult>=0) {
610       iResult=pTask->ProcessTask(eventNo, eventtype, trgMask, timestamp, participatingDetectors);
611 //       ProcInfo_t ProcInfo;
612 //       gSystem->GetProcInfo(&ProcInfo);
613 //       HLTInfo("task %s processed (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
614       } else {
615         pTask->SubscribeSourcesAndSkip();
616       }
617     } else {
618     }
619     lnk = lnk->Next();
620   }
621
622   if (iResult>=0) {
623     HLTImportant("Event %d successfully finished (%d)", eventNo, iResult);
624     iResult=0;
625   } else {
626     HLTError("Processing of event %d failed (%d)", eventNo, iResult);
627   }
628
629   return iResult;
630 }
631
632 int AliHLTSystem::StopTasks()
633 {
634   // see header file for class documentation
635   int iResult=0;
636   if ((iResult=SendControlEvent(kAliHLTDataTypeEOR))<0) {
637     HLTError("can not send EOR event");
638   }
639
640   // cleanup blocks from the last event. This is a bit awkward. All output
641   // blocks from the chains need to be stored in the HLTOUT task. Though,
642   // we do not know, whether HLTOUT is going to be processed or not.
643   if (fpHLTOUTTask)
644     fpHLTOUTTask->Reset();
645
646   TObjLink *lnk=fTaskList.FirstLink();
647   while (lnk) {
648     TObject* obj=lnk->GetObject();
649     if (obj) {
650       AliHLTTask* pTask=(AliHLTTask*)obj;
651       int locResult=pTask->EndRun();
652       if (iResult>=0 && locResult<0) iResult=locResult;
653 //       ProcInfo_t ProcInfo;
654 //       gSystem->GetProcInfo(&ProcInfo);
655 //       HLTInfo("task %s stopped (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
656     } else {
657     }
658     lnk = lnk->Next();
659   }
660   PrintBenchmarking(fStopwatches, 1 /*clean*/);
661   if (fEventCount!=fGoodEvents) {
662     HLTError("%d out of %d event(s) failed", fEventCount-fGoodEvents, fEventCount);
663   }
664   ClearStatusFlags(kStarted);
665   return iResult;
666 }
667
668 int AliHLTSystem::SendControlEvent(AliHLTComponentDataType dt)
669 {
670   // see header file for class documentation
671   int iResult=0;
672
673   AliHLTComponentBlockDataList controlBlocks;
674   AliHLTComponentBlockData bd;
675
676   // run decriptor block of type kAliHLTDataTypeSOR/kAliHLTDataTypeEOR 
677   AliHLTComponent::FillBlockData(bd);
678   AliHLTRunDesc runDesc;
679   memset(&runDesc, 0, sizeof(AliHLTRunDesc));
680   runDesc.fStructSize=sizeof(AliHLTRunDesc);
681   runDesc.fRunNo=AliHLTMisc::Instance().GetCDBRunNo();
682   bd.fPtr=&runDesc;
683   bd.fSize=sizeof(AliHLTRunDesc);
684   bd.fDataType=dt;
685   bd.fSpecification=kAliHLTVoidDataSpec;
686   controlBlocks.push_back(bd);
687
688   // ECS parameter of type kAliHLTDataTypeECSParam
689   if (fECSParams.IsNull())
690     fECSParams="CTP_TRIGGER_CLASS=00:DUMMY-TRIGGER-ALL:00-01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17";
691   AliHLTComponent::FillBlockData(bd);
692   bd.fPtr=(void*)fECSParams.Data();
693   bd.fSize=fECSParams.Length()+1;
694   bd.fDataType=kAliHLTDataTypeECSParam;
695   bd.fSpecification=kAliHLTVoidDataSpec;
696   controlBlocks.push_back(bd);  
697
698   AliHLTControlTask::AliHLTControlEventGuard g(fpControlTask, controlBlocks);
699   HLTDebug("sending event %s, run descriptor %p", AliHLTComponent::DataType2Text(dt).c_str(), &runDesc);
700   TObjLink *lnk=fTaskList.FirstLink();
701   while (lnk && iResult>=0) {
702     TObject* obj=lnk->GetObject();
703     if (obj) {
704       AliHLTTask* pTask=(AliHLTTask*)obj;
705       AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
706       if (dt==kAliHLTDataTypeSOR) eventType=gkAliEventTypeStartOfRun;
707       else if (dt==kAliHLTDataTypeEOR) eventType=gkAliEventTypeEndOfRun;
708       else HLTWarning("unknown control event %s", AliHLTComponent::DataType2Text(dt).c_str());
709       iResult=pTask->ProcessTask(-1, eventType, 0, 0);
710     } else {
711     }
712     lnk = lnk->Next();
713   }
714
715   // control events are not supposed to go into the HLTOUT
716   if (fpHLTOUTTask)
717     fpHLTOUTTask->Reset();
718
719   HLTDebug("event %s done (%d)", AliHLTComponent::DataType2Text(dt).c_str(), iResult);
720   return iResult;
721 }
722
723 int AliHLTSystem::DeinitTasks()
724 {
725   // see header file for class documentation
726   int iResult=0;
727   TObjLink *lnk=fTaskList.LastLink();
728   while (lnk) {
729     TObject* obj=lnk->GetObject();
730     if (obj) {
731       AliHLTTask* pTask=(AliHLTTask*)obj;
732       int localRes=pTask->Deinit();
733       if (iResult>=0) iResult=localRes;
734 //       ProcInfo_t ProcInfo;
735 //       gSystem->GetProcInfo(&ProcInfo);
736 //       HLTInfo("task %s cleaned (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
737     } else {
738     }
739     lnk = lnk->Prev();
740   }
741   fEventCount=-1;
742   fGoodEvents=-1;
743
744   return iResult;
745 }
746
747 int AliHLTSystem::CleanupHLTOUTHandlers()
748 {
749   // see header file for class documentation
750   if (fpChainHandlers) {
751     AliHLTOUT::AliHLTOUTHandlerListEntryVector* pHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpChainHandlers);
752     fpChainHandlers=NULL;
753     if (pHandlers) {
754       AliHLTOUT::InvalidateBlocks(*pHandlers);
755       AliHLTOUT::RemoveEmptyDuplicateHandlers(*pHandlers);
756     }
757     assert(pHandlers->size()==0);
758     delete pHandlers;
759   }
760
761   if (fpEsdHandlers) {
762     AliHLTOUT::AliHLTOUTHandlerListEntryVector* pHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpEsdHandlers);
763     fpEsdHandlers=NULL;
764     if (pHandlers) {
765       AliHLTOUT::InvalidateBlocks(*pHandlers);
766       AliHLTOUT::RemoveEmptyDuplicateHandlers(*pHandlers);
767     }
768     assert(pHandlers->size()==0);
769     delete pHandlers;
770   }
771
772   if (fpProprietaryHandlers) {
773     AliHLTOUT::AliHLTOUTHandlerListEntryVector* pHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpProprietaryHandlers);
774     fpProprietaryHandlers=NULL;
775     if (pHandlers) {
776       AliHLTOUT::InvalidateBlocks(*pHandlers);
777       AliHLTOUT::RemoveEmptyDuplicateHandlers(*pHandlers);
778     }
779     assert(pHandlers->size()==0);
780     delete pHandlers;
781   }
782   return 0;
783 }
784
785 void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
786 {
787   // see header file for class documentation
788   void* p=NULL;
789   try {
790     p=(void*)new char[size];
791   }
792   catch (...) {
793     AliHLTLogging log;
794     log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
795   }
796   return p;
797 }
798
799 int AliHLTSystem::AllocEventDoneData( void* /*param*/, AliHLTEventID_t /*eventID*/, unsigned long size, AliHLTComponentEventDoneData** edd )
800 {
801   // see header file for class documentation
802   unsigned long blocksize=sizeof(AliHLTComponentEventDoneData)+size;
803   void* block=AllocMemory(NULL, blocksize);
804   if (!block) return -ENOMEM;
805   memset(block, 0, blocksize);
806   *edd=reinterpret_cast<AliHLTComponentEventDoneData*>(block);
807   (*edd)->fStructSize=sizeof(AliHLTComponentEventDoneData);
808   (*edd)->fDataSize=size;
809   (*edd)->fData=reinterpret_cast<AliHLTUInt8_t*>(block)+sizeof(AliHLTComponentEventDoneData);
810   
811   return 0;
812 }
813
814 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
815                               AliRawReader* rawReader)
816 {
817   // see header file for class documentation
818   int iResult=0;
819   if (runLoader || rawReader || nofEvents==0) {
820     if (nofEvents>0) {HLTInfo("Run Loader %p, Raw Reader %p , %d event(s)", runLoader, rawReader, nofEvents);}
821     if (CheckStatus(kReady)) {
822       if (nofEvents==0) {
823         // special case to close the reconstruction
824         if (!CheckStatus(kError)) {
825         StopTasks();
826         DeinitTasks();
827         CleanupHLTOUTHandlers();
828         }
829       } else {
830       if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
831         AliHLTTriggerMask_t trgMask=0x1;
832         AliHLTUInt32_t timestamp=kMaxUInt;
833         AliHLTUInt32_t eventtype=0;
834         if (runLoader==NULL) {
835           // this is a quick workaround for the case of simulation
836           // the trigger framework is still under development, secondly, AliHLTSimulation
837           // does not yet add the emulated ECS parameters, so no CTP trigger is known in the HLT
838           // AliHLTTask will initialize one dummy CTP trigger class with bit 0, that's why the
839           // default trigger mask is 0x1
840           trgMask=AliHLTMisc::Instance().GetTriggerMask(rawReader);
841
842           // get the timestamp and type of the event from the raw reader
843           // this is currently only meaningfull for reconstruction (runloader==NULL)
844           timestamp=AliHLTMisc::Instance().GetTimeStamp(rawReader);
845           eventtype=AliHLTMisc::Instance().GetEventType(rawReader);
846         }
847         // the system always remains started after event processing, a specific
848         // call with nofEvents==0 is needed to execute the stop sequence
849         if ((iResult=Run(nofEvents, 0, trgMask, timestamp, eventtype))<0) SetStatusFlags(kError);
850       }
851       }
852
853       // add the current HLTOUT task to the collection
854       if (fpHLTOUTTask) {
855         AliHLTOUT* pTask=dynamic_cast<AliHLTOUT*>(fpHLTOUTTask);
856         if (pTask && (iResult=pTask->Init())>=0) {
857           if (pTask->GetNofDataBlocks()>0) {
858             AliHLTOUT* pHLTOUT=RequestHLTOUT();
859             if (pHLTOUT) {
860               pHLTOUT->AddSubCollection(pTask);
861               ReleaseHLTOUT(pHLTOUT);
862             } else {
863               HLTWarning("no HLTOUT instance available, output blocks of the chain are ignored");
864             }
865           }
866         } else {
867           HLTWarning("can not initialize HLTOUT sub collection %s for reconstruction chain (%d), data blocks are lost", pTask?fpHLTOUTTask->GetName():"nil", iResult);
868           iResult=0;
869         }
870       }
871     } else {
872       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
873     }
874   } else {
875     HLTError("missing RunLoader (%p)/RawReader (%p) instance", runLoader, rawReader);
876     iResult=-EINVAL;
877   }
878   return iResult;
879 }
880
881 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
882 {
883   // see header file for class documentation
884   int iResult=0;
885   if (runLoader || esd) {
886     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
887     iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
888   } else {
889     HLTError("missing run loader/ESD instance(s)");
890     iResult=-EINVAL;
891   }
892   return iResult;
893 }
894
895 int AliHLTSystem::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd)
896 {
897   // see header file for class documentation
898   int iResult=0;
899   if (!pHLTOUT) return -EINVAL;
900   HLTDebug("processing %d HLT data blocks", pHLTOUT->GetNofDataBlocks());
901
902   //
903   // process all kChain handlers first
904   //
905   if ((iResult=ProcessHLTOUTkChain(pHLTOUT))<0) {
906     HLTWarning("Processing of kChain-type data blocks failed with error code %d", iResult);
907     iResult=0;
908   } 
909
910   if (!fpEsdHandlers)
911     fpEsdHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
912   if (!fpProprietaryHandlers)
913     fpProprietaryHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
914
915   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pEsdHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpEsdHandlers);
916   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pProprietaryHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpProprietaryHandlers);
917   if (!pEsdHandlers || !pProprietaryHandlers) return -ENOMEM;
918
919   // invalidate all blocks
920   AliHLTOUT::InvalidateBlocks(*pEsdHandlers);
921   AliHLTOUT::InvalidateBlocks(*pProprietaryHandlers);
922
923   AliHLTComponentDataTypeList esdBlocks;
924
925   for (iResult=pHLTOUT->SelectFirstDataBlock();
926        iResult>=0;
927        iResult=pHLTOUT->SelectNextDataBlock()) {
928     AliHLTComponentDataType dt=kAliHLTVoidDataType;
929     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
930     pHLTOUT->GetDataBlockDescription(dt, spec);
931     AliHLTOUTHandler* pHandler=pHLTOUT->GetHandler();
932     AliHLTModuleAgent::AliHLTOUTHandlerType handlerType=pHLTOUT->GetDataBlockHandlerType();
933
934     // default handling for ESD data blocks does not require an explicite handler
935     if (!pHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
936       handlerType=AliHLTModuleAgent::kEsd;
937     }
938     const char* pMsg="invalid";
939     switch (handlerType) {
940     case AliHLTModuleAgent::kEsd:
941       {
942         if (pHandler) {
943           // schedule for later processing
944           pHLTOUT->InsertHandler(*pEsdHandlers, pHLTOUT->GetDataBlockHandlerDesc());
945         } else {
946           AliHLTComponentDataTypeList::iterator element=esdBlocks.begin();
947           for (; element!=esdBlocks.end(); element++) {
948             if (*element==dt) {
949               HLTWarning("multiple ESDs of identical data type %s, please add appropriate handler to merge ESDs", AliHLTComponent::DataType2Text(dt).c_str());
950               break;
951             }
952           }
953           if (element==esdBlocks.end()) esdBlocks.push_back(dt);
954
955           // write directly
956           const AliHLTUInt8_t* pBuffer=NULL;
957           AliHLTUInt32_t size=0;
958           if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
959             pHLTOUT->WriteESD(pBuffer, size, dt, esd);
960             pHLTOUT->ReleaseDataBuffer(pBuffer);
961           }
962           pHLTOUT->MarkDataBlockProcessed();
963         }
964       }
965       break;
966     case AliHLTModuleAgent::kRawReader:
967       // handled in the AliRawReaderHLT
968       break;
969     case AliHLTModuleAgent::kRawStream:
970       HLTWarning("HLTOUT handler type 'kRawStream' not yet implemented: agent %s, data type %s, specification %#x",
971                  pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
972                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
973       break;
974     case AliHLTModuleAgent::kChain:
975       HLTWarning("HLTOUT handler type 'kChain' has already been processed: agent %s, data type %s, specification %#x\n"
976                  "New block of this type added by the chain? Skipping data block ...",
977                  pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
978                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
979       break;
980     case AliHLTModuleAgent::kProprietary:
981       HLTDebug("processing proprietary data: agent %s, data type %s, specification %#x",
982                  pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
983                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
984       if (pHandler) {
985         AliHLTOUT::AliHLTOUTLockGuard g(pHLTOUT);
986         int res=pHandler->ProcessData(pHLTOUT);
987         if (res<0) {
988           HLTWarning("processing proprietary data failed (%d): agent %s, data type %s, specification %#x",
989                      res, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
990                      AliHLTComponent::DataType2Text(dt).c_str(), spec);
991         }
992       }
993       break;
994     case AliHLTModuleAgent::kUnknownOutput:
995       pMsg="unknown";
996       // fall trough intended
997     default:
998       HLTWarning("%s handler type: agent %s, data type %s, specification %#x, ... skipping data block",
999                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
1000                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
1001     }
1002   }
1003   // TODO: the return value of SelectFirst/NextDataBlock must be
1004   // changed in order to avoid this check
1005   if (iResult==-ENOENT) iResult=0;
1006
1007   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator handler;
1008
1009   // process and write all esd data blocks
1010   for (handler=pEsdHandlers->begin(); handler!=pEsdHandlers->end() && iResult>=0; handler++) {
1011     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*handler));     
1012     AliHLTOUTHandler* pHandler=*handler;
1013     const AliHLTUInt8_t* pBuffer=NULL;
1014     AliHLTUInt32_t size=0;
1015     pHandler->ProcessData(pHLTOUT);
1016     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
1017       AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*handler;
1018       AliHLTComponentDataType dt=desc;
1019       pHLTOUT->WriteESD(pBuffer, size, dt, esd);
1020       pHandler->ReleaseProcessedData(pBuffer, size);
1021     }
1022     pHLTOUT->MarkDataBlocksProcessed(&(*handler));
1023   }
1024
1025   // process all kProprietary data blocks
1026   for (handler=pProprietaryHandlers->begin(); handler!=pProprietaryHandlers->end() && iResult>=0; handler++) {
1027     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*handler));     
1028     AliHLTOUTHandler* pHandler=*handler;
1029     const AliHLTUInt8_t* pBuffer=NULL;
1030     AliHLTUInt32_t size=0;
1031     pHandler->ProcessData(pHLTOUT);
1032     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
1033       HLTWarning("data produced by kProprietary handler ignored");
1034       pHandler->ReleaseProcessedData(pBuffer, size);
1035     }
1036     pHLTOUT->MarkDataBlocksProcessed(&(*handler));
1037   }
1038
1039   // remove all empty handlers form the list (handlers which did not get a block this time)
1040   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pEsdHandlers);
1041   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pProprietaryHandlers);
1042
1043   return iResult;
1044 }
1045
1046 int AliHLTSystem::ProcessHLTOUTkChain(AliHLTOUT* pHLTOUT)
1047 {
1048   // see header file for class documentation
1049   int iResult=0;
1050   if (!pHLTOUT) return -EINVAL;
1051
1052   if (!fpChainHandlers)
1053     fpChainHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
1054
1055   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pChainHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpChainHandlers);
1056   if (!pChainHandlers) return -ENOMEM;
1057
1058   // invalidate all blocks
1059   AliHLTOUT::InvalidateBlocks(*pChainHandlers);
1060
1061   // fill the list
1062   pHLTOUT->FillHandlerList(*pChainHandlers, AliHLTModuleAgent::kChain);
1063
1064   // process all defined chain handlers
1065   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator chainHandler;
1066   for (chainHandler=pChainHandlers->begin(); chainHandler!=pChainHandlers->end() && iResult>=0; chainHandler++) {
1067     if (chainHandler->IsEmpty()) continue;
1068     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*chainHandler));        
1069     AliHLTOUTHandler* pHandler=*chainHandler;
1070     const AliHLTUInt8_t* pBuffer=NULL;
1071     AliHLTUInt32_t size=0;
1072     pHandler->ProcessData(pHLTOUT);
1073     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
1074       AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*chainHandler;
1075       //AliHLTComponentDataType dt=desc;
1076
1077       pHandler->ReleaseProcessedData(pBuffer, size);
1078     }
1079     pHLTOUT->MarkDataBlocksProcessed(&(*chainHandler));
1080   }
1081
1082   // remove all empty handlers form the list (handlers which did not get a block this time)
1083   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pChainHandlers);
1084
1085   return iResult;
1086 }
1087
1088 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
1089 {
1090   // see header file for class documentation
1091   int iResult=0;
1092   if (libraries) {
1093     if (fpComponentHandler) {
1094       TString libs(libraries);
1095       TObjArray* pTokens=libs.Tokenize(" ");
1096       if (pTokens) {
1097         int iEntries=pTokens->GetEntriesFast();
1098         for (int i=0; i<iEntries && iResult>=0; i++) {
1099           if (!pTokens->At(i)) continue;
1100           iResult=fpComponentHandler->LoadLibrary(pTokens->At(i)->GetName());
1101         }
1102         delete pTokens;
1103       }
1104       if (iResult>=0) {
1105         SetStatusFlags(kLibrariesLoaded);
1106       } else {
1107         // lets see if we need this, probably not
1108         //fpComponentHandler->UnloadLibraries();
1109         ClearStatusFlags(kLibrariesLoaded);
1110       }
1111     } else {
1112       iResult=-EFAULT;
1113       HLTFatal("no component handler available");
1114     }
1115   } else {
1116     iResult=-EINVAL;
1117   }
1118   return iResult;
1119 }
1120
1121 int AliHLTSystem::Configure(AliRunLoader* runloader)
1122 {
1123   // see header file for class documentation
1124   return Configure(NULL, runloader);
1125 }
1126
1127 int AliHLTSystem::Configure(AliRawReader* rawReader, AliRunLoader* runloader)
1128 {
1129   // see header file for class documentation
1130   int iResult=0;
1131   if (CheckStatus(kRunning)) {
1132     HLTError("HLT system in running state, can not configure");
1133     return -EBUSY;
1134   }
1135   ClearStatusFlags(kTaskListCreated);
1136   if (CheckFilter(kHLTLogDebug))
1137     AliHLTModuleAgent::PrintStatus();
1138   if (CheckStatus(kConfigurationLoaded)==0) {
1139     iResult=LoadConfigurations(rawReader, runloader);
1140   } else {
1141     if (fChains.Length()==0) {
1142       HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'chains=<chain,...>\' option");
1143       iResult=-ENOENT;
1144     }
1145   }
1146   if (iResult>=0) {
1147     SetStatusFlags(kConfigurationLoaded);
1148     if (CheckFilter(kHLTLogDebug))
1149       fpConfigurationHandler->PrintConfigurations();
1150     iResult=BuildTaskListsFromReconstructionChains(rawReader, runloader);
1151     if (iResult>=0) {
1152       SetStatusFlags(kTaskListCreated);
1153     }
1154   }
1155   if (iResult<0) SetStatusFlags(kError);
1156   
1157   return iResult;
1158 }
1159
1160 int AliHLTSystem::ScanOptions(const char* options)
1161 {
1162   // see header file for class documentation
1163   int iResult=0;
1164   if (options) {
1165     //AliHLTComponentHandler::TLibraryMode libMode=AliHLTComponentHandler::kDynamic;
1166     TString libs("");
1167     TString excludelibs("");
1168     TString alloptions(options);
1169     TObjArray* pTokens=alloptions.Tokenize(" ");
1170     if (pTokens) {
1171       int iEntries=pTokens->GetEntriesFast();
1172       for (int i=0; i<iEntries; i++) {
1173         if (!pTokens->At(i)) continue;
1174         TString token=pTokens->At(i)->GetName();
1175         if (token.Contains("loglevel=")) {
1176           TString param=token.ReplaceAll("loglevel=", "");
1177           if (param.IsDigit()) {
1178             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
1179           } else if (param.BeginsWith("0x") &&
1180                      param.Replace(0,2,"",0).IsHex()) {
1181             int severity=0;
1182             sscanf(param.Data(),"%x", &severity);
1183             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
1184           } else {
1185             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
1186           }
1187         } else if (token.Contains("frameworklog=")) {
1188           TString param=token.ReplaceAll("frameworklog=", "");
1189           if (param.IsDigit()) {
1190             SetFrameworkLog((AliHLTComponentLogSeverity)param.Atoi());
1191           } else if (param.BeginsWith("0x") &&
1192                      param.Replace(0,2,"",0).IsHex()) {
1193             int severity=0;
1194             sscanf(param.Data(),"%x", &severity);
1195             SetFrameworkLog((AliHLTComponentLogSeverity)severity);
1196           } else {
1197             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
1198           }
1199         } else if (token.Contains("alilog=off")) {
1200           SwitchAliLog(0);
1201         } else if (token.Contains("config=") || token.Contains("run-online-config")) {
1202           if (!CheckStatus(kConfigurationLoaded)) {
1203             Int_t error=0;
1204             AliHLTOnlineConfiguration* pConf = NULL;
1205             if (token.Contains("run-online-config")) {
1206               AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry("HLT/Calib/OnlineConfig");
1207               if (pEntry) {
1208                 TObject* pObject=AliHLTMisc::Instance().ExtractObject(pEntry);
1209                 if (pObject && pObject->IsA() == AliHLTOnlineConfiguration::Class())
1210                   pConf = (AliHLTOnlineConfiguration*)pObject;
1211               }
1212             }
1213             if (token.Contains("config=")) {
1214               TString param=token.ReplaceAll("config=", "");
1215               if (token.EndsWith(".xml", TString::kIgnoreCase)) {
1216                 Int_t filesize = 0;
1217                 pConf = new AliHLTOnlineConfiguration;
1218                 filesize = pConf->LoadConfiguration(param.Data());
1219                 if (filesize <= 0) {
1220                   HLTError("cannot load config \'%s\'", param.Data());
1221                   iResult=-EBADF;
1222                 }
1223               } else {
1224                 gROOT->Macro(param.Data(), &error);
1225                 if (error==0) {
1226                   SetStatusFlags(kConfigurationLoaded);
1227                 } else {
1228                   HLTError("cannot execute macro \'%s\'", param.Data());
1229                   iResult=-EBADF;
1230                 }
1231               }
1232             }
1233             if (pConf) {
1234                 error = pConf->Parse();
1235                 if (error==0) {
1236                   fChains = pConf->GetDefaultChains();
1237                   libs = pConf->GetComponentLibraries();
1238                   libs += " ";
1239                   SetStatusFlags(kConfigurationLoaded);
1240                 } else {
1241                   HLTError("cannot parse online configuration");
1242                   iResult=-EBADF;
1243                 }
1244             }
1245             delete pConf; pConf=NULL;
1246           } else {
1247             HLTWarning("HLT options has both a config file and run-online-config set");
1248           }
1249         } else if (token.Contains("chains=")) {
1250           TString param=token.ReplaceAll("chains=", "");
1251           fChains=param.ReplaceAll(",", " ");
1252           if (fChains.IsNull()) fChains=" "; // disable all chains
1253         } else if (token.Contains("libmode=")) {
1254           TString param=token.ReplaceAll("libmode=", "");
1255           param.ReplaceAll(",", " ");
1256           if (fpComponentHandler) {
1257             if (param.CompareTo("static")==0) {
1258               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kStatic);
1259             } else if (param.CompareTo("dynamic")==0) {
1260               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kDynamic);
1261             } else {
1262               HLTWarning("wrong argument for option \'libmode=\', use \'static\' or \'dynamic\'");
1263             }
1264           }
1265         } else if (token.BeginsWith("ECS=")) {
1266           fECSParams=token.ReplaceAll("ECS=", "");
1267         } else if (token.BeginsWith("hltout-mode=")) {
1268           // The actual parameter for argument 'hltout-mode' is treated in AliSimulation.
1269           // For AliHLTSystem the occurrence with parameter 'split' signals the use of the
1270           // separated HLTOUTComponents for digit and raw data. All others indicate
1271           // HLTOUTComponent type 'global' where the data generation is steered from global
1272           // flags
1273           fUseHLTOUTComponentTypeGlobal=token.CompareTo("hltout-mode=split")!=0;
1274         } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
1275           libs+=token;
1276           libs+=" ";
1277         } else if (token.BeginsWith("!lib") && token.EndsWith(".so")) {
1278           excludelibs+=token;
1279           excludelibs+=" ";
1280         } else {
1281           HLTWarning("unknown option \'%s\'", token.Data());
1282         }
1283       }
1284       delete pTokens;
1285     }
1286
1287     if (iResult>=0) {
1288       if (libs.IsNull()) {
1289         const char** deflib=fgkHLTDefaultLibs;
1290         for (;*deflib; deflib++) {
1291           if (excludelibs.Contains(*deflib)) continue;
1292           libs+=*deflib;
1293           libs+=" ";
1294         }
1295       }
1296       if ((!CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
1297           (LoadComponentLibraries(libs.Data())<0)) {
1298         HLTError("error while loading HLT libraries");
1299         iResult=-EFAULT;
1300       }
1301     }
1302   }
1303   return iResult;
1304 }
1305
1306 int AliHLTSystem::Reset(int bForce)
1307 {
1308   // see header file for class documentation
1309   int iResult=0;
1310   if (!bForce && CheckStatus(kRunning)) {
1311     HLTError("HLT system in running state, can not configure");
1312     return -EBUSY;
1313   }
1314   CleanTaskList();
1315   ClearStatusFlags(~kUninitialized);
1316   return iResult;
1317 }
1318
1319 int AliHLTSystem::LoadConfigurations(AliRawReader* rawReader, AliRunLoader* runloader)
1320 {
1321   // see header file for class documentation
1322   if (CheckStatus(kRunning)) {
1323     HLTError("HLT system in running state, can not configure");
1324     return -EBUSY;
1325   }
1326   int iResult=0;
1327   AliHLTModuleAgent* pAgent=NULL;
1328
1329   // first check for the required libraries and load those
1330   TString extralibs;
1331   for (pAgent=AliHLTModuleAgent::GetFirstAgent(); 
1332        pAgent && iResult>=0;
1333        pAgent=AliHLTModuleAgent::GetNextAgent()) {
1334     const char* deplibs=pAgent->GetRequiredComponentLibraries();
1335     if (deplibs) {
1336       HLTDebug("required libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
1337       extralibs+=" ";
1338       extralibs+=deplibs;
1339     }
1340   }
1341   if (iResult>=0) {
1342     iResult=LoadComponentLibraries(extralibs.Data());
1343   }
1344
1345   // in order to register the configurations in the correct sequence
1346   // all agents need to be ordered with respect to the required
1347   // libraries. Ordering relies on the naming convention
1348   // libAliHLT<Module>.so
1349   TList agents;
1350   for (pAgent=AliHLTModuleAgent::GetFirstAgent(); 
1351        pAgent && iResult>=0;
1352        pAgent=AliHLTModuleAgent::GetNextAgent()) {
1353     AliHLTModuleAgent* pPrevDep=NULL;
1354     TString dependencies=pAgent->GetRequiredComponentLibraries();
1355     TObjArray* pTokens=dependencies.Tokenize(" ");
1356     if (pTokens) {
1357       for (int n=0; n<pTokens->GetEntriesFast(); n++) {
1358         if (!pTokens->At(n)) continue;
1359         TString module=pTokens->At(n)->GetName();
1360         HLTDebug("  checking %s", module.Data());
1361         module.ReplaceAll("libAliHLT", "");
1362         module.ReplaceAll(".so", "");
1363         
1364         for (AliHLTModuleAgent* pCurrent=dynamic_cast<AliHLTModuleAgent*>(pPrevDep==NULL?agents.First():agents.After(pPrevDep));
1365              pCurrent!=NULL; pCurrent=dynamic_cast<AliHLTModuleAgent*>(agents.After(pCurrent))) {
1366           HLTDebug("    checking %s == %s", module.Data(), pCurrent->GetModuleId());
1367
1368           if (module.CompareTo(pCurrent->GetModuleId())==0) {
1369             pPrevDep=pCurrent;
1370             break;
1371           }
1372         }
1373       }
1374       delete pTokens;
1375     }
1376
1377     if (pPrevDep) {
1378       // insert right after the last dependency
1379       agents.AddAfter(pPrevDep, pAgent);
1380       HLTDebug("insert %s after %s", pAgent->GetModuleId(), pPrevDep->GetModuleId());
1381     } else {
1382       // insert at the beginning
1383       agents.AddFirst(pAgent);
1384       HLTDebug("insert %s at beginning", pAgent->GetModuleId());
1385     }
1386   }
1387
1388   // now we load the configurations
1389   if (agents.GetEntries()) {
1390     TIter next(&agents);
1391     while ((pAgent = dynamic_cast<AliHLTModuleAgent*>(next()))) {
1392       if(fDetMask && !(fDetMask & pAgent->GetDetectorMask())) {
1393         HLTInfo("Skipping %s due to active detector mask.", pAgent->GetName());
1394       } else {
1395         HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
1396         pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
1397       }
1398     }
1399   }
1400
1401   return iResult;
1402 }
1403
1404 int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
1405 {
1406   // see header file for class documentation
1407   if (CheckStatus(kRunning)) {
1408     HLTError("HLT system in running state, can not configure");
1409     return -EBUSY;
1410   }
1411   if (!CheckStatus(kConfigurationLoaded)) {
1412     HLTWarning("configurations not yet loaded");
1413     return 0;
1414   }
1415
1416   if (!fpConfigurationHandler || !fpComponentHandler) return -EFAULT;
1417
1418   int iResult=0;
1419   int bHaveOutput=0;
1420
1421   // query chains
1422   TString chains;
1423   if (fChains.Length()>0) {
1424     chains=fChains;
1425     HLTImportant("custom reconstruction chain: %s", chains.Data());
1426   } else {
1427     for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
1428          pAgent && iResult>=0;
1429          pAgent=AliHLTModuleAgent::GetNextAgent()) {
1430       const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
1431       if (agentchains) {
1432         if (!chains.IsNull()) chains+=" ";
1433         chains+=agentchains;
1434         HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
1435       }
1436     }
1437   }
1438
1439   // build task list for chains
1440   TObjArray* pTokens=chains.Tokenize(" ");
1441   if (pTokens) {
1442     int iEntries=pTokens->GetEntriesFast();
1443     for (int i=0; i<iEntries && iResult>=0; i++) {
1444       if (!pTokens->At(i)) continue;
1445       const char* pCID=pTokens->At(i)->GetName();
1446       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
1447       if (pConf) {
1448         iResult=BuildTaskList(pConf);
1449         if (true) { // condition was deprecated but kept for sake of svn diff
1450           // bHaveOutput variable has to be set for both running modes
1451           // AliHLTSimulation and AliHLTReconstruction
1452           TString cid=pConf->GetComponentID();
1453           if (runloader!=NULL && cid.CompareTo("HLTOUT")==0) {
1454             // remove from the input of a global HLTOUT configuration
1455             chains.ReplaceAll(pCID, "");
1456           } else if (bHaveOutput==0) {
1457             // check whether this configuration produces data output
1458             if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
1459               bHaveOutput=0;
1460               chains.ReplaceAll(pCID, "");
1461             }
1462           }
1463         }
1464       } else {
1465         HLTWarning("can not find configuration %s", pCID);
1466       }
1467     }
1468     delete pTokens;
1469   }
1470
1471   // build HLTOUT for simulation
1472   if (iResult>=0 && runloader) {
1473     if (bHaveOutput) {
1474       // there are components in the chain which produce data which need to be
1475       // piped to an HLTOUT
1476
1477       // add the SchemaEvolutionComponent which analyzes the ROOT objects in
1478       // the output stream
1479       if (fpComponentHandler->FindComponentIndex("ROOTSchemaEvolutionComponent")>=0 ||
1480           fpComponentHandler->LoadLibrary("libAliHLTUtil.so")>=0) {
1481         fpConfigurationHandler->CreateConfiguration("_schemaevolution_", "ROOTSchemaEvolutionComponent", 
1482                                                      chains.Data(), "-file=HLT.StreamerInfo.root");
1483         iResult=BuildTaskList("_schemaevolution_");
1484       } else {
1485         HLTWarning("can not load libAliHLTUtil.so and ROOTSchemaEvolutionComponent");
1486       }
1487
1488       // add the HLTOUT component
1489       if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
1490           fpComponentHandler->LoadLibrary("libHLTsim.so")>=0) {
1491         // for the default HLTOUTComponent type 'global' the data generation is steered
1492         // by global flags from AliSimulation. This allows for emulation of the old
1493         // AliHLTSimulation behavior where only one chain is run on either digits or
1494         // simulated raw data and the HLT digits and raw files have been generated
1495         // depending on the configuration
1496         const char* HLTOUTComponentId="HLTOUT";
1497         if (!fUseHLTOUTComponentTypeGlobal) {
1498           // choose the type of output depending  on the availability of
1499           // the raw reader
1500           if (rawReader) HLTOUTComponentId="HLTOUTraw";
1501           else HLTOUTComponentId="HLTOUTdigits";
1502         }
1503         fpConfigurationHandler->CreateConfiguration("_globalout_", HLTOUTComponentId, chains.Data(), NULL);
1504         iResult=BuildTaskList("_globalout_");
1505       } else {
1506         HLTError("can not load libHLTsim.so and HLTOUT component");
1507         iResult=-EFAULT;
1508       }
1509     }
1510   }
1511
1512   // build HLTOUT task for reconstruction
1513   // Matthias 08.07.2008 the rawReader is never set when running embedded into
1514   // AliReconstruction. The system is configured during AliHLTReconstructor::Init
1515   // where the RawReader is not available. It is available in the first invocation
1516   // of Reconstruct.
1517   // 
1518   // That means that policy is slightly changed:
1519   // - if the run loader is available -> AliSimulation
1520   // - no run loader available -> AliReconstruction
1521   if (iResult>=0 && !runloader) {
1522     if (bHaveOutput) {
1523       // there are components in the chain which produce data which need to be
1524       // piped to an HLTOUT sub-collection
1525       if (!fpHLTOUTTask) {
1526         iResult=AddHLTOUTTask(chains.Data());
1527       }
1528     }
1529   }
1530
1531   if (iResult>=0) SetStatusFlags(kTaskListCreated);
1532
1533   return iResult;
1534 }
1535
1536 int AliHLTSystem::AddHLTOUTTask(const char* hltoutchains)
1537 {
1538   // see header file for class documentation
1539   int iResult=0;
1540   if (!hltoutchains || hltoutchains[0]==0) return 0;
1541
1542   // check chains for output
1543   TString chains=hltoutchains;
1544   TObjArray* pTokens=chains.Tokenize(" ");
1545   if (pTokens) {
1546     int iEntries=pTokens->GetEntriesFast();
1547     for (int i=0; i<iEntries && iResult>=0; i++) {
1548       if (!pTokens->At(i)) continue;
1549       const char* token=pTokens->At(i)->GetName();
1550       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(token);
1551       if (pConf) {
1552         TString cid=pConf->GetComponentID();
1553         if (fpComponentHandler->HasOutputData(cid.Data())) {
1554           continue;
1555         }
1556       } else {
1557         HLTWarning("can not find configuration %s", token);
1558       }
1559       // remove from the list of hltout chains
1560       chains.ReplaceAll(token, "");
1561     }
1562     delete pTokens;
1563   }
1564
1565   // do not create the HLTOUT task if none of the chains have output
1566   if (chains.IsNull()) return 0;
1567
1568   // indicate the task to be available
1569   iResult=1;
1570
1571   if (fpHLTOUTTask) {
1572     if (strcmp(chains.Data(), fpHLTOUTTask->GetSourceChains())==0) {
1573       HLTWarning("HLTOUT task already added for chains \"%s\" %p", chains.Data(), fpHLTOUTTask);
1574     } else {
1575       HLTError("HLTOUT task already added for chains \"%s\" %p, ignoring new chains  \"%s\"",
1576                fpHLTOUTTask->GetSourceChains(), fpHLTOUTTask, chains.Data());
1577     }
1578     return iResult;
1579   }
1580
1581   fpHLTOUTTask=new AliHLTOUTTask(chains);
1582   if (fpHLTOUTTask) {
1583     if (fpHLTOUTTask->GetConf() && 
1584         (fpHLTOUTTask->GetConf()->SourcesResolved()>0 ||
1585          fpHLTOUTTask->GetConf()->ExtractSources(fpConfigurationHandler)>0)) {
1586       iResult=InsertTask(fpHLTOUTTask);
1587     } else {
1588       HLTError("HLTOUT task (%s) sources not resolved", fpHLTOUTTask->GetName());
1589       iResult=-ENOENT;
1590     }
1591
1592     if (iResult<0) {
1593       delete fpHLTOUTTask;
1594     }
1595
1596   } else {
1597     iResult=-ENOMEM;
1598   }
1599   return iResult;
1600 }
1601
1602 int AliHLTSystem::CheckStatus(int flag)
1603 {
1604   // see header file for class documentation
1605   if (flag==kUninitialized && flag==fState) return 1;
1606   if ((fState&flag)==flag) return 1;
1607   return 0;
1608 }
1609
1610 int AliHLTSystem::GetStatusFlags()
1611 {
1612   // see header file for class documentation
1613   return fState;
1614 }
1615
1616 int AliHLTSystem::SetStatusFlags(int flags)
1617 {
1618   // see header file for class documentation
1619   fState|=flags;
1620   return fState;
1621 }
1622
1623 int AliHLTSystem::ClearStatusFlags(int flags)
1624 {
1625   // see header file for class documentation
1626   fState&=~flags;
1627   return fState;
1628 }
1629
1630 AliHLTfctVoid AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
1631 {
1632   // see header file for class documentation
1633   if (fpComponentHandler==NULL) return NULL;
1634   return fpComponentHandler->FindSymbol(library, symbol);
1635 }
1636
1637 void AliHLTSystem::SetFrameworkLog(AliHLTComponentLogSeverity level) 
1638 {
1639   // see header file for class documentation
1640   SetLocalLoggingLevel(level);
1641   if (fpComponentHandler) fpComponentHandler->SetLocalLoggingLevel(level);
1642   if (fpConfigurationHandler) fpConfigurationHandler->SetLocalLoggingLevel(level);
1643 }
1644
1645 int AliHLTSystem::LoggingVarargs(AliHLTComponentLogSeverity severity, 
1646                                  const char* originClass, const char* originFunc,
1647                                  const char* file, int line, ... ) const
1648 {
1649   // see header file for function documentation
1650   int iResult=0;
1651
1652   va_list args;
1653   va_start(args, line);
1654
1655   if (!fName.IsNull())
1656     AliHLTLogging::SetLogString(this, " (%p)", "%s_pfmt_: ", fName.Data());
1657   iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, !fName.IsNull() /*append if non empty*/));
1658   va_end(args);
1659
1660   return iResult;
1661 }
1662
1663 int AliHLTSystem::InitHLTOUT(AliHLTOUT* instance)
1664 {
1665   // Init the HLTOUT instance for the current event.
1666   // The instance can be used by other classes to get hold on the data
1667   // from HLTOUT.
1668   if (!instance) return -EINVAL;
1669   if (fpHLTOUT && fpHLTOUT!=instance) return -EBUSY;
1670   fpHLTOUT=instance;
1671   return 0;
1672 }
1673
1674 int AliHLTSystem::InvalidateHLTOUT(AliHLTOUT** target)
1675 {
1676   // Clear the HLTOUT instance.
1677   int iResult=0;
1678   if (fHLTOUTUse>0) {
1679     HLTWarning("HLTOUT instance still in use, potential problem due to invalid pointer ahead");
1680     fHLTOUTUse=0;
1681     iResult=-EBUSY;
1682   }
1683   if (target) *target=fpHLTOUT;
1684   fpHLTOUT=NULL;
1685   return iResult;
1686 }
1687
1688 AliHLTOUT* AliHLTSystem::RequestHLTOUT()
1689 {
1690   // Get the HLTOUT instance.
1691   // User method for processing classes. To be released after use.
1692   if (!fpHLTOUT) return NULL;
1693   fHLTOUTUse++;
1694   return fpHLTOUT;
1695 }
1696
1697 int AliHLTSystem::ReleaseHLTOUT(const AliHLTOUT* instance)
1698 {
1699   // Release the HLTOUT instance after use.
1700   if (!instance) return -EINVAL;
1701   if (instance!=fpHLTOUT) return -ENOENT;
1702   fHLTOUTUse--;
1703   return 0;
1704 }