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 // handling of HLT data buffers //
22 ///////////////////////////////////////////////////////////////////////////////
28 #include "AliHLTDataBuffer.h"
30 #include "AliHLTSystem.h"
32 AliHLTConsumerDescriptor::AliHLTConsumerDescriptor()
35 memset(&fDataType, 0, sizeof(AliHLTComponent_DataType));
36 fDataType.fStructSize=sizeof(AliHLTComponent_DataType);
40 AliHLTConsumerDescriptor::AliHLTConsumerDescriptor(AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype)
47 AliHLTConsumerDescriptor::~AliHLTConsumerDescriptor()
51 int AliHLTConsumerDescriptor::SetActiveDataSegment(AliHLTDataSegment* pSegment)
57 int AliHLTConsumerDescriptor::CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
63 int AliHLTConsumerDescriptor::ReleaseActiveDataSegment()
69 ClassImp(AliHLTDataBuffer)
71 int AliHLTDataBuffer::fNofInstances=0;
72 vector<AliHLTRawBuffer*> AliHLTDataBuffer::fFreeBuffers;
73 vector<AliHLTRawBuffer*> AliHLTDataBuffer::fActiveBuffers;
74 AliHLTUInt32_t AliHLTDataBuffer::fMargin=1024;
77 AliHLTDataBuffer::AliHLTDataBuffer()
79 // TODO: do the right initialization
89 AliHLTDataBuffer::~AliHLTDataBuffer()
91 if (--fNofInstances<=0) {
94 CleanupConsumerList();
97 int AliHLTDataBuffer::SetConsumer(AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype)
101 AliHLTConsumerDescriptor* pDesc=new AliHLTConsumerDescriptor(pConsumer, datatype);
103 fConsumers.push_back(pDesc);
105 HLTError("memory allocation failed");
109 HLTError("invalid parameter");
115 int AliHLTDataBuffer::Subscribe(AliHLTComponent_DataType datatype, const AliHLTComponent* pConsumer, AliHLTComponent_BlockData* pBlockDesc)
118 if (pConsumer && pBlockDesc) {
120 AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, datatype, fConsumers);
122 AliHLTDataSegment* pSegment=FindDataSegment(datatype);
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);
140 HLTError("can not activate consumer %p for data buffer %p", pConsumer, this);
144 HLTError("unresolved data segment: %s::%s is not available", datatype.fID, datatype.fOrigin);
148 HLTWarning("can not find consumer %p in component list of data buffer %d", pConsumer, this);
152 HLTError("data buffer %p is empty", this);
156 HLTError("invalid parameter");
162 int AliHLTDataBuffer::Release(AliHLTComponent_BlockData* pBlockDesc, const AliHLTComponent* pConsumer)
165 if (pBlockDesc && pConsumer) {
166 AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, pBlockDesc->fDataType, fActiveConsumers);
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
173 pDesc->ReleaseActiveDataSegment();
174 pBlockDesc->fOffset=0;
175 pBlockDesc->fPtr=NULL;
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;
182 ReleaseRawBuffer(pBuffer);
185 HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this);
189 HLTWarning("component %p has currently not subscribed to the data buffer", pConsumer);
193 HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer);
199 AliHLTUInt8_t* AliHLTDataBuffer::GetTargetBuffer(int iMinSize)
201 AliHLTUInt8_t* pTargetBuffer=NULL;
202 fpBuffer=CreateRawBuffer(iMinSize);
203 pTargetBuffer=(AliHLTUInt8_t*)fpBuffer;
204 return pTargetBuffer;
207 int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponent_BlockData* arrayBlockData, int iSize)
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);
221 HLTError("block data specification #%d (%s@%s) exceeds size of data buffer", i, arrayBlockData[i].fDataType.fOrigin, arrayBlockData[i].fDataType.fID);
225 HLTError("inavalid parameter: pTgtBuffer=%p arrayBlockData=%p", pTgt, arrayBlockData);
231 int AliHLTDataBuffer::IsEmpty()
233 int iResult=fpBuffer==NULL || GetNofSegments()==0;
237 int AliHLTDataBuffer::GetNofSegments()
239 int iResult=fSegments.size();
243 int AliHLTDataBuffer::GetNofConsumers()
245 int iResult=fConsumers.size() + GetNofActiveConsumers() + fReleasedConsumers.size();
249 int AliHLTDataBuffer::GetNofActiveConsumers()
251 int iResult=fActiveConsumers.size();
255 AliHLTRawBuffer* AliHLTDataBuffer::CreateRawBuffer(AliHLTUInt32_t size)
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
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);
268 // check the next element
272 if (pRawBuffer==NULL) {
273 pRawBuffer=new AliHLTRawBuffer;
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);
285 //HLTError("memory allocation failed");
288 //HLTError("memory allocation failed");
294 int AliHLTDataBuffer::ReleaseRawBuffer(AliHLTRawBuffer* pBuffer)
298 vector<AliHLTRawBuffer*>::iterator buffer=fActiveBuffers.begin();
299 while (buffer!=fActiveBuffers.end() && (*buffer)!=pBuffer) {
302 if (buffer!=fActiveBuffers.end()) {
304 fFreeBuffers.push_back(*buffer);
305 fActiveBuffers.erase(buffer);
307 //HLTWarning("can not find raw buffer container %p in the list of active containers", pBuffer);
311 //HLTError("invalid parameter");
318 int AliHLTDataBuffer::DeleteRawBuffers()
321 vector<AliHLTRawBuffer*>::iterator buffer=fFreeBuffers.begin();
322 while (buffer!=fFreeBuffers.end()) {
323 free((*buffer)->fPtr);
325 fFreeBuffers.erase(buffer);
326 buffer=fFreeBuffers.begin();
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);
333 fActiveBuffers.erase(buffer);
334 buffer=fActiveBuffers.begin();
339 AliHLTConsumerDescriptor* AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype, vector<AliHLTConsumerDescriptor*> &list)
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) {
351 int AliHLTDataBuffer::ResetDataBuffer() {
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);
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);
372 int AliHLTDataBuffer::ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, vector<AliHLTConsumerDescriptor*> &srcList, vector<AliHLTConsumerDescriptor*> &tgtList)
376 vector<AliHLTConsumerDescriptor*>::iterator desc=srcList.begin();
377 while (desc!=srcList.end()) {
378 if ((*desc)==pDesc) {
380 tgtList.push_back(pDesc);
384 if (desc==srcList.end()) {
385 HLTError("can not find consumer descriptor %p in list", pDesc);
389 HLTError("invalid parameter");
395 int AliHLTDataBuffer::CleanupConsumerList() {
398 vector<AliHLTConsumerDescriptor*>::iterator desc=fConsumers.begin();
399 while (desc!=fConsumers.end()) {
401 fConsumers.erase(desc);
402 desc=fConsumers.begin();
407 AliHLTDataSegment* AliHLTDataBuffer::FindDataSegment(AliHLTComponent_DataType datatype)
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