- adapted to AliRoot logging system, messages printed out via AliRoot
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
1 // $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          for The ALICE Off-line Project.                               *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          *
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 /** @file   AliHLTSystem.cxx
19     @author Matthias Richter
20     @date   
21     @brief  Implementation of HLT module management.
22 */
23
24 #if __GNUC__>= 3
25 using namespace std;
26 #endif
27
28 #include "AliHLTStdIncludes.h"
29 #include "AliHLTSystem.h"
30 #include "AliHLTComponentHandler.h"
31 #include "AliHLTComponent.h"
32 #include "AliHLTConfiguration.h"
33 #include "AliHLTConfigurationHandler.h"
34 #include "AliHLTTask.h"
35 #include "TString.h"
36
37 /** ROOT macro for the implementation of ROOT specific class methods */
38 ClassImp(AliHLTSystem)
39
40 AliHLTSystem::AliHLTSystem()
41   :
42   fpComponentHandler(new AliHLTComponentHandler()),
43   fpConfigurationHandler(new AliHLTConfigurationHandler()),
44   fTaskList()
45 {
46   // see header file for class documentation
47   // or
48   // refer to README to build package
49   // or
50   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
51
52   if (fgNofInstances++>0)
53     HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
54
55   SetGlobalLoggingLevel(kHLTLogDefault);
56   if (fpComponentHandler) {
57     AliHLTComponentEnvironment env;
58     memset(&env, 0, sizeof(AliHLTComponentEnvironment));
59     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
60     env.fLoggingFunc=NULL;
61     fpComponentHandler->SetEnvironment(&env);
62   } else {
63     HLTFatal("can not create Component Handler");
64   }
65   if (fpConfigurationHandler) {
66     AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
67   } else {
68     HLTFatal("can not create Configuration Handler");
69   }
70 }
71
72 AliHLTSystem::AliHLTSystem(const AliHLTSystem&)
73   :
74   AliHLTLogging(),
75   fpComponentHandler(NULL),
76   fpConfigurationHandler(NULL),
77   fTaskList()
78 {
79   // see header file for class documentation
80   if (fgNofInstances++>0)
81     HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
82
83   HLTFatal("copy constructor untested");
84 }
85
86 AliHLTSystem& AliHLTSystem::operator=(const AliHLTSystem&)
87
88   // see header file for class documentation
89   HLTFatal("assignment operator untested");
90   return *this;
91 }
92
93 AliHLTSystem::~AliHLTSystem()
94 {
95   // see header file for class documentation
96   fgNofInstances--;
97   CleanTaskList();
98   AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
99   if (fpConfigurationHandler) {
100     delete fpConfigurationHandler;
101   }
102   fpConfigurationHandler=NULL;
103   
104   if (fpComponentHandler) {
105     delete fpComponentHandler;
106   }
107   fpComponentHandler=NULL;
108 }
109
110 int AliHLTSystem::fgNofInstances=0;
111
112 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
113 {
114   // see header file for class documentation
115   int iResult=0;
116   if (pConf) {
117   } else {
118     iResult=-EINVAL;
119   }
120   return iResult;
121 }
122
123 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
124 {
125   // see header file for class documentation
126   int iResult=0;
127   if (pConf) {
128     if (pPrec) {
129       // find the position
130     }
131   } else {
132     iResult=-EINVAL;
133   }
134   return iResult;
135 }
136
137 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
138 {
139   // see header file for class documentation
140   int iResult=0;
141   if (pConf) {
142   } else {
143     iResult=-EINVAL;
144   }
145   return iResult;
146 }
147
148 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
149 {
150   // see header file for class documentation
151   int iResult=0;
152   if (pConf) {
153     AliHLTTask* pTask=NULL;
154     if ((pTask=FindTask(pConf->GetName()))!=NULL) {
155       if (pTask->GetConf()!=pConf) {
156         HLTError("configuration missmatch, there is already a task with configuration name \"%s\", but it is different. Most likely configuration %p is not registered properly", pConf->GetName(), pConf);
157         iResult=-EEXIST;
158         pTask=NULL;
159       }
160     } else if (pConf->SourcesResolved(1)!=1) {
161         HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
162         iResult=-ENOLINK;
163     } else {
164       pTask=new AliHLTTask(pConf);
165       if (pTask==NULL) {
166         iResult=-ENOMEM;
167       }
168     }
169     if (pTask) {
170       // check for circular dependencies
171       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
172         HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
173         pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
174         HLTError("aborted ...");
175         iResult=-ELOOP;
176       }
177       if (iResult>=0) {
178         // check whether all dependencies are already in the task list
179         // create the missing ones
180         // this step is an iterative process which calls this function again for the missing
181         // configurations, in order to avoid the currently processed task to be created
182         // again it is added to the list temporarily and removed afterwards
183         // This is of high importance to preserve the order of the tasks. Furthermore, the
184         // InsertTask method has to be used in order to set all the cross links right 
185         fTaskList.Add(pTask);
186         AliHLTConfiguration* pDep=pConf->GetFirstSource();
187         while (pDep!=NULL && iResult>=0) {
188           if (FindTask(pDep->GetName())==NULL) {
189             iResult=BuildTaskList(pDep);
190           }
191           pDep=pConf->GetNextSource();
192         }
193         // remove the temporarily added task
194         fTaskList.Remove(pTask);
195
196         // insert the task and set the cross-links
197         if (iResult>=0) {
198           iResult=InsertTask(pTask);
199         }
200       } else {
201         delete pTask;
202         pTask=NULL;
203       }
204     }
205   } else {
206     iResult=-EINVAL;
207   }
208   return iResult;
209 }
210
211 int AliHLTSystem::CleanTaskList()
212 {
213   // see header file for class documentation
214   int iResult=0;
215   TObjLink* lnk=NULL;
216   while ((lnk=fTaskList.FirstLink())!=NULL) {
217     fTaskList.Remove(lnk);
218     delete (lnk->GetObject());
219   }
220   return iResult;
221 }
222
223 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
224 {
225   // see header file for class documentation
226   int iResult=0;
227   TObjLink *lnk = NULL;
228   if ((iResult=pTask->CheckDependencies())>0)
229     lnk=fTaskList.FirstLink();
230   while (lnk && iResult>0) {
231     AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
232     //HLTDebug("checking  \"%s\"", pCurr->GetName());
233     iResult=pTask->Depends(pCurr);
234     if (iResult>0) {
235       iResult=pTask->SetDependency(pCurr);
236       pCurr->SetTarget(pTask);
237       HLTDebug("set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
238     }
239     if (pCurr->Depends(pTask)) {
240       // circular dependency
241       HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
242       iResult=-ELOOP;
243     } else if ((iResult=pTask->CheckDependencies())>0) {
244       lnk = lnk->Next();
245     }
246   }
247   if (iResult==0) {
248       if (lnk) {
249         fTaskList.AddAfter(lnk, pTask);
250       } else {
251         fTaskList.AddFirst(pTask);
252       }
253       HLTDebug("task \"%s\" inserted", pTask->GetName());
254   } else if (iResult>0) {
255     HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
256     iResult=-ENOLINK;
257   }
258   return iResult;
259 }
260
261 AliHLTTask* AliHLTSystem::FindTask(const char* id)
262 {
263   // see header file for class documentation
264   AliHLTTask* pTask=NULL;
265   if (id) {
266     pTask=(AliHLTTask*)fTaskList.FindObject(id); 
267   }
268   return pTask;
269 }
270
271 void AliHLTSystem::PrintTaskList()
272 {
273   // see header file for class documentation
274   HLTLogKeyword("task list");
275   TObjLink *lnk = NULL;
276   HLTMessage("Task List");
277   lnk=fTaskList.FirstLink();
278   while (lnk) {
279     TObject* obj=lnk->GetObject();
280     if (obj) {
281       HLTMessage("  %s - status:", obj->GetName());
282       AliHLTTask* pTask=(AliHLTTask*)obj;
283       pTask->PrintStatus();
284     } else {
285     }
286     lnk = lnk->Next();
287   }
288 }
289
290 int AliHLTSystem::Run(Int_t iNofEvents) 
291 {
292   // see header file for class documentation
293   int iResult=0;
294   if ((iResult=InitTasks())>=0) {
295     if ((iResult=StartTasks())>=0) {
296       for (int i=0; i<iNofEvents && iResult>=0; i++) {
297         iResult=ProcessTasks(i);
298         if (iResult>=0) {
299           HLTInfo("Event %d successfully finished (%d)", i, iResult);
300           iResult=0;
301         } else {
302           HLTError("Processing of event %d failed (%d)", i, iResult);
303           // TODO: define different running modes to either ignore errors in
304           // event processing or not
305           // currently ignored 
306           //iResult=0;
307         }
308       }
309       StopTasks();
310     } else {
311       HLTError("can not start task list");
312     }
313     DeinitTasks();
314   } else if (iResult!=-ENOENT) {
315     HLTError("can not initialize task list");
316   }
317   return iResult;
318 }
319
320 int AliHLTSystem::InitTasks()
321 {
322   // see header file for class documentation
323   int iResult=0;
324   TObjLink *lnk=fTaskList.FirstLink();
325   if (lnk==NULL) {
326     HLTWarning("Task list is empty, aborting ...");
327     return -ENOENT;
328   }
329   while (lnk && iResult>=0) {
330     TObject* obj=lnk->GetObject();
331     if (obj) {
332       AliHLTTask* pTask=(AliHLTTask*)obj;
333       iResult=pTask->Init(NULL, fpComponentHandler);
334     } else {
335     }
336     lnk = lnk->Next();
337   }
338   if (iResult<0) {
339   }
340   return iResult;
341 }
342
343 int AliHLTSystem::StartTasks()
344 {
345   // see header file for class documentation
346   int iResult=0;
347   TObjLink *lnk=fTaskList.FirstLink();
348   while (lnk && iResult>=0) {
349     TObject* obj=lnk->GetObject();
350     if (obj) {
351       AliHLTTask* pTask=(AliHLTTask*)obj;
352       iResult=pTask->StartRun();
353     } else {
354     }
355     lnk = lnk->Next();
356   }
357   if (iResult<0) {
358   }
359   return iResult;
360 }
361
362 int AliHLTSystem::ProcessTasks(Int_t eventNo)
363 {
364   // see header file for class documentation
365   int iResult=0;
366   HLTDebug("processing event no %d", eventNo);
367   TObjLink *lnk=fTaskList.FirstLink();
368   while (lnk && iResult>=0) {
369     TObject* obj=lnk->GetObject();
370     if (obj) {
371       AliHLTTask* pTask=(AliHLTTask*)obj;
372       iResult=pTask->ProcessTask(eventNo);
373       HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
374     } else {
375     }
376     lnk = lnk->Next();
377   }
378   return iResult;
379 }
380
381 int AliHLTSystem::StopTasks()
382 {
383   // see header file for class documentation
384   int iResult=0;
385   TObjLink *lnk=fTaskList.FirstLink();
386   while (lnk && iResult>=0) {
387     TObject* obj=lnk->GetObject();
388     if (obj) {
389       AliHLTTask* pTask=(AliHLTTask*)obj;
390       iResult=pTask->EndRun();
391     } else {
392     }
393     lnk = lnk->Next();
394   }
395   return iResult;
396 }
397
398 int AliHLTSystem::DeinitTasks()
399 {
400   // see header file for class documentation
401   int iResult=0;
402   TObjLink *lnk=fTaskList.FirstLink();
403   while (lnk && iResult>=0) {
404     TObject* obj=lnk->GetObject();
405     if (obj) {
406       AliHLTTask* pTask=(AliHLTTask*)obj;
407       iResult=pTask->Deinit();
408     } else {
409     }
410     lnk = lnk->Next();
411   }
412   return iResult;
413 }
414
415 void* AliHLTSystem::AllocMemory( void* param, unsigned long size )
416 {
417   // see header file for class documentation
418   return (void*)new char[size];
419 }