]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTDataBuffer.cxx
fix in Gain
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataBuffer.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 // handling of HLT data buffers                                              //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #if __GNUC__== 3
25 using namespace std;
26 #endif
27
28 #include "AliHLTDataBuffer.h"
29 #include <string>
30 #include "AliHLTSystem.h"
31
32 AliHLTConsumerDescriptor::AliHLTConsumerDescriptor()
33 {
34   fpConsumer=NULL;
35   memset(&fDataType, 0, sizeof(AliHLTComponent_DataType));
36   fDataType.fStructSize=sizeof(AliHLTComponent_DataType);
37   fpSegment=NULL;
38 }
39
40 AliHLTConsumerDescriptor::AliHLTConsumerDescriptor(AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype)
41 {
42   fpConsumer=pConsumer;
43   fDataType=datatype;
44   fpSegment=NULL;
45 }
46
47 AliHLTConsumerDescriptor::~AliHLTConsumerDescriptor()
48 {
49 }
50
51 int AliHLTConsumerDescriptor::SetActiveDataSegment(AliHLTDataSegment* pSegment)
52 {
53   int iResult=0;
54   return iResult;
55 }
56
57 int AliHLTConsumerDescriptor::CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
58 {
59   int iResult=0;
60   return iResult;
61 }
62
63 int AliHLTConsumerDescriptor::ReleaseActiveDataSegment()
64 {
65   int iResult=0;
66   return iResult;
67 }
68
69 ClassImp(AliHLTDataBuffer)
70
71 int AliHLTDataBuffer::fNofInstances=0;
72 vector<AliHLTRawBuffer*> AliHLTDataBuffer::fFreeBuffers;
73 vector<AliHLTRawBuffer*> AliHLTDataBuffer::fActiveBuffers;
74 AliHLTUInt32_t AliHLTDataBuffer::fMargin=1024;
75
76
77 AliHLTDataBuffer::AliHLTDataBuffer()
78 {
79   // TODO: do the right initialization 
80   //fSegments.empty();
81   //fConsumers;
82   //fActiveConsumers;
83   //fReleasedConsumers;
84   fpBuffer=NULL;
85   fFlags=0;
86   fNofInstances++;
87 }
88
89 AliHLTDataBuffer::~AliHLTDataBuffer()
90 {
91   if (--fNofInstances<=0) {
92     DeleteRawBuffers();
93   }
94   CleanupConsumerList();
95 }
96
97 int AliHLTDataBuffer::SetConsumer(AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype)
98 {
99   int iResult=0;
100   if (pConsumer) {
101     AliHLTConsumerDescriptor* pDesc=new AliHLTConsumerDescriptor(pConsumer, datatype);
102     if (pDesc) {
103       fConsumers.push_back(pDesc);
104     } else {
105       HLTError("memory allocation failed");
106       iResult=-ENOMEM;
107     }
108   } else {
109     HLTError("invalid parameter");
110     iResult=-EINVAL;
111   }
112   return iResult;
113 }
114
115 int AliHLTDataBuffer::Subscribe(AliHLTComponent_DataType datatype, const AliHLTComponent* pConsumer, AliHLTComponent_BlockData* pBlockDesc)
116 {
117   int iResult=0;
118   if (pConsumer && pBlockDesc) {
119     if (fpBuffer) {
120       AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, datatype, fConsumers);
121       if (pDesc) {
122         AliHLTDataSegment* pSegment=FindDataSegment(datatype);
123         if (pSegment) {
124           // move this consumer to the active list
125           if ((iResult=ChangeConsumerState(pDesc, fConsumers, fActiveConsumers))>=0) {
126             pDesc->SetActiveDataSegment(pSegment);
127             // fill the block data descriptor
128             pBlockDesc->fStructSize=sizeof(AliHLTComponent_BlockData);
129             // the shared memory key is not used in AliRoot
130             pBlockDesc->fShmKey.fStructSize=sizeof(AliHLTComponent_ShmData);
131             pBlockDesc->fShmKey.fShmType=0;
132             pBlockDesc->fShmKey.fShmID=0;
133             pBlockDesc->fOffset=pSegment->fSegmentOffset;
134             pBlockDesc->fPtr=fpBuffer->fPtr;
135             pBlockDesc->fSize=pSegment->fSegmentSize;
136             pBlockDesc->fDataType=pSegment->fDataType;
137             pBlockDesc->fSpecification=pSegment->fSpecification;
138             HLTDebug("component %p (%s) subscribed to data buffer %p (%s)", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), this, datatype.fID);
139           } else {
140             HLTError("can not activate consumer %p for data buffer %p", pConsumer, this);
141             iResult=-EACCES;
142           }
143         } else {
144           HLTError("unresolved data segment: %s::%s is not available", datatype.fID, datatype.fOrigin);
145           iResult=-EBADF;
146         }
147       } else {
148         HLTWarning("can not find consumer %p in component list of data buffer %d", pConsumer, this);
149         iResult=-ENOENT;
150       }
151     } else {
152       HLTError("data buffer %p is empty", this);
153       iResult=-ENODATA;
154     }
155   } else {
156     HLTError("invalid parameter");
157     iResult=-EINVAL;
158   }
159   return iResult;
160 }
161
162 int AliHLTDataBuffer::Release(AliHLTComponent_BlockData* pBlockDesc, const AliHLTComponent* pConsumer)
163 {
164   int iResult=0;
165   if (pBlockDesc && pConsumer) {
166       AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, pBlockDesc->fDataType, fActiveConsumers);
167       if (pDesc) {
168         if ((iResult=pDesc->CheckActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize))!=1) {
169           HLTWarning("data segment missmatch, component %p has not subscribed to a segment with offset %#x and size %d", pBlockDesc->fOffset, pBlockDesc->fSize);
170           // TODO: appropriate error handling, but so far optional
171           iResult=0;
172         }
173         pDesc->ReleaseActiveDataSegment();
174         pBlockDesc->fOffset=0;
175         pBlockDesc->fPtr=NULL;
176         pBlockDesc->fSize=0;
177         if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) {
178           if (GetNofActiveConsumers()==0) {
179             // this is the last consumer, release the raw buffer
180             AliHLTRawBuffer* pBuffer=fpBuffer;
181             ResetDataBuffer();
182             ReleaseRawBuffer(pBuffer);
183           }
184         } else {
185           HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this);
186           iResult=-EACCES;
187         }
188       } else {
189         HLTWarning("component %p has currently not subscribed to the data buffer", pConsumer);
190         iResult=-ENOENT;
191       }
192   } else {
193     HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer);
194     iResult=-EINVAL;
195   }
196   return iResult;
197 }
198
199 AliHLTUInt8_t* AliHLTDataBuffer::GetTargetBuffer(int iMinSize)
200 {
201   AliHLTUInt8_t* pTargetBuffer=NULL;
202   fpBuffer=CreateRawBuffer(iMinSize);
203   pTargetBuffer=(AliHLTUInt8_t*)fpBuffer;
204   return pTargetBuffer;
205 }
206
207 int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponent_BlockData* arrayBlockData, int iSize)
208 {
209   int iResult=0;
210   if (pTgt && arrayBlockData && iSize>=0) {
211     AliHLTDataSegment segment;
212     memset(&segment, 0, sizeof(AliHLTDataSegment));
213     for (int i=0; i<iSize; i++) {
214       if (arrayBlockData[i].fOffset+arrayBlockData[i].fSize<fpBuffer->fSize) {
215       segment.fSegmentOffset=arrayBlockData[i].fOffset;
216       segment.fSegmentSize=arrayBlockData[i].fSize;
217       segment.fDataType=arrayBlockData[i].fDataType;
218       segment.fSpecification=arrayBlockData[i].fSpecification;
219       fSegments.push_back(segment);
220       } else {
221         HLTError("block data specification #%d (%s@%s) exceeds size of data buffer", i, arrayBlockData[i].fDataType.fOrigin, arrayBlockData[i].fDataType.fID);
222       }
223     }
224   } else {
225     HLTError("inavalid parameter: pTgtBuffer=%p arrayBlockData=%p", pTgt, arrayBlockData);
226     iResult=-EINVAL;
227   }
228   return iResult;
229 }
230
231 int AliHLTDataBuffer::IsEmpty()
232 {
233   int iResult=fpBuffer==NULL || GetNofSegments()==0;
234   return iResult;
235 }
236
237 int AliHLTDataBuffer::GetNofSegments()
238 {
239   int iResult=fSegments.size();
240   return iResult;
241 }
242
243 int AliHLTDataBuffer::GetNofConsumers()
244 {
245   int iResult=fConsumers.size() + GetNofActiveConsumers() + fReleasedConsumers.size();
246   return iResult;
247 }
248
249 int AliHLTDataBuffer::GetNofActiveConsumers()
250 {
251   int iResult=fActiveConsumers.size();
252   return iResult;
253 }
254
255 AliHLTRawBuffer* AliHLTDataBuffer::CreateRawBuffer(AliHLTUInt32_t size)
256 {
257   AliHLTRawBuffer* pRawBuffer=NULL;
258   vector<AliHLTRawBuffer*>::iterator buffer=fFreeBuffers.begin();
259   while (buffer!=fFreeBuffers.end() && pRawBuffer==NULL) {
260     if ((*buffer)->fTotalSize>=size && ((*buffer)->fTotalSize-size)<fMargin) {
261       // assign this element
262       pRawBuffer=*buffer;
263       pRawBuffer->fSize=size;
264       fFreeBuffers.erase(buffer);
265       //HLTDebug("raw buffer container %p provided for request of %d bytes (total %d available in buffer %p)", pRawBuffer, size, pRawBuffer->fTotalSize, pRawBuffer->fPtr);
266       fActiveBuffers.push_back(pRawBuffer);
267     } else {
268       // check the next element
269       buffer++;
270     }
271   }
272   if (pRawBuffer==NULL) {
273     pRawBuffer=new AliHLTRawBuffer;
274     if (pRawBuffer) {
275       memset(pRawBuffer, 0, sizeof(AliHLTRawBuffer));
276       pRawBuffer->fPtr=malloc(size);
277       if (pRawBuffer->fPtr) {
278         pRawBuffer->fSize=size;
279         pRawBuffer->fTotalSize=size;
280         fActiveBuffers.push_back(pRawBuffer);
281         //HLTDebug("new raw buffer %p of size %d created (container %p)", pRawBuffer->fPtr, pRawBuffer->fTotalSize, pRawBuffer);
282       } else {
283         delete pRawBuffer;
284         pRawBuffer=NULL;
285         //HLTError("memory allocation failed");
286       } 
287     } else {
288       //HLTError("memory allocation failed");
289     }
290   }
291   return pRawBuffer;
292 }
293
294 int AliHLTDataBuffer::ReleaseRawBuffer(AliHLTRawBuffer* pBuffer)
295 {
296   int iResult=0;
297   if (pBuffer) {
298     vector<AliHLTRawBuffer*>::iterator buffer=fActiveBuffers.begin();
299     while (buffer!=fActiveBuffers.end() && (*buffer)!=pBuffer) {
300       buffer++;
301     }
302     if (buffer!=fActiveBuffers.end()) {
303       (*buffer)->fSize=0;
304       fFreeBuffers.push_back(*buffer);
305       fActiveBuffers.erase(buffer);
306     } else {
307       //HLTWarning("can not find raw buffer container %p in the list of active containers", pBuffer);
308       iResult=-ENOENT;
309     }
310   } else {
311     //HLTError("invalid parameter");
312     iResult=-EINVAL;
313   }
314   return iResult;
315 }
316
317
318 int AliHLTDataBuffer::DeleteRawBuffers() 
319 {
320   int iResult=0;
321   vector<AliHLTRawBuffer*>::iterator buffer=fFreeBuffers.begin();
322   while (buffer!=fFreeBuffers.end()) {
323     free((*buffer)->fPtr);
324     delete *buffer;
325     fFreeBuffers.erase(buffer);
326     buffer=fFreeBuffers.begin();
327   }
328   buffer=fActiveBuffers.begin();
329   while (buffer!=fFreeBuffers.end()) {
330     //HLTWarning("request to delete active raw buffer container %d (raw buffer %p, size %d)", *buffer, *buffer->fPtr, *buffer->fTotalSize);
331     free((*buffer)->fPtr);
332     delete *buffer;
333     fActiveBuffers.erase(buffer);
334     buffer=fActiveBuffers.begin();
335   }
336   return iResult;
337 }
338
339 AliHLTConsumerDescriptor* AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype, vector<AliHLTConsumerDescriptor*> &list)
340 {
341   AliHLTConsumerDescriptor* pDesc=NULL;
342   vector<AliHLTConsumerDescriptor*>::iterator desc=list.begin();
343   while (desc!=list.end() && pDesc==NULL) {
344     if ((pConsumer==NULL || (*desc)->GetComponent()==pConsumer) && (*desc)->GetDataType()==datatype) {
345       pDesc=*desc;
346     }
347   }
348   return pDesc;
349 }
350
351 int AliHLTDataBuffer::ResetDataBuffer() {
352   int iResult=0;
353   fpBuffer=NULL;
354   vector<AliHLTConsumerDescriptor*>::iterator desc=fReleasedConsumers.begin();
355   while (desc!=fReleasedConsumers.end()) {
356     AliHLTConsumerDescriptor* pDesc=*desc;
357     fReleasedConsumers.erase(desc);
358     desc=fReleasedConsumers.begin();
359     fConsumers.push_back(pDesc);
360   }
361   desc=fActiveConsumers.begin();
362   while (desc!=fActiveConsumers.end()) {
363     AliHLTConsumerDescriptor* pDesc=*desc;
364     HLTWarning("consumer %p was not released", pDesc);
365     fActiveConsumers.erase(desc);
366     desc=fActiveConsumers.begin();
367     fConsumers.push_back(pDesc);
368   }
369   return iResult;
370 }
371
372 int AliHLTDataBuffer::ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, vector<AliHLTConsumerDescriptor*> &srcList, vector<AliHLTConsumerDescriptor*> &tgtList)
373 {
374   int iResult=0;
375   if (pDesc) {
376     vector<AliHLTConsumerDescriptor*>::iterator desc=srcList.begin();
377     while (desc!=srcList.end()) {
378       if ((*desc)==pDesc) {
379         srcList.erase(desc);
380         tgtList.push_back(pDesc);
381         break;
382       }
383     }
384     if (desc==srcList.end()) {
385       HLTError("can not find consumer descriptor %p in list", pDesc);
386       iResult=-ENOENT;
387     }
388   } else {
389     HLTError("invalid parameter");
390     iResult=-EINVAL;
391   }
392   return iResult;
393 }
394
395 int AliHLTDataBuffer::CleanupConsumerList() {
396   int iResult=0;
397   ResetDataBuffer();
398   vector<AliHLTConsumerDescriptor*>::iterator desc=fConsumers.begin();
399   while (desc!=fConsumers.end()) {
400     delete *desc;
401     fConsumers.erase(desc);
402     desc=fConsumers.begin();
403   }
404   return iResult;
405 }
406
407 AliHLTDataSegment* AliHLTDataBuffer::FindDataSegment(AliHLTComponent_DataType datatype)
408 {
409   AliHLTDataSegment* pSegment=NULL;
410   vector<AliHLTDataSegment>::iterator segment=fSegments.begin();
411   while (segment!=fSegments.end() && pSegment==NULL) {
412     if ((*segment).fDataType==datatype) {
413       // TODO: check this use of the vector
414       //pSegment=segment;
415     }
416   }
417   return pSegment;
418 }