logging class extended and macros for easy log messages introduced, code changed...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTConfiguration.cxx
1 // $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          for The ALICE Off-line Project.                               *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          *
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // HLT configuration handling                                             //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #if __GNUC__== 3
25 using namespace std;
26 #endif
27
28 #include <errno.h>
29 #include "AliHLTConfiguration.h"
30 #include "AliHLTComponent.h"
31 #include "AliHLTComponentHandler.h"
32 #include <iostream>
33 #include <string.h>
34
35 ClassImp(AliHLTConfiguration)
36
37 /* the global configuration handler which is used to automatically register the configuration
38  */
39 AliHLTConfigurationHandler* AliHLTConfiguration::fConfigurationHandler=NULL;
40
41 AliHLTConfiguration::AliHLTConfiguration()
42
43   fID=NULL;
44   fComponent=NULL;
45   fStringSources=NULL;
46   fNofSources=-1;
47   fArguments=NULL;
48   fArgc=-1;
49   fArgv=NULL;
50   fListSrcElement=fListSources.begin();
51 }
52
53 AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
54 {
55   fArgc=-1;
56   fArgv=NULL;
57   
58   if (id && component) {
59     fID=id;
60     fComponent=component;
61     fStringSources=sources;
62     fNofSources=-1;
63     fArguments=arguments;
64     fListSrcElement=fListSources.begin();
65     if (fConfigurationHandler) {
66       fConfigurationHandler->RegisterConfiguration(this);
67     } else {
68       HLTError("no configuration handler set, abort registration");
69     }
70   }
71 }
72
73 AliHLTConfiguration::~AliHLTConfiguration()
74 {
75   if (fConfigurationHandler) {
76     if (fConfigurationHandler->FindConfiguration(fID)!=NULL) {
77       fConfigurationHandler->RemoveConfiguration(this);
78     }
79   }
80   if (fArgv != NULL) {
81     if (fArgc>0) {
82       for (int i=0; i<fArgc; i++) {
83         delete[] fArgv[i];
84       }
85     }
86     delete[] fArgv;
87     fArgv=NULL;
88   }
89 }
90
91 int AliHLTConfiguration::GlobalInit(AliHLTConfigurationHandler* pHandler)
92 {
93   int iResult=0;
94   if (fConfigurationHandler!=NULL) {
95     fConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalInit", HLT_DEFAULT_LOG_KEYWORD, "configuration handler already initialized, overriding object %p", fConfigurationHandler);
96   }
97   fConfigurationHandler=pHandler;
98   return iResult;
99 }
100
101 int AliHLTConfiguration::GlobalDeinit()
102 {
103   int iResult=0;
104   fConfigurationHandler=NULL;
105   return iResult;
106 }
107
108 const char* AliHLTConfiguration::GetName() const {
109   if (fID)
110     return fID;
111   return TObject::GetName();
112 }
113
114 AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
115 {
116   AliHLTConfiguration* pSrc=NULL;
117   if (id) {
118     // first check the current element
119     if (fListSrcElement!=fListSources.end() && strcmp(id, (*fListSrcElement)->GetName())==0) {
120       pSrc=*fListSrcElement;
121       } else {
122       // check the list
123
124       pSrc=GetFirstSource();
125       while (pSrc) {
126         if (strcmp(id, pSrc->GetName())==0)
127           break;
128         pSrc=GetNextSource();
129       }
130     }
131   }
132   return pSrc;
133 }
134
135 AliHLTConfiguration* AliHLTConfiguration::GetFirstSource()
136 {
137   AliHLTConfiguration* pSrc=NULL;
138   if (fNofSources>=0 || ExtractSources()) {
139     fListSrcElement=fListSources.begin();
140     if (fListSrcElement!=fListSources.end()) pSrc=*fListSrcElement;
141   } 
142   return pSrc;
143 }
144
145 AliHLTConfiguration* AliHLTConfiguration::GetNextSource()
146 {
147   AliHLTConfiguration* pSrc=NULL;
148   if (fNofSources>0) {
149     if (fListSrcElement!=fListSources.end() && (++fListSrcElement)!=fListSources.end()) 
150       pSrc=*fListSrcElement;
151   } 
152   return pSrc;
153 }
154
155 int AliHLTConfiguration::SourcesResolved(int bAuto) 
156 {
157   int iResult=0;
158   if (fNofSources>=0 || bAuto && (iResult=ExtractSources())>=0) {
159     //HLTDebug("fNofSources=%d", fNofSources);
160     //HLTDebug("list size = %d", fListSources.size());
161     iResult=fNofSources==(int)fListSources.size();
162   }
163   return iResult;
164 }
165
166 int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
167 {
168   int iResult=0;
169   if (pConf) {
170     vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
171     while (element!=fListSources.end()) {
172       if (*element==pConf) {
173         fListSources.erase(element);
174         fListSrcElement=fListSources.end();
175         // there is no need to re-evaluate until there was a new configuration registered
176         // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
177         //InvalidateSources();
178         break;
179       }
180       element++;
181     }
182   } else {
183     iResult=-EINVAL;
184   }
185   return iResult;
186 }
187
188 void AliHLTConfiguration::PrintStatus()
189 {
190   HLTLogKeyword("configuration status");
191   HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
192   if (fComponent) HLTMessage("  - component: \"%s\"", fComponent);
193   else HLTMessage("  - component string invalid");
194   if (fStringSources) HLTMessage("  - sources: \"%s\"", fStringSources);
195   else HLTMessage("  - no sources");
196   if (SourcesResolved(1)<=0)
197     HLTMessage("    there are unresolved sources");
198   AliHLTConfiguration* pSrc=GetFirstSource();
199   while (pSrc) {
200     HLTMessage("    source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
201     pSrc=GetNextSource();
202   }
203 }
204
205 int AliHLTConfiguration::GetArguments(int* pArgc, const char*** pArgv)
206 {
207   int iResult=0;
208   if (pArgc && pArgv) {
209     *pArgc=fArgc;
210     *pArgv=(const char**)fArgv;
211   } else {
212     iResult=-EINVAL;
213   }
214   return iResult;
215 }
216
217
218 int AliHLTConfiguration::ExtractSources()
219 {
220   int iResult=0;
221   fNofSources=0;
222   if (fStringSources!=NULL) {
223     vector<char*> tgtList;
224     fListSources.clear();
225     if ((iResult=InterpreteString(fStringSources, tgtList))>=0) {
226       fNofSources=tgtList.size();
227       vector<char*>::iterator element=tgtList.begin();
228       while ((element=tgtList.begin())!=tgtList.end()) {
229         if (fConfigurationHandler) {
230           AliHLTConfiguration* pConf=fConfigurationHandler->FindConfiguration(*element);
231           if (pConf) {
232             HLTDebug("source \"%s\" inserted", pConf->GetName());
233             fListSources.push_back(pConf);
234           } else {
235             HLTError("can not find source \"%s\"", (*element));
236             iResult=-ENOENT;
237           }
238         } else if (iResult>=0) {
239           iResult=-EFAULT;
240           HLTFatal("global configuration handler not initialized, can not resolve sources");
241         }
242         delete[] (*element);
243         tgtList.erase(element);
244       }
245       fListSrcElement=fListSources.begin();
246     }
247   }
248   return iResult;
249 }
250
251 int AliHLTConfiguration::ExtractArguments()
252 {
253   int iResult=0;
254   if (fArguments!=NULL) {
255     vector<char*> tgtList;
256     if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
257       fArgc=tgtList.size();
258       //HLTDebug("found %d arguments", fArgc);
259       if (fArgc>0) {
260         fArgv = new char*[fArgc];
261         if (fArgv) {
262           vector<char*>::iterator element=tgtList.begin();
263           int i=0;
264           while (element!=tgtList.end()) {
265             //HLTDebug("assign arguments %d (%s)", i, *element);
266             fArgv[i++]=(*element);
267             element++;
268           }
269         } else {
270           iResult=-ENOMEM;
271         }
272       }
273     }
274   }
275   return iResult;
276 }
277
278 int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
279 {
280   int iResult=0;
281   if (arg) {
282     //HLTDebug("interprete \"%s\"", arg);
283     int i=0;
284     int prec=-1;
285     do {
286       if (arg[i]==0 || arg[i]==' ') {
287         if (prec>=0) {
288           char* pEntry= new char[i-prec+1];
289           if (pEntry) {
290             strncpy(pEntry, &arg[prec], i-prec);
291             pEntry[i-prec]=0; // terminate string
292             //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
293             argList.push_back(pEntry);
294           } else 
295             iResult=-ENOMEM;
296           prec=-1;
297         }
298       } else if (prec==-1) prec=i;
299     } while (arg[i++]!=0 && iResult>=0); 
300   } else {
301     iResult=-EINVAL;
302   }
303   return iResult;
304 }
305
306 int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
307 {
308   int iResult=0;
309   if (id) {
310     AliHLTConfiguration* pDep=NULL;
311     if ((pDep=GetSource(id))!=NULL) {
312       if (pTgtList) pTgtList->Add(pDep);
313       iResult++;
314     } else {
315       pDep=GetFirstSource();
316       while (pDep && iResult==0) {
317         if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
318           if (pTgtList) pTgtList->AddFirst(pDep);
319           iResult++;
320         }
321         pDep=GetNextSource();
322       }
323     }
324   } else {
325     iResult=-EINVAL;
326   }
327   return iResult;
328 }
329
330 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
331
332 ClassImp(AliHLTTask)
333
334 AliHLTTask::AliHLTTask()
335 {
336   fpConfiguration=NULL;
337   fpComponent=NULL;
338   fpBlockDataArray=NULL;
339 }
340
341 AliHLTTask::AliHLTTask(AliHLTConfiguration* fConf, AliHLTComponentHandler* pCH)
342 {
343   fpConfiguration=NULL;
344   fpComponent=NULL;
345   fpBlockDataArray=NULL;
346   Init(fConf, pCH);
347 }
348
349 AliHLTTask::~AliHLTTask()
350 {
351   if (fpComponent) delete fpComponent;
352   fpComponent=NULL;
353   if (fpBlockDataArray) delete[] fpBlockDataArray;
354   fpBlockDataArray=NULL;
355 }
356
357 int AliHLTTask::Init(AliHLTConfiguration* fConf, AliHLTComponentHandler* pCH)
358 {
359   int iResult=0;
360   if (fConf) {
361     fpConfiguration=fConf;
362     if (pCH) {
363       int argc=0;
364       const char** argv=NULL;
365       if ((iResult=fConf->GetArguments(&argc, &argv))>=0) {
366         iResult=pCH->CreateComponent(fConf->GetComponentID(), NULL, argc, argv, fpComponent);
367         if (fpComponent) {
368         } else {
369           HLTError("can not find component \"%s\"", fConf->GetComponentID());
370         }
371       }
372     }
373   } else {
374     iResult=-EINVAL;
375   }
376   return iResult;
377 }
378
379 const char *AliHLTTask::GetName() const
380 {
381   if (fpConfiguration)
382     return fpConfiguration->GetName();
383   return TObject::GetName();
384 }
385
386 AliHLTConfiguration* AliHLTTask::GetConf()
387 {
388   return fpConfiguration;
389 }
390
391 AliHLTComponent* AliHLTTask::GetComponent()
392 {
393   return fpComponent;
394 }
395
396 AliHLTTask* AliHLTTask::FindDependency(const char* id)
397 {
398   AliHLTTask* pTask=NULL;
399   if (id) {
400     pTask=(AliHLTTask*)fListDependencies.FindObject(id);
401   }
402   return pTask;
403 }
404
405 int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
406 {
407   int iResult=0;
408   if (id) {
409     AliHLTTask* pDep=NULL;
410     if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
411       if (pTgtList) pTgtList->Add(pDep);
412       iResult++;
413     } else {
414       TObjLink* lnk=fListDependencies.FirstLink();
415       while (lnk && iResult==0) {
416         pDep=(AliHLTTask*)lnk->GetObject();
417         if (pDep) {
418           if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
419             if (pTgtList) pTgtList->AddFirst(pDep);
420             iResult++;
421           }
422         } else {
423           iResult=-EFAULT;
424         }
425         lnk=lnk->Next();
426       }
427     }
428   } else {
429     iResult=-EINVAL;
430   }
431   return iResult;
432 }
433
434 void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
435 {
436   HLTLogKeyword("task dependencies");
437   int iResult=0;
438   TList tgtList;
439   if (bFromConfiguration) {
440     if (fpConfiguration)
441       iResult=fpConfiguration->FollowDependency(id, &tgtList);
442     else
443       iResult=-EFAULT;
444   } else
445     iResult=FollowDependency(id, &tgtList);
446   if (iResult>0) {
447     HLTMessage("     task \"%s\": dependency level %d ", GetName(), iResult);
448     TObjLink* lnk=tgtList.FirstLink();
449     int i=iResult;
450     char* pSpace = new char[iResult+1];
451     if (pSpace) {
452       memset(pSpace, 32, iResult);
453       pSpace[i]=0;
454       while (lnk) {
455         TObject* obj=lnk->GetObject();
456         HLTMessage("     %s^-- %s ", &pSpace[i--], obj->GetName());
457         lnk=lnk->Next();
458       }
459       delete [] pSpace;
460     } else {
461       iResult=-ENOMEM;
462     }
463   }
464 }
465
466 int AliHLTTask::InsertBlockData(AliHLTComponent_BlockData* pBlock, AliHLTTask* pSource)
467 {
468   int iResult=0;
469   return iResult;
470 }
471
472 int AliHLTTask::SetDependency(AliHLTTask* pDep)
473 {
474   int iResult=0;
475   if (pDep) {
476     if (FindDependency(pDep->GetName())==NULL) {
477       fListDependencies.Add(pDep);
478     } else {
479       iResult=-EEXIST;
480     }
481   } else {
482     iResult=-EINVAL;
483   }
484   return iResult;
485 }
486
487 int AliHLTTask::CheckDependencies()
488 {
489   int iResult=0;
490   AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
491   while (pSrc) {
492     if (FindDependency(pSrc->GetName())==NULL) {
493       //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
494       iResult++;
495     }
496     pSrc=fpConfiguration->GetNextSource();
497   }
498   return iResult;
499 }
500
501
502 int AliHLTTask::Depends(AliHLTTask* pTask)
503 {
504   int iResult=0;
505   if (pTask) {
506     if (fpConfiguration) {
507       iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
508       if (iResult>0) {
509         //HLTDebug("task  \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
510       } else {
511         //HLTDebug("task  \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
512       }
513     } else {
514       iResult=-EFAULT;
515     }
516   } else {
517     iResult=-EINVAL;
518   }
519   return iResult;
520 }
521
522 AliHLTTask* AliHLTTask::FindTarget(const char* id)
523 {
524   AliHLTTask* pTask=NULL;
525   if (id) {
526     pTask=(AliHLTTask*)fListTargets.FindObject(id);
527   }
528   return pTask;
529 }
530
531 int AliHLTTask::SetTarget(AliHLTTask* pTgt)
532 {
533   int iResult=0;
534   if (pTgt) {
535     if (FindTarget(pTgt->GetName())==NULL) {
536       fListTargets.Add(pTgt);
537     } else {
538       iResult=-EEXIST;
539     }
540   } else {
541     iResult=-EINVAL;
542   }
543   return iResult;
544 }
545
546 int AliHLTTask::BuildBlockDataArray(AliHLTComponent_BlockData*& pTgt)
547 {
548   int iResult=0;
549   return iResult;
550 }
551
552
553 // int AliHLTTask::ProcessTask(...)
554 // {
555 //   int iResult=0;
556 //   return iResult;
557 // }
558
559
560 int AliHLTTask::ClearSourceBlocks()
561 {
562   int iResult=0;
563   return iResult;
564 }
565
566 void AliHLTTask::PrintStatus()
567 {
568   HLTLogKeyword("task properties");
569   if (fpComponent) {
570     HLTMessage("     component: %s (%p)", fpComponent->GetComponentID(), fpComponent);
571   } else {
572     HLTMessage("     no component set!");
573   }
574   if (fpConfiguration) {
575     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
576     while (pSrc) {
577       const char* pQualifier="unresolved";
578       if (FindDependency(pSrc->GetName()))
579         pQualifier="resolved";
580       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
581       pSrc=fpConfiguration->GetNextSource();
582     }
583     TObjLink* lnk = fListTargets.FirstLink();
584     while (lnk) {
585       TObject *obj = lnk->GetObject();
586       HLTMessage("     target: %s", obj->GetName());
587       lnk = lnk->Next();
588     }
589   } else {
590     HLTMessage("     task \"%s\" not initialized", GetName());
591   }
592 }
593
594 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
595
596 TList AliHLTConfigurationHandler::fListConfigurations;
597 TList AliHLTConfigurationHandler::fListDynamicConfigurations;
598
599 ClassImp(AliHLTConfigurationHandler)
600
601 AliHLTConfigurationHandler::AliHLTConfigurationHandler()
602 {
603 }
604
605 AliHLTConfigurationHandler::~AliHLTConfigurationHandler()
606 {
607   TObjLink* lnk=fListDynamicConfigurations.FirstLink();
608   while (lnk) {
609     TObject* obj=lnk->GetObject();
610     if (fListConfigurations.FindObject(obj->GetName())==NULL) {
611       HLTDebug("delete dynamic configuration \"%s\"", obj->GetName());
612       delete obj;
613     }
614     lnk=lnk->Next();
615   }
616 }
617
618 int AliHLTConfigurationHandler::RegisterConfiguration(AliHLTConfiguration* pConf)
619 {
620   int iResult=0;
621   if (pConf) {
622     if (FindConfiguration(pConf->GetName()) == NULL) {
623       fListConfigurations.Add(pConf);
624       //HLTDebug("configuration \"%s\" registered", pConf->GetName());
625
626       // mark all configurations with unresolved dependencies for re-evaluation
627       TObjLink* lnk=fListConfigurations.FirstLink();
628       while (lnk) {
629         AliHLTConfiguration* pSrc=(AliHLTConfiguration*)lnk->GetObject();
630         if (pSrc && pSrc!=pConf && pSrc->SourcesResolved()!=1) {
631           pSrc->InvalidateSources();
632         }
633         lnk=lnk->Next();
634       }
635     } else {
636       iResult=-EEXIST;
637       HLTWarning("configuration \"%s\" already registered", pConf->GetName());
638     }
639   } else {
640     iResult=-EINVAL;
641   }
642   return iResult;
643 }
644
645 int AliHLTConfigurationHandler::CreateConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
646 {
647   int iResult=0;
648   AliHLTConfiguration* pConf= new AliHLTConfiguration(id, component, sources, arguments);
649   if (pConf) {
650     // the configuration will be registered automatically, if this failes the configuration
651     // is missing -> delete it
652     if (FindConfiguration(id)==NULL) {
653       delete pConf;
654       pConf=NULL;
655       iResult=-EEXIST;
656     } else {
657       fListDynamicConfigurations.Add(pConf);
658     }
659   } else {
660     HLTError("system error: object allocation failed");
661     iResult=-ENOMEM;
662   }
663   return iResult;
664 }
665
666 void AliHLTConfigurationHandler::PrintConfigurations()
667 {
668   HLTLogKeyword("configuration listing");
669   HLTMessage("registered configurations:");
670   TObjLink *lnk = fListConfigurations.FirstLink();
671   while (lnk) {
672     TObject *obj = lnk->GetObject();
673     HLTMessage("  %s", obj->GetName());
674     lnk = lnk->Next();
675   }
676 }
677
678 int AliHLTConfigurationHandler::RemoveConfiguration(const char* id)
679 {
680   int iResult=0;
681   if (id) {
682     AliHLTConfiguration* pConf=NULL;
683     if ((pConf=FindConfiguration(id))!=NULL) {
684       iResult=RemoveConfiguration(pConf);
685     } else {
686       HLTWarning("can not find configuration \"%s\"", id);
687       iResult=-ENOENT;
688     }
689   } else {
690     iResult=-EINVAL;
691   }
692   return iResult;
693 }
694
695 int AliHLTConfigurationHandler::RemoveConfiguration(AliHLTConfiguration* pConf)
696 {
697   int iResult=0;
698   if (pConf) {
699     // remove the configuration from the list
700     fListConfigurations.Remove(pConf);
701     // remove cross links in the remaining configurations
702     TObjLink* lnk=fListConfigurations.FirstLink();
703     while (lnk && iResult>=0) {
704       AliHLTConfiguration* pRem=(AliHLTConfiguration*)lnk->GetObject();
705       if (pRem) {
706         pRem->InvalidateSource(pConf);
707       } else {
708         iResult=-EFAULT;
709       }
710       lnk=lnk->Next();
711     }
712   }
713   return iResult;
714 }
715
716 AliHLTConfiguration* AliHLTConfigurationHandler::FindConfiguration(const char* id)
717 {
718   AliHLTConfiguration* pConf=NULL;
719   if (id) {
720     pConf=(AliHLTConfiguration*)fListConfigurations.FindObject(id); 
721   }
722   return pConf;
723 }
724