bugfix: support of multiple output blocks per event and component
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 19 Aug 2007 22:01:33 +0000 (22:01 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 19 Aug 2007 22:01:33 +0000 (22:01 +0000)
HLT/BASE/AliHLTConfiguration.cxx
HLT/BASE/AliHLTDataBuffer.cxx
HLT/BASE/AliHLTDataBuffer.h
HLT/BASE/AliHLTTask.h

index aa66f42..eac0eab 100644 (file)
@@ -428,8 +428,7 @@ AliHLTTask::AliHLTTask()
   fpDataBuffer(NULL),
   fListTargets(),
   fListDependencies(),
-  fpBlockDataArray(NULL),
-  fBlockDataArraySize(0)
+  fBlockDataArray()
 {
   // see header file for function documentation
 }
@@ -441,34 +440,11 @@ AliHLTTask::AliHLTTask(AliHLTConfiguration* pConf)
   fpDataBuffer(NULL),
   fListTargets(),
   fListDependencies(),
-  fpBlockDataArray(NULL),
-  fBlockDataArraySize(0)
+  fBlockDataArray()
 {
   // see header file for function documentation
 }
 
-AliHLTTask::AliHLTTask(const AliHLTTask&)
-  :
-  TObject(),
-  AliHLTLogging(),
-  fpConfiguration(NULL),
-  fpComponent(NULL),
-  fpDataBuffer(NULL),
-  fListTargets(),
-  fListDependencies(),
-  fpBlockDataArray(NULL),
-  fBlockDataArraySize(0)
-{
-  HLTFatal("copy constructor untested");
-}
-
-AliHLTTask& AliHLTTask::operator=(const AliHLTTask&)
-{ 
-  // see header file for function documentation
-  HLTFatal("assignment operator untested");
-  return *this;
-}
-
 AliHLTTask::~AliHLTTask()
 {
   TObjLink* lnk=fListDependencies.FirstLink();
@@ -488,8 +464,6 @@ AliHLTTask::~AliHLTTask()
 
   if (fpComponent) delete fpComponent;
   fpComponent=NULL;
-  if (fpBlockDataArray) delete[] fpBlockDataArray;
-  fpBlockDataArray=NULL;
 }
 
 int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH)
@@ -757,11 +731,9 @@ int AliHLTTask::StartRun()
       lnk=lnk->Next();
     }
     if (iResult>=0) {
-      if (fpBlockDataArray) {
+      if (fBlockDataArray.size()>0) {
        HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
-       delete [] fpBlockDataArray;
-       fpBlockDataArray=NULL;
-       fBlockDataArraySize=0;
+       fBlockDataArray.resize(0);
       }
 
       // component init
@@ -772,13 +744,9 @@ int AliHLTTask::StartRun()
       // allocate internal task variables for bookkeeping aso.
       // we allocate the BlockData array with at least one member
       if (iNofInputDataBlocks==0) iNofInputDataBlocks=1;
-      fpBlockDataArray=new AliHLTComponentBlockData[iNofInputDataBlocks];
-      if (fpBlockDataArray) {
-       fBlockDataArraySize=iNofInputDataBlocks;
-      } else {
-       HLTError("memory allocation failed");
-       iResult=-ENOMEM;
-      }
+      AliHLTComponentBlockData init;
+      memset(&init, 0, sizeof(AliHLTComponentBlockData));
+      fBlockDataArray.resize(iNofInputDataBlocks, init);
 
       // allocate the data buffer, which controls the output buffer and subscriptions
       if (iResult>=0) {
@@ -814,10 +782,8 @@ int AliHLTTask::EndRun()
 {
   // see header file for function documentation
   int iResult=0;
-  if (fpBlockDataArray) {
-    fBlockDataArraySize=0;
-    delete [] fpBlockDataArray;
-    fpBlockDataArray=0;
+  if (fBlockDataArray.size()>0) {
+    fBlockDataArray.resize(0);
   } else {
     HLTWarning("task %s (%p) doesn't seem to be in running mode", GetName(), this);
   }
@@ -840,19 +806,6 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
     int iSourceDataBlock=0;
     int iInputDataVolume=0;
 
-    int iNofInputDataBlocks=0;
-    /* TODO: the assumption of only one output data type per component is the current constraint
-     * later it should be checked how many output blocks of the source component match the input
-     * data types of the consumer component (GetNofMatchingDataBlocks). If one assumes that a
-     * certain output block is always been produced, the initialization could be done in the
-     * StartRun. Otherwise the fpBlockDataArray has to be adapted each time.
-     */
-    iNofInputDataBlocks=fListDependencies.GetSize(); // one block per source
-    // is not been used since the allocation was done in StartRun, but check the size
-    if (iNofInputDataBlocks>fBlockDataArraySize) {
-      HLTError("block data array too small");
-    }
-
     AliHLTTask* pSrcTask=NULL;
     TList subscribedTaskList;
     TObjLink* lnk=fListDependencies.FirstLink();
@@ -862,29 +815,23 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
       pSrcTask=(AliHLTTask*)lnk->GetObject();
       if (pSrcTask) {
        int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
-       if (iMatchingDB<=fBlockDataArraySize-iSourceDataBlock) {
-         if (fpBlockDataArray) {
-         if ((iResult=pSrcTask->Subscribe(this, &fpBlockDataArray[iSourceDataBlock],fBlockDataArraySize-iSourceDataBlock))>0) {
-           for (int i=0; i<iResult; i++) {
-             iInputDataVolume+=fpBlockDataArray[i+iSourceDataBlock].fSize;
-             // put the source task as many times into the list as it provides data blocks
-             // makes the bookkeeping for the data release easier
-             subscribedTaskList.Add(pSrcTask);
-           }
-           iSourceDataBlock+=iResult;
-           HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
-           iResult=0;
-         } else {
-           HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
-           iResult=-EFAULT;
-         }
-         } else {
-           HLTFatal("Task %s (%p): BlockData array not allocated", GetName(), this);
-           iResult=-EFAULT;
+       if (iMatchingDB>fBlockDataArray.size()-iSourceDataBlock) {
+         AliHLTComponentBlockData init;
+         memset(&init, 0, sizeof(AliHLTComponentBlockData));
+         fBlockDataArray.resize(iSourceDataBlock+iMatchingDB, init);
+       }
+       if ((iResult=pSrcTask->Subscribe(this, &fBlockDataArray[iSourceDataBlock],fBlockDataArray.size()-iSourceDataBlock))>0) {
+         for (int i=0; i<iResult; i++) {
+           iInputDataVolume+=fBlockDataArray[i+iSourceDataBlock].fSize;
+           // put the source task as many times into the list as it provides data blocks
+           // makes the bookkeeping for the data release easier
+           subscribedTaskList.Add(pSrcTask);
          }
+         HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
+         iSourceDataBlock+=iResult;      
+         iResult=0;
        } else {
-         HLTFatal("Task %s (%p): too little space in data block array for subscription to task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
-         HLTDebug("#data types=%d, array size=%d, current index=%d", iMatchingDB, fBlockDataArraySize, iSourceDataBlock);
+         HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
          iResult=-EFAULT;
        }
       } else {
@@ -927,7 +874,7 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
       AliHLTComponentBlockData* outputBlocks=NULL;
       AliHLTComponentEventDoneData* edd;
       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
-       iResult=pComponent->ProcessEvent(evtData, fpBlockDataArray, trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
+       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);
        if (iResult>=0 && pTgtBuffer) {
          iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
@@ -949,8 +896,8 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
       pSrcTask=(AliHLTTask*)lnk->GetObject();
       if (pSrcTask) {
        int iTempRes=0;
-       if ((iTempRes=pSrcTask->Release(&fpBlockDataArray[iSourceDataBlock], this))>=0) {
-         HLTDebug("Task %s (%p) successfully released task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
+       if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
+         HLTDebug("Task %s (%p) successfully released segment of task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
        } else {
          HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
        }
index 08c4577..9018532 100644 (file)
@@ -198,12 +198,15 @@ int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponen
            arrayBlockDesc[i].fShmKey.fShmType=gkAliHLTComponentInvalidShmType;
            arrayBlockDesc[i].fShmKey.fShmID=gkAliHLTComponentInvalidShmID;
            arrayBlockDesc[i].fOffset=(*segment).fSegmentOffset;
-           arrayBlockDesc[i].fPtr=fpBuffer->fPtr;
+           arrayBlockDesc[i].fPtr=*fpBuffer;
            arrayBlockDesc[i].fSize=(*segment).fSegmentSize;
            arrayBlockDesc[i].fDataType=(*segment).fDataType;
            arrayBlockDesc[i].fSpecification=(*segment).fSpecification;
            pDesc->SetActiveDataSegment(arrayBlockDesc[i].fOffset, arrayBlockDesc[i].fSize);
-           HLTDebug("component %p (%s) subscribed to segment #%d offset %d", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), i, arrayBlockDesc[i].fOffset);
+           HLTDebug("component %p (%s) subscribed to segment #%d offset %d size %d data type %s %#x", 
+                    pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), i, arrayBlockDesc[i].fOffset,
+                    arrayBlockDesc[i].fSize, (AliHLTComponent::DataType2Text(arrayBlockDesc[i].fDataType)).c_str(), 
+                    arrayBlockDesc[i].fSpecification);
            i++;
            segment++;
          }
@@ -283,7 +286,7 @@ AliHLTUInt8_t* AliHLTDataBuffer::GetTargetBuffer(int iMinSize)
   }
   fpBuffer=CreateRawBuffer(iMinSize);
   if (fpBuffer) {
-    pTargetBuffer=(AliHLTUInt8_t*)fpBuffer->fPtr;
+    pTargetBuffer=*fpBuffer;
   } else {
     HLTError("can not create raw buffer");
   }
@@ -296,20 +299,26 @@ int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData*
   int iResult=0;
   if (pTgt && arrayBlockData && iSize>=0) {
     if (fpBuffer) {
-      if (fpBuffer->fPtr==(void*)pTgt) {
+      if (*fpBuffer==pTgt) {
        AliHLTDataBuffer::AliHLTDataSegment segment;
        for (int i=0; i<iSize; i++) {
-         if (arrayBlockData[i].fOffset+arrayBlockData[i].fSize<=fpBuffer->fSize) {
-           segment.fSegmentOffset=arrayBlockData[i].fOffset;
-           segment.fSegmentSize=arrayBlockData[i].fSize;
-           segment.fDataType=arrayBlockData[i].fDataType;
-           segment.fSpecification=arrayBlockData[i].fSpecification;
-           fSegments.push_back(segment);
-           HLTDebug("set segment %s with size %d at offset %d", AliHLTComponent::DataType2Text(segment.fDataType).data(), segment.fSegmentSize, segment.fSegmentOffset);
+         if ((*fpBuffer)<=arrayBlockData[i].fPtr && (*fpBuffer)>arrayBlockData[i].fPtr) {
+           int ptrOffset=(*fpBuffer)-arrayBlockData[i].fPtr;
+           if (arrayBlockData[i].fOffset+ptrOffset+arrayBlockData[i].fSize<=fpBuffer->fSize) {
+             segment.fSegmentOffset=arrayBlockData[i].fOffset+ptrOffset;
+             segment.fSegmentSize=arrayBlockData[i].fSize;
+             segment.fDataType=arrayBlockData[i].fDataType;
+             segment.fSpecification=arrayBlockData[i].fSpecification;
+             fSegments.push_back(segment);
+             HLTDebug("set segment %s with size %d at offset %d", AliHLTComponent::DataType2Text(segment.fDataType).data(), segment.fSegmentSize, segment.fSegmentOffset);
+           } else {
+             HLTError("block data specification %#d (%s) exceeds size of data buffer", i, AliHLTComponent::DataType2Text(arrayBlockData[i].fDataType).data());
+             HLTError("block offset=%d, block size=%d, buffer size=%d", arrayBlockData[i].fOffset, arrayBlockData[i].fSize, fpBuffer->fSize);
+             iResult=-E2BIG;
+           }
          } else {
-           HLTError("block data specification %#d (%s) exceeds size of data buffer", i, AliHLTComponent::DataType2Text(arrayBlockData[i].fDataType).data());
-           HLTError("block offset=%d, block size=%d, buffer size=%d", arrayBlockData[i].fOffset, arrayBlockData[i].fSize, fpBuffer->fSize);
-           iResult=-E2BIG;
+           HLTError("invalid pointer (%p) in block data specification (buffer %p size %d)", arrayBlockData[i].fPtr, fpBuffer->fPtr, fpBuffer->fSize);
+           iResult=-ERANGE;
          }
        }
       } else {
@@ -377,7 +386,7 @@ AliHLTDataBuffer::AliHLTRawBuffer* AliHLTDataBuffer::CreateRawBuffer(AliHLTUInt3
     // no buffer found, create a new one
     pRawBuffer=new AliHLTRawBuffer;
     if (pRawBuffer) {
-      pRawBuffer->fPtr=malloc(reqSize);
+      pRawBuffer->fPtr=static_cast<AliHLTUInt8_t*>(malloc(reqSize));
       if (pRawBuffer->fPtr) {
        pRawBuffer->fSize=size;
        pRawBuffer->fTotalSize=reqSize;
@@ -597,3 +606,27 @@ int AliHLTDataBuffer::FindConsumer(AliHLTComponent* pConsumer, int bAllLists)
   }
   return 0;
 }
+
+int AliHLTDataBuffer::AliHLTRawBuffer::operator==(void* ptr)
+{
+  return fPtr == static_cast<AliHLTUInt8_t*>(ptr);
+}
+
+int AliHLTDataBuffer::AliHLTRawBuffer::operator<=(void* ptr)
+{
+  int iResult=fPtr <= static_cast<AliHLTUInt8_t*>(ptr);
+  //printf("%p: %p <= %p (%d)\n", this, fPtr, ptr, iResult);
+  return iResult;
+}
+
+int AliHLTDataBuffer::AliHLTRawBuffer::operator>(void* ptr)
+{
+  int iResult=fPtr+fSize > static_cast<AliHLTUInt8_t*>(ptr);
+  //printf("%p: %p + %d > %p (%d)\n", this, fPtr, fSize, ptr, iResult);
+  return iResult;
+}
+
+int AliHLTDataBuffer::AliHLTRawBuffer::operator-(void* ptr)
+{
+  return static_cast<int>(static_cast<AliHLTUInt8_t*>(ptr)-fPtr);
+}
index 6684d42..e083fee 100644 (file)
@@ -244,13 +244,23 @@ class AliHLTDataBuffer : public TObject, public AliHLTLogging
     AliHLTRawBuffer& operator=(const AliHLTRawBuffer&) {return *this;}
     /** standard destructor */
     virtual ~AliHLTRawBuffer() {}
+
+    int operator==(void*);
+    int operator==(AliHLTUInt8_t* ptr) {return fPtr==ptr;}
+    int operator<=(void*);
+    int operator>(void*);
+    int operator-(void*);
+
+    operator void*() {return fPtr;}
+    operator AliHLTUInt8_t*() {return fPtr;}
+
   private:
     /** size of the currently occupied partition of the buffer */
     AliHLTUInt32_t fSize;                                          // see above
     /** total size of the buffer, including safety margin */
     AliHLTUInt32_t fTotalSize;                                     // see above
     /** the buffer */
-    void* fPtr;                                                    //! transient
+    AliHLTUInt8_t* fPtr;                                           //! transient
   };
 
  private:
index adacd06..3a10909 100644 (file)
@@ -59,10 +59,6 @@ class AliHLTTask : public TObject, public AliHLTLogging {
       @param pConf pointer to configuration descriptor
    */
   AliHLTTask(AliHLTConfiguration* pConf);
-  /** not a valid copy constructor, defined according to effective C++ style */
-  AliHLTTask(const AliHLTTask&);
-  /** not a valid assignment op, but defined according to effective C++ style */
-  AliHLTTask& operator=(const AliHLTTask&);
   /** destructor */
   virtual ~AliHLTTask();
 
@@ -277,6 +273,11 @@ class AliHLTTask : public TObject, public AliHLTLogging {
   int GetNofSources() const {return fListDependencies.GetSize();}
 
  private:
+  /** prohibited copy constructor */
+  AliHLTTask(const AliHLTTask&);
+  /** prohibited assignment operator */
+  AliHLTTask& operator=(const AliHLTTask&);
+
   /** the configuration descriptor (external pointer) */
   AliHLTConfiguration* fpConfiguration;                           //! transient
   /** the component described by this task (created and deleted internally) */
@@ -293,11 +294,9 @@ class AliHLTTask : public TObject, public AliHLTLogging {
    * @ref AliHLTComponent::ProcessEvent method. 
    * Filled through subscription to source tasks (@ref Subscribe).
    */
-  AliHLTComponentBlockData* fpBlockDataArray;                     //! transient
-  /** size of the block data array */
-  int fBlockDataArraySize;                                        // see above
+  vector<AliHLTComponentBlockData> fBlockDataArray;               //! transient
 
-  ClassDef(AliHLTTask, 1);
+  ClassDef(AliHLTTask, 2);
 };
 
 #endif