3 /**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * for The ALICE Off-line Project. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // HLT configuration handling //
22 ///////////////////////////////////////////////////////////////////////////////
29 #include "AliHLTConfiguration.h"
30 #include "AliHLTConfigurationHandler.h"
31 #include "AliHLTTask.h"
32 #include "AliHLTComponent.h"
33 #include "AliHLTComponentHandler.h"
37 ClassImp(AliHLTConfiguration)
39 /* the global configuration handler which is used to automatically register the configuration
41 AliHLTConfigurationHandler* AliHLTConfiguration::fConfigurationHandler=NULL;
43 AliHLTConfiguration::AliHLTConfiguration()
52 fListSrcElement=fListSources.begin();
55 AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
60 if (id && component) {
63 fStringSources=sources;
66 fListSrcElement=fListSources.begin();
67 if (fConfigurationHandler) {
68 fConfigurationHandler->RegisterConfiguration(this);
70 HLTError("no configuration handler set, abort registration");
75 AliHLTConfiguration::~AliHLTConfiguration()
77 if (fConfigurationHandler) {
78 if (fConfigurationHandler->FindConfiguration(fID)!=NULL) {
79 fConfigurationHandler->RemoveConfiguration(this);
84 for (int i=0; i<fArgc; i++) {
93 int AliHLTConfiguration::GlobalInit(AliHLTConfigurationHandler* pHandler)
96 if (fConfigurationHandler!=NULL) {
97 fConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalInit", HLT_DEFAULT_LOG_KEYWORD, "configuration handler already initialized, overriding object %p", fConfigurationHandler);
99 fConfigurationHandler=pHandler;
103 int AliHLTConfiguration::GlobalDeinit()
106 fConfigurationHandler=NULL;
110 const char* AliHLTConfiguration::GetName() const {
113 return TObject::GetName();
116 AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
118 AliHLTConfiguration* pSrc=NULL;
120 // first check the current element
121 if (fListSrcElement!=fListSources.end() && strcmp(id, (*fListSrcElement)->GetName())==0) {
122 pSrc=*fListSrcElement;
126 pSrc=GetFirstSource();
128 if (strcmp(id, pSrc->GetName())==0)
130 pSrc=GetNextSource();
137 AliHLTConfiguration* AliHLTConfiguration::GetFirstSource()
139 AliHLTConfiguration* pSrc=NULL;
140 if (fNofSources>=0 || ExtractSources()) {
141 fListSrcElement=fListSources.begin();
142 if (fListSrcElement!=fListSources.end()) pSrc=*fListSrcElement;
147 AliHLTConfiguration* AliHLTConfiguration::GetNextSource()
149 AliHLTConfiguration* pSrc=NULL;
151 if (fListSrcElement!=fListSources.end() && (++fListSrcElement)!=fListSources.end())
152 pSrc=*fListSrcElement;
157 int AliHLTConfiguration::SourcesResolved(int bAuto)
160 if (fNofSources>=0 || bAuto && (iResult=ExtractSources())>=0) {
161 //HLTDebug("fNofSources=%d", fNofSources);
162 //HLTDebug("list size = %d", fListSources.size());
163 iResult=fNofSources==(int)fListSources.size();
168 int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
172 vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
173 while (element!=fListSources.end()) {
174 if (*element==pConf) {
175 fListSources.erase(element);
176 fListSrcElement=fListSources.end();
177 // there is no need to re-evaluate until there was a new configuration registered
178 // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
179 //InvalidateSources();
190 void AliHLTConfiguration::PrintStatus()
192 HLTLogKeyword("configuration status");
193 HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
194 if (fComponent) HLTMessage(" - component: \"%s\"", fComponent);
195 else HLTMessage(" - component string invalid");
196 if (fStringSources) HLTMessage(" - sources: \"%s\"", fStringSources);
197 else HLTMessage(" - no sources");
198 if (SourcesResolved(1)<=0)
199 HLTMessage(" there are unresolved sources");
200 AliHLTConfiguration* pSrc=GetFirstSource();
202 HLTMessage(" source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
203 pSrc=GetNextSource();
207 int AliHLTConfiguration::GetArguments(const char*** pArgv)
212 *pArgv=(const char**)fArgv;
220 int AliHLTConfiguration::ExtractSources()
224 if (fStringSources!=NULL) {
225 vector<char*> tgtList;
226 fListSources.clear();
227 if ((iResult=InterpreteString(fStringSources, tgtList))>=0) {
228 fNofSources=tgtList.size();
229 vector<char*>::iterator element=tgtList.begin();
230 while ((element=tgtList.begin())!=tgtList.end()) {
231 if (fConfigurationHandler) {
232 AliHLTConfiguration* pConf=fConfigurationHandler->FindConfiguration(*element);
234 HLTDebug("source \"%s\" inserted", pConf->GetName());
235 fListSources.push_back(pConf);
237 HLTError("can not find source \"%s\"", (*element));
240 } else if (iResult>=0) {
242 HLTFatal("global configuration handler not initialized, can not resolve sources");
245 tgtList.erase(element);
247 fListSrcElement=fListSources.begin();
253 int AliHLTConfiguration::ExtractArguments()
256 if (fArguments!=NULL) {
257 vector<char*> tgtList;
258 if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
259 fArgc=tgtList.size();
260 //HLTDebug("found %d arguments", fArgc);
262 fArgv = new char*[fArgc];
264 vector<char*>::iterator element=tgtList.begin();
266 while (element!=tgtList.end()) {
267 //HLTDebug("assign arguments %d (%s)", i, *element);
268 fArgv[i++]=(*element);
280 int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
284 //HLTDebug("interprete \"%s\"", arg);
288 if (arg[i]==0 || arg[i]==' ') {
290 char* pEntry= new char[i-prec+1];
292 strncpy(pEntry, &arg[prec], i-prec);
293 pEntry[i-prec]=0; // terminate string
294 //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
295 argList.push_back(pEntry);
300 } else if (prec==-1) prec=i;
301 } while (arg[i++]!=0 && iResult>=0);
308 int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
312 AliHLTConfiguration* pDep=NULL;
313 if ((pDep=GetSource(id))!=NULL) {
314 if (pTgtList) pTgtList->Add(pDep);
317 pDep=GetFirstSource();
318 while (pDep && iResult==0) {
319 if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
320 if (pTgtList) pTgtList->AddFirst(pDep);
323 pDep=GetNextSource();
332 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
336 AliHLTTask::AliHLTTask()
338 fpConfiguration=NULL;
340 fpBlockDataArray=NULL;
341 fBlockDataArraySize=0;
345 AliHLTTask::AliHLTTask(AliHLTConfiguration* fConf, AliHLTComponentHandler* pCH)
347 fpConfiguration=NULL;
349 fpBlockDataArray=NULL;
350 fBlockDataArraySize=0;
355 AliHLTTask::~AliHLTTask()
357 if (fpComponent) delete fpComponent;
359 if (fpBlockDataArray) delete[] fpBlockDataArray;
360 fpBlockDataArray=NULL;
363 int AliHLTTask::Init(AliHLTConfiguration* fConf, AliHLTComponentHandler* pCH)
367 fpConfiguration=fConf;
370 const char** argv=NULL;
371 if ((iResult=fConf->GetArguments(&argv))>=0) {
372 argc=iResult; // just to make it clear
373 iResult=pCH->CreateComponent(fConf->GetComponentID(), NULL, argc, argv, fpComponent);
376 HLTError("can not find component \"%s\"", fConf->GetComponentID());
386 const char *AliHLTTask::GetName() const
389 return fpConfiguration->GetName();
390 return TObject::GetName();
393 AliHLTConfiguration* AliHLTTask::GetConf() const
395 return fpConfiguration;
398 AliHLTComponent* AliHLTTask::GetComponent() const
403 AliHLTTask* AliHLTTask::FindDependency(const char* id)
405 AliHLTTask* pTask=NULL;
407 pTask=(AliHLTTask*)fListDependencies.FindObject(id);
412 int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
416 AliHLTTask* pDep=NULL;
417 if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
418 if (pTgtList) pTgtList->Add(pDep);
421 TObjLink* lnk=fListDependencies.FirstLink();
422 while (lnk && iResult==0) {
423 pDep=(AliHLTTask*)lnk->GetObject();
425 if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
426 if (pTgtList) pTgtList->AddFirst(pDep);
441 void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
443 HLTLogKeyword("task dependencies");
446 if (bFromConfiguration) {
448 iResult=fpConfiguration->FollowDependency(id, &tgtList);
452 iResult=FollowDependency(id, &tgtList);
454 HLTMessage(" task \"%s\": dependency level %d ", GetName(), iResult);
455 TObjLink* lnk=tgtList.FirstLink();
457 char* pSpace = new char[iResult+1];
459 memset(pSpace, 32, iResult);
462 TObject* obj=lnk->GetObject();
463 HLTMessage(" %s^-- %s ", &pSpace[i--], obj->GetName());
473 /* this function is most likely depricated
474 int AliHLTTask::InsertBlockData(AliHLTComponent_BlockData* pBlock, AliHLTTask* pSource)
481 int AliHLTTask::SetDependency(AliHLTTask* pDep)
485 if (FindDependency(pDep->GetName())==NULL) {
486 fListDependencies.Add(pDep);
496 int AliHLTTask::CheckDependencies()
499 AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
501 if (FindDependency(pSrc->GetName())==NULL) {
502 //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
505 pSrc=fpConfiguration->GetNextSource();
511 int AliHLTTask::Depends(AliHLTTask* pTask)
515 if (fpConfiguration) {
516 iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
518 //HLTDebug("task \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
520 //HLTDebug("task \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
531 AliHLTTask* AliHLTTask::FindTarget(const char* id)
533 AliHLTTask* pTask=NULL;
535 pTask=(AliHLTTask*)fListTargets.FindObject(id);
540 int AliHLTTask::SetTarget(AliHLTTask* pTgt)
544 if (FindTarget(pTgt->GetName())==NULL) {
545 fListTargets.Add(pTgt);
555 /* this function is most likely depricated
556 int AliHLTTask::BuildBlockDataArray(AliHLTComponent_BlockData*& pBlockData)
563 int AliHLTTask::StartRun()
566 int iNofInputDataBlocks=0;
567 AliHLTComponent* pComponent=GetComponent();
569 // determine the number of input data blocks provided from the source tasks
570 TObjLink* lnk=fListDependencies.FirstLink();
571 while (lnk && iResult>=0) {
572 AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
574 if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
575 iNofInputDataBlocks+=iResult;
576 } else if (iResult==0) {
577 HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
579 HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
586 if (fpBlockDataArray) {
587 HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
588 delete [] fpBlockDataArray;
589 fpBlockDataArray=NULL;
590 fBlockDataArraySize=0;
594 //iResult=Init( AliHLTComponentEnvironment* environ, void* environ_param, int argc, const char** argv );
596 // allocate internal task varables for bookkeeping aso.
597 fpBlockDataArray=new AliHLTComponent_BlockData[iNofInputDataBlocks];
598 if (fpBlockDataArray) {
599 fBlockDataArraySize=iNofInputDataBlocks;
601 HLTError("memory allocation failed");
606 HLTError("task %s (%p) does not have a component", GetName(), this);
612 int AliHLTTask::EndRun()
618 int AliHLTTask::ProcessTask()
621 if (fpComponent && fpBlockDataArray) {
622 int iSourceDataBlock=0;
623 int iInputDataVolume=0;
625 int iNofInputDataBlocks=0;
626 /* TODO: the assumption of only one output data type per component is the current constraint
627 * later it should be checked how many output blocks of the source component match the input
628 * data types of the consumer component (GetNofMatchingDataBlocks). If one assumes that a
629 * certain output block is always been produced, the initialization could be done in the
630 * StartRun. Otherwise the fpBlockDataArray has to be adapted each time.
632 iNofInputDataBlocks=fListDependencies.GetSize(); // one block per source
633 // is not been used since the allocation was done in StartRun, but check the size
634 if (iNofInputDataBlocks>fBlockDataArraySize) {
635 HLTError("block data array too small");
638 AliHLTTask* pSrcTask=NULL;
639 TList subscribedTaskList;
640 TObjLink* lnk=fListDependencies.FirstLink();
642 // subscribe to all source tasks
643 while (lnk && iResult>=0) {
644 pSrcTask=(AliHLTTask*)lnk->GetObject();
646 if (pSrcTask->GetNofMatchingDataBlocks(this)<fBlockDataArraySize-iSourceDataBlock) {
647 if ((iResult=pSrcTask->Subscribe(this, &fpBlockDataArray[iSourceDataBlock],fBlockDataArraySize-iSourceDataBlock))>0) {
648 for (int i=0; i<iResult; i++) {
649 iInputDataVolume+=fpBlockDataArray[i+iSourceDataBlock].fSize;
650 // put the source task as many times into the list as it provides data blocks
651 // makes the bookkeeping for the data release easier
652 subscribedTaskList.Add(pSrcTask);
654 iSourceDataBlock+=iResult;
655 HLTDebug("Task %s (%p) successfully subscribed to %d data blocks of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
658 HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
662 HLTFatal("Task %s (%p): too little space in data block array for subscription to task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
666 HLTFatal("fatal internal error in ROOT list handling");
674 long unsigned int iConstBase=0;
675 double fInputMultiplier=0;
676 fpComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
677 int iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
678 AliHLTUInt8_t* pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
679 AliHLTComponent_EventData evtData;
680 AliHLTComponent_TriggerData trigData;
681 AliHLTUInt32_t size=iOutputDataSize;
682 AliHLTUInt32_t outputBlockCnt=0;
683 AliHLTComponent_BlockData* outputBlocks=NULL;
684 AliHLTComponent_EventDoneData* edd;
685 if (pTgtBuffer!=NULL || iOutputDataSize==0) {
686 iResult=fpComponent->ProcessEvent(evtData, fpBlockDataArray, trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
691 // now release all buffers which we have subscribed to
693 lnk=subscribedTaskList.FirstLink();
695 pSrcTask=(AliHLTTask*)lnk->GetObject();
698 if ((iTempRes=pSrcTask->Release(&fpBlockDataArray[iSourceDataBlock], this))>=0) {
699 HLTDebug("Task %s (%p) successfully released task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
701 HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
704 HLTFatal("fatal internal error in ROOT list handling");
707 subscribedTaskList.Remove(lnk);
708 lnk=subscribedTaskList.FirstLink();
711 if (subscribedTaskList.GetSize()>0) {
712 HLTError("task %s (%p): could not release all data buffers", GetName(), this);
715 HLTError("internal failure: task not initialized");
721 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask)
726 iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
728 HLTFatal("internal data buffer missing");
737 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask)
741 AliHLTComponent* pComponent=GetComponent();
746 iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
748 HLTFatal("task initialization failed");
757 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponent_BlockData* pBlockDesc, int iArraySize)
762 iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), pBlockDesc, iArraySize);
764 HLTFatal("internal data buffer missing");
773 int AliHLTTask::Release(AliHLTComponent_BlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
776 if (pConsumerTask && pBlockDesc) {
778 iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent());
780 HLTFatal("internal data buffer missing");
789 /* this function is most likely depricated
790 int AliHLTTask::ClearSourceBlocks()
797 void AliHLTTask::PrintStatus()
799 HLTLogKeyword("task properties");
801 HLTMessage(" component: %s (%p)", fpComponent->GetComponentID(), fpComponent);
803 HLTMessage(" no component set!");
805 if (fpConfiguration) {
806 AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
808 const char* pQualifier="unresolved";
809 if (FindDependency(pSrc->GetName()))
810 pQualifier="resolved";
811 HLTMessage(" source: %s (%s)", pSrc->GetName(), pQualifier);
812 pSrc=fpConfiguration->GetNextSource();
814 TObjLink* lnk = fListTargets.FirstLink();
816 TObject *obj = lnk->GetObject();
817 HLTMessage(" target: %s", obj->GetName());
821 HLTMessage(" task \"%s\" not initialized", GetName());
825 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
827 TList AliHLTConfigurationHandler::fListConfigurations;
828 TList AliHLTConfigurationHandler::fListDynamicConfigurations;
830 ClassImp(AliHLTConfigurationHandler)
832 AliHLTConfigurationHandler::AliHLTConfigurationHandler()
836 AliHLTConfigurationHandler::~AliHLTConfigurationHandler()
838 TObjLink* lnk=fListDynamicConfigurations.FirstLink();
840 TObject* obj=lnk->GetObject();
841 if (fListConfigurations.FindObject(obj->GetName())==NULL) {
842 HLTDebug("delete dynamic configuration \"%s\"", obj->GetName());
849 int AliHLTConfigurationHandler::RegisterConfiguration(AliHLTConfiguration* pConf)
853 if (FindConfiguration(pConf->GetName()) == NULL) {
854 fListConfigurations.Add(pConf);
855 //HLTDebug("configuration \"%s\" registered", pConf->GetName());
857 // mark all configurations with unresolved dependencies for re-evaluation
858 TObjLink* lnk=fListConfigurations.FirstLink();
860 AliHLTConfiguration* pSrc=(AliHLTConfiguration*)lnk->GetObject();
861 if (pSrc && pSrc!=pConf && pSrc->SourcesResolved()!=1) {
862 pSrc->InvalidateSources();
868 HLTWarning("configuration \"%s\" already registered", pConf->GetName());
876 int AliHLTConfigurationHandler::CreateConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
879 AliHLTConfiguration* pConf= new AliHLTConfiguration(id, component, sources, arguments);
881 // the configuration will be registered automatically, if this failes the configuration
882 // is missing -> delete it
883 if (FindConfiguration(id)==NULL) {
888 fListDynamicConfigurations.Add(pConf);
891 HLTError("system error: object allocation failed");
897 void AliHLTConfigurationHandler::PrintConfigurations()
899 HLTLogKeyword("configuration listing");
900 HLTMessage("registered configurations:");
901 TObjLink *lnk = fListConfigurations.FirstLink();
903 TObject *obj = lnk->GetObject();
904 HLTMessage(" %s", obj->GetName());
909 int AliHLTConfigurationHandler::RemoveConfiguration(const char* id)
913 AliHLTConfiguration* pConf=NULL;
914 if ((pConf=FindConfiguration(id))!=NULL) {
915 iResult=RemoveConfiguration(pConf);
917 HLTWarning("can not find configuration \"%s\"", id);
926 int AliHLTConfigurationHandler::RemoveConfiguration(AliHLTConfiguration* pConf)
930 // remove the configuration from the list
931 fListConfigurations.Remove(pConf);
932 // remove cross links in the remaining configurations
933 TObjLink* lnk=fListConfigurations.FirstLink();
934 while (lnk && iResult>=0) {
935 AliHLTConfiguration* pRem=(AliHLTConfiguration*)lnk->GetObject();
937 pRem->InvalidateSource(pConf);
947 AliHLTConfiguration* AliHLTConfigurationHandler::FindConfiguration(const char* id)
949 AliHLTConfiguration* pConf=NULL;
951 pConf=(AliHLTConfiguration*)fListConfigurations.FindObject(id);