]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/BASE/AliHLTTask.cxx
files moved to TPC folder
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTTask.cxx
index b0f8caf73a4a723421f5c0b9c1ac84a6e4ad948f..024b6db4176602843cd9ec8c68392d6b94cb605f 100644 (file)
@@ -36,6 +36,7 @@ using namespace std;
 #include <cassert>
 #include <iostream>
 #include <string>
+#include <ctime>
 #include "AliHLTTask.h"
 #include "AliHLTConfiguration.h"
 #include "AliHLTComponent.h"
@@ -100,26 +101,45 @@ int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH)
   // see header file for function documentation
   int iResult=0;
   if (fpConfiguration!=NULL && pConf!=NULL && fpConfiguration!=pConf) {
-    HLTWarning("overriding existing reference to configuration object %p (%s) by %p",
-              fpConfiguration, GetName(), pConf);
+    HLTWarning("overriding existing reference to configuration object %p by %p",
+              fpConfiguration, pConf);
   }
   if (pConf!=NULL) fpConfiguration=pConf;
-  if (fpConfiguration) {
+  iResult=CreateComponent(fpConfiguration, pCH, fpComponent);
+  if (iResult>=0) {
+    iResult=CustomInit(pCH);
+  }
+  return iResult;
+}
+
+int AliHLTTask::CreateComponent(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH, AliHLTComponent*& pComponent) const
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (pConf) {
     if (pCH) {
       int argc=0;
       const char** argv=NULL;
-      if ((iResult=fpConfiguration->GetArguments(&argv))>=0) {
+      if ((iResult=pConf->GetArguments(&argv))>=0) {
        argc=iResult; // just to make it clear
        // TODO: we have to think about the optional environment parameter,
-       // currently just set to NULL. 
-       iResult=pCH->CreateComponent(fpConfiguration->GetComponentID(), NULL, argc, argv, fpComponent);
-       if (fpComponent || iResult<=0) {
-         //HLTDebug("component %s (%p) created", fpComponent->GetComponentID(), fpComponent); 
+       // currently just set to NULL.
+       iResult=pCH->CreateComponent(pConf->GetComponentID(), pComponent);
+       if (pComponent && iResult>=0) {
+         TString description;
+         description.Form("chainid=%s", GetName());
+         pComponent->SetComponentDescription(description.Data());
+         const AliHLTAnalysisEnvironment* pEnv=pCH->GetEnvironment();
+         if ((iResult=pComponent->Init(pEnv, NULL, argc, argv))>=0) {
+           //HLTDebug("component %s (%p) created", pComponent->GetComponentID(), pComponent); 
+         } else {
+           HLTError("Initialization of component \"%s\" failed with error %d", pComponent->GetComponentID(), iResult);
+         }
        } else {
-         //HLTError("can not find component \"%s\" (%d)", fpConfiguration->GetComponentID(), iResult);
+         //HLTError("can not find component \"%s\" (%d)", pConf->GetComponentID(), iResult);
        }
       } else {
-       HLTError("can not get argument list for configuration %s (%s)", fpConfiguration->GetName(), fpConfiguration->GetComponentID());
+       HLTError("can not get argument list for configuration %s (%s)", pConf->GetName(), pConf->GetComponentID());
        iResult=-EINVAL;
       }
     } else {
@@ -137,6 +157,7 @@ int AliHLTTask::Deinit()
 {
   // see header file for function documentation
   int iResult=0;
+  CustomCleanup();
   AliHLTComponent* pComponent=GetComponent();
   fpComponent=NULL;
   if (pComponent) {
@@ -144,7 +165,7 @@ int AliHLTTask::Deinit()
     pComponent->Deinit();
     delete pComponent;
   } else {
-    HLTWarning("task %s (%p) doesn't seem to be in initialized", GetName(), this);
+    HLTWarning("task doesn't seem to be in initialized");
   }
   return iResult;
 }
@@ -223,7 +244,7 @@ void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
   } else
     iResult=FollowDependency(id, &tgtList);
   if (iResult>0) {
-    HLTMessage("     task \"%s\": dependency level %d ", GetName(), iResult);
+    HLTMessage("     dependency level %d ", iResult);
     TObjLink* lnk=tgtList.FirstLink();
     int i=iResult;
     char* pSpace = new char[iResult+1];
@@ -346,6 +367,7 @@ int AliHLTTask::StartRun()
   AliHLTComponent* pComponent=GetComponent();
   if (pComponent) {
     // determine the number of input data blocks provided from the source tasks
+    { // set scope for lnk as a local variable
     TObjLink* lnk=fListDependencies.FirstLink();
     while (lnk && iResult>=0) {
       AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
@@ -361,6 +383,7 @@ int AliHLTTask::StartRun()
       }
       lnk=lnk->Next();
     }
+    }
     if (iResult>=0) {
       if (fBlockDataArray.size()>0) {
        HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
@@ -370,7 +393,7 @@ int AliHLTTask::StartRun()
       // component init
       // the initialization of the component is done by the ComponentHandler after creation
       // of the component.
-      //iResult=Init( AliHLTComponentEnvironment* environ, void* environ_param, int argc, const char** argv );
+      //iResult=Init( AliHLTAnalysisEnvironment* environ, void* environ_param, int argc, const char** argv );
 
       // allocate the data buffer, which controls the output buffer and subscriptions
       if (iResult>=0) {
@@ -422,7 +445,7 @@ int AliHLTTask::EndRun()
   return iResult;
 }
 
-int AliHLTTask::ProcessTask(Int_t eventNo)
+int AliHLTTask::ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType)
 {
   // see header file for function documentation
   int iResult=0;
@@ -440,6 +463,11 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
     // instances of SOR and EOR events to be kept
     int iSOR=-1;
     int iEOR=-1;
+    // TODO 2009-09-30
+    // generalize handling of the special blocks to be forwarded on SOR and EOR
+    // just adding a new specific handling for the ECS parameter block as a quick
+    // solution
+    int iECS=-1;
 
     // subscribe to all source tasks
     fBlockDataArray.clear();
@@ -455,12 +483,13 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
          HLTDebug("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
        }
        if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) {
-         iSOR=iEOR=-1;
+         iSOR=iEOR=iECS=-1;
          AliHLTComponentBlockDataList::iterator block=fBlockDataArray.begin();
          for (int i=0; block!=fBlockDataArray.end(); i++) {
            bool bRemove=0;
            bRemove|=(*block).fDataType==kAliHLTDataTypeSOR && !(iSOR<0 && (iSOR=i)>=0);
            bRemove|=(*block).fDataType==kAliHLTDataTypeEOR && !(iEOR<0 && (iEOR=i)>=0);
+           bRemove|=(*block).fDataType==kAliHLTDataTypeECSParam && !(iECS<0 && (iECS=i)>=0);
            //HLTInfo("block %d, iSOR=%d iEOR=%d remove=%d", i, iSOR, iEOR, bRemove);
            if (i<iSourceDataBlock) {
              assert(!bRemove);
@@ -493,12 +522,11 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
 
     // process the event
     int iNofTrial=0; // repeat processing if component returns -ENOSPC
-    AliHLTUInt32_t size=0;
+    AliHLTUInt32_t iLastOutputDataSize=0;
     if (iResult>=0) {
     do {
       long unsigned int iOutputDataSize=0;
       AliHLTConfiguration* pConf=GetConf();
-      assert(pConf);
       // check if there was a buffer size specified, query output size
       // estimator from component otherwize
       if (pConf && pConf->GetOutputBufferSize()>=0) {
@@ -506,8 +534,20 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
       } else {
       long unsigned int iConstBase=0;
       double fInputMultiplier=0;
-      if (pComponent->GetComponentType()!=AliHLTComponent::kSink)
+      if (pComponent->GetComponentType()!=AliHLTComponent::kSink) {
        pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
+       // add a small margin to the buffer to allow optional component
+       // statistics
+       iConstBase+=100;
+#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
+       for (AliHLTComponentBlockDataList::iterator element=fBlockDataArray.begin();
+            element!=fBlockDataArray.end(); element++) {
+         if (element->fDataType==kAliHLTDataTypeComponentStatistics) {
+           iConstBase+=element->fSize;
+         }
+       }
+#endif
+      }
       if (fInputMultiplier<0) {
        HLTWarning("ignoring negative input multiplier");
        fInputMultiplier=0;
@@ -517,30 +557,114 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
       }
       if (iNofTrial>0) {
        // dont process again if the buffer size is the same
-       if (size==iOutputDataSize) break;
-       HLTInfo("processing task %s again with buffer size %d", GetName(), iOutputDataSize);
+       if (iLastOutputDataSize==iOutputDataSize) break;
+       HLTImportant("processing event %d again with buffer size %d", eventNo, iOutputDataSize);
       }
       AliHLTUInt8_t* pTgtBuffer=NULL;
       if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
       //HLTDebug("provided raw buffer %p", pTgtBuffer);
       AliHLTComponentEventData evtData;
       AliHLTComponent::FillEventData(evtData);
-      evtData.fEventID=(AliHLTEventID_t)eventNo;
-      evtData.fBlockCnt=iSourceDataBlock;
+      if (eventNo>=0)
+       evtData.fEventID=(AliHLTEventID_t)eventNo;
+      evtData.fEventCreation_s=static_cast<AliHLTUInt32_t>(time(NULL));
       AliHLTComponentTriggerData trigData;
-      size=iOutputDataSize;
+      AliHLTEventTriggerData evtTrigData;
+      trigData.fStructSize=sizeof(trigData);
+      trigData.fDataSize=sizeof(AliHLTEventTriggerData);
+      memset(&evtTrigData, 0, trigData.fDataSize);
+      evtTrigData.fCommonHeaderWordCnt=gkAliHLTCommonHeaderCount;
+      // TODO 2009-09-30
+      // Whenever the trigger framework is implemented and provides more than
+      // just a dummy CT_TRIGGER_CLASS, this needs to be changed. Now for
+      // all events the first bit in the trigger mask is set
+      evtTrigData.fCommonHeader[5]=0x1;
+      trigData.fData=&evtTrigData;
+      iLastOutputDataSize=iOutputDataSize;
+      AliHLTUInt32_t size=iOutputDataSize;
       AliHLTUInt32_t outputBlockCnt=0;
       AliHLTComponentBlockData* outputBlocks=NULL;
-      AliHLTComponentEventDoneData* edd;
+      AliHLTComponentEventDoneData* edd=NULL;
       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
+       // add event type data block
+       // the block is removed immediately after processing from the list
+       AliHLTComponentBlockData eventTypeBlock;
+       AliHLTComponent::FillBlockData(eventTypeBlock);
+       // Note: no payload!
+       eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
+       eventTypeBlock.fSpecification=eventType;
+       fBlockDataArray.push_back(eventTypeBlock);
+
+       // process
+       evtData.fBlockCnt=fBlockDataArray.size();
        iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
-       HLTDebug("task %s: component %s ProcessEvent finnished (%d): size=%d blocks=%d", GetName(), pComponent->GetComponentID(), iResult, size, outputBlockCnt);
+       HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt);
+
+       // EventDoneData is for the moment ignored in AliHLTSystem
+       if (edd) {
+         HLTDebug("got EventDoneData size %d", edd->fDataSize);
+         delete [] reinterpret_cast<char*>(edd);
+         edd=NULL;
+       }
+
+       // remove event data block
+       fBlockDataArray.pop_back();
+
+       // check for forwarded blocks.
+       // loop over all output blocks and check
+       // 1. for duplicate blocks (pointing to same location in output buffer
+       //    or to the same buffer)
+       // 2. for blocks forwarded from the input.
        if (iResult>=0 && outputBlocks) {
          if (fListTargets.First()!=NULL) {
            AliHLTComponentBlockDataList segments;
            for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
+             // consistency check for data reference
+             if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
+                 outputBlocks[oblock].fOffset!=0) {
+               HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: "
+                          "for new blocks use offset only, forwarded blocks have fPtr set only",
+                          AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
+                          outputBlocks[oblock].fSpecification,
+                          outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset);
+             }
+
+             // check for duplicates in the output
+             AliHLTUInt32_t checkblock=0;
+             for (; checkblock<oblock; checkblock++) {
+               if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
+                   outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) {
+                 if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize ||
+                     outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) {
+                   HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p "
+                              "but differ in data type and/or size: %d vs. %d",
+                              oblock,
+                              AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
+                              outputBlocks[oblock].fSpecification,
+                              checkblock,
+                              AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(),
+                              outputBlocks[checkblock].fSpecification,
+                              outputBlocks[oblock].fPtr,
+                              outputBlocks[oblock].fSize,
+                              outputBlocks[checkblock].fSize);
+                 }
+                 // ignore from the second copy
+                 break;
+               }
+             }
+             if (checkblock<oblock) continue;
+
+             // search for the forwarded data blocks
+             // new data blocks are announced to the data buffer, forwarded data blocks
+             // to the publisher task. The publisher task of a forwarded data block is
+             // removed from the list in order to keep the buffer open. It will be releases
+             // when the subscribing task releases it
              AliHLTUInt32_t iblock=0;
-             for (; iblock<evtData.fBlockCnt; iblock++) {
+             for (; iblock<fBlockDataArray.size(); iblock++) {
+               if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) {
+                 // the event type data block is ignored if it was forwarded
+                 break;
+               }
                if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
                  assert(subscribedTaskList[iblock]!=NULL);
                  if (subscribedTaskList[iblock]==NULL) continue;
@@ -550,7 +674,7 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
                  break;
                }
              }
-             if (iblock==evtData.fBlockCnt) segments.push_back(outputBlocks[oblock]);
+             if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
            }
            if (pTgtBuffer && segments.size()>0) {
              iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
@@ -575,9 +699,14 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
            fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
            subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
          }
+         if (iECS>=0 && subscribedTaskList[iECS]!=NULL) {
+           HLTDebug("forward EOR event (%s) segment %d (source task %s %p) to data buffer %p", AliHLTComponent::DataType2Text(fBlockDataArray[iECS].fDataType).c_str(), iECS, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
+           fpDataBuffer->Forward(subscribedTaskList[iECS], &fBlockDataArray[iECS]);
+           subscribedTaskList[iECS]=NULL; // not to be released in the loop further down
+         }
        }
       } else {
-       HLTError("task %s: no target buffer available", GetName());
+       HLTError("no target buffer available");
        iResult=-EFAULT;
       }
     } while (iResult==-ENOSPC && iNofTrial++<1);
@@ -591,19 +720,19 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
       if (pSrcTask) {
        int iTempRes=0;
        if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
-         HLTDebug("Task %s (%p) successfully released segment of task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
+         HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
        } else {
-         HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
+         HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes);
        }
       }
       subscribedTaskList.erase(element);
       iSourceDataBlock++;
     }
     if (subscribedTaskList.size()>0) {
-      HLTError("task %s (%p): could not release all data buffers", GetName(), this);
+      HLTError("could not release all data buffers");
     }
   } else {
-    HLTError("task %s (%p): internal failure (not initialized component %p, data buffer %p)", GetName(), this, fpComponent, fpDataBuffer);
+    HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer);
     iResult=-EFAULT;
   }
   return iResult;
@@ -709,6 +838,35 @@ void AliHLTTask::PrintStatus()
       lnk = lnk->Next();
     }
   } else {
-    HLTMessage("     task \"%s\" not initialized", GetName());
+    HLTMessage("     task not initialized");
   }
 }
+
+int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
+{
+  // default implementation nothing to do
+  return 0;
+}
+
+int AliHLTTask::CustomCleanup()
+{
+  // default implementation nothing to do
+  return 0;
+}
+
+int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity, 
+                                   const char* originClass, const char* originFunc,
+                                   const char* file, int line, ... ) const
+{
+  // see header file for function documentation
+  int iResult=0;
+
+  va_list args;
+  va_start(args, line);
+
+  AliHLTLogging::SetLogString(this, " (%p)", "%s_pfmt_: ", GetName());
+  iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
+  va_end(args);
+
+  return iResult;
+}