eec69daedb93020d69dfdaefcaf4001407923d79
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTOUT.cxx
1 // $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTOUT.cxx
20     @author Matthias Richter
21     @date   
22     @brief  The control class for HLTOUT data.                            */
23
24 // see header file for class documentation
25 // or
26 // refer to README to build package
27 // or
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
29
30 #include <cerrno>
31 #include <cassert>
32 #include "AliHLTOUT.h"
33
34 /** ROOT macro for the implementation of ROOT specific class methods */
35 ClassImp(AliHLTOUT)
36
37 AliHLTOUT::AliHLTOUT()
38   :
39   fSearchDataType(kAliHLTVoidDataType),
40   fSearchSpecification(kAliHLTVoidDataSpec),
41   fFlags(0),
42   fBlockDescList(),
43   fCurrent(fBlockDescList.begin()),
44   fpBuffer(NULL),
45   fDataHandlers()
46 {
47   // see header file for class documentation
48   // or
49   // refer to README to build package
50   // or
51   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
52 }
53
54 // definitions from ALICE internal note ALICE-INT-2002-010
55 const unsigned char AliHLTOUT::fgkCDHStatusWord=4;
56 const unsigned char AliHLTOUT::fgkCDHStatusFlagsOffset=12;
57
58 // definitions from ALICE internal note ALICE-INT-2006-XXX
59 const unsigned char AliHLTOUT::fgkCDHFlagsHLTDecision=6;
60 const unsigned char AliHLTOUT::fgkCDHFlagsHLTPayload=7;
61
62 AliHLTOUT::~AliHLTOUT()
63 {
64   // see header file for class documentation
65 }
66
67 int AliHLTOUT::Init()
68 {
69   // see header file for class documentation
70   int iResult=0;
71   SetStatusFlag(kCollecting);
72   if ((iResult=GenerateIndex())>=0) {
73     if ((iResult=InitHandlers())>=0) {
74     }
75   }
76   ClearStatusFlag(kCollecting);
77   return iResult;
78 }
79
80 int AliHLTOUT::GetNofDataBlocks()
81 {
82   // see header file for class documentation
83   return fBlockDescList.size();
84 }
85
86 int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
87                                     AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
88 {
89   // see header file for class documentation
90   if (CheckStatusFlag(kLocked)) return -EPERM;
91   fCurrent=fBlockDescList.begin();
92   fSearchDataType=dt;
93   fSearchSpecification=spec;
94   //fSearchHandlerType=handlerType;
95   return FindAndSelectDataBlock();
96 }
97
98 int AliHLTOUT::SelectNextDataBlock()
99 {
100   // see header file for class documentation
101   if (CheckStatusFlag(kLocked)) return -EPERM;
102   if (fCurrent==fBlockDescList.end()) return -ENOENT;
103   fCurrent++;
104   return FindAndSelectDataBlock();
105 }
106
107 int AliHLTOUT::FindAndSelectDataBlock()
108 {
109   // see header file for class documentation
110   if (CheckStatusFlag(kLocked)) return -EPERM;
111   int iResult=-ENOENT;
112   while (fCurrent!=fBlockDescList.end() && iResult==-ENOENT) {
113     if ((*fCurrent)==fSearchDataType &&
114         fSearchSpecification==kAliHLTVoidDataSpec || (*fCurrent)==fSearchSpecification &&
115         1/*fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput*/) {
116       iResult=fCurrent->GetIndex();
117       // TODO: check the byte order on the current system and the byte order of the
118       // data block, print warning when missmatch and user did not check
119       //AliHLTOUTByteOrder_t blockBO=CheckByteOrder();
120       CheckByteOrder();
121       /*
122         if (blockBO!=fByteOrder) {
123         SetStatusFlag(kByteOrderWarning);
124
125         }
126        */
127       ClearStatusFlag(kByteOrderChecked);
128
129       // TODO: check the alignment on the current system and the alignment of the
130       // data block, print warning when missmatch and user did not check
131       ClearStatusFlag(kAlignmentChecked);
132
133       break;
134     }
135     fCurrent++;
136   }
137   return iResult;
138 }
139
140 int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
141 {
142   // see header file for class documentation
143   int iResult=-ENOENT;
144   if (fCurrent!=fBlockDescList.end()) {
145     iResult=0;
146     dt=(*fCurrent);
147     spec=(*fCurrent);
148   }
149   return iResult;
150 }
151
152 AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
153 {
154   // see header file for class documentation
155   if (fCurrent==fBlockDescList.end()) return AliHLTOUTInvalidIndex;
156   return fCurrent->GetIndex();
157 }
158
159 int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
160 {
161   // see header file for class documentation
162   int iResult=-ENOENT;
163   pBuffer=NULL;
164   size=0;
165   if (fCurrent!=fBlockDescList.end()) {
166     if ((iResult=GetDataBuffer((*fCurrent).GetIndex(), pBuffer, size))>=0) {
167       fpBuffer=pBuffer;
168     }
169   }
170   return iResult;  
171 }
172
173 int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
174 {
175   // see header file for class documentation
176   int iResult=0;
177   if (pBuffer==fpBuffer) {
178     fpBuffer=NULL;
179   } else {
180     HLTWarning("buffer %p does not match the provided one %p", pBuffer, fpBuffer);
181   }
182   return iResult;  
183 }
184
185 AliHLTOUTHandler* AliHLTOUT::GetHandler()
186 {
187   // see header file for class documentation
188   AliHLTOUTHandler* pHandler=NULL;
189   pHandler=FindHandlerDesc(GetDataBlockIndex());
190   return pHandler;
191 }
192
193 int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
194 {
195   // see header file for class documentation
196   if (!CheckStatusFlag(kCollecting)) return -EPERM;
197   int iResult=0;
198   fBlockDescList.push_back(desc);
199   return iResult;  
200 }
201
202 AliHLTOUT::AliHLTOUTByteOrder_t AliHLTOUT::CheckByteOrder()
203 {
204   // see header file for class documentation
205   if (fCurrent!=fBlockDescList.end()) {
206     SetStatusFlag(kByteOrderChecked);
207     AliHLTOUT::AliHLTOUTByteOrder_t order=CheckBlockByteOrder((*fCurrent).GetIndex());
208     return order;
209   }
210   return kInvalidByteOrder;
211 }
212
213 int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType_t type)
214 {
215   // see header file for class documentation
216   if (fCurrent!=fBlockDescList.end()) {
217     SetStatusFlag(kAlignmentChecked);
218     int alignment=CheckBlockAlignment((*fCurrent).GetIndex(), type);
219     return alignment;
220   }
221   return -ENOENT;
222 }
223
224 int AliHLTOUT::InitHandlers()
225 {
226   // see header file for class documentation
227   int iResult=0;
228   AliHLTOUTIndexList remnants;
229   for (iResult=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); iResult>=0; iResult=SelectNextDataBlock()) {
230     remnants.push_back(GetDataBlockIndex());
231     AliHLTComponentDataType dt=kAliHLTVoidDataType;
232     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
233     if ((iResult=GetDataBlockDescription(dt, spec))<0) break;
234     for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
235       AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
236       if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
237         AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
238         iResult=InsertHandler(entry);
239         remnants.pop_back();
240         break;
241       }
242     }
243   }
244   if (remnants.size()>0) {
245     HLTWarning("no handlers found for %d data blocks out of %d", remnants.size(), GetNofDataBlocks());
246     vector<AliHLTOUTBlockDescriptor>::iterator block=fBlockDescList.begin();
247     for (AliHLTOUTIndexList::iterator element=remnants.begin(); element!=remnants.end(); element++) {
248       for (int trials=0; trials<2; trials++) {
249         do {
250           // we start searching the index from the current position in the block list
251           if ((*block).GetIndex()==*element) break;
252         } while ((++block)!=fBlockDescList.end());
253         if (block==fBlockDescList.end()) {
254           // rewind and try again
255           block=fBlockDescList.begin();
256         }
257       }
258       assert(block!=fBlockDescList.end());
259       if (block!=fBlockDescList.end()) {
260         HLTDebug("   %s", AliHLTComponent::DataType2Text((AliHLTComponentDataType)*block).c_str());
261       }
262     }
263   }
264   return iResult;
265 }
266
267 int AliHLTOUT::InsertHandler(const AliHLTOUTHandlerListEntry &entry)
268 {
269   // see header file for class documentation
270   int iResult=0;
271   vector<AliHLTOUTHandlerListEntry>::iterator element=fDataHandlers.begin();
272   while (element!=fDataHandlers.end()) {
273     if (entry==(*element)) break;
274     element++;
275   }
276   if (element==fDataHandlers.end()) {
277     fDataHandlers.push_back(entry);
278   } else {
279     
280   }
281   return iResult;
282 }
283
284 AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
285 {
286   // see header file for class documentation
287   int iResult=0;
288   vector<AliHLTOUTHandlerListEntry>::iterator element=fDataHandlers.begin();
289   while (element!=fDataHandlers.end()) {
290     if (element->HasIndex(blockIndex)) {
291       return *element;
292     }
293     element++;
294   }
295   return AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
296 }
297
298 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
299   :
300   fpHandler(NULL),
301   fpHandlerDesc(NULL),
302   fpAgent(NULL),
303   fBlocks()
304 {
305   // see header file for class documentation
306 }
307
308 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler, 
309                                                                 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
310                                                                 AliHLTModuleAgent* pAgent,
311                                                                 AliHLTUInt32_t index)
312   :
313   fpHandler(pHandler),
314   fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
315   fpAgent(pAgent),
316   fBlocks()
317 {
318   // see header file for class documentation
319   *fpHandlerDesc=handlerDesc;
320   fBlocks.push_back(index);
321 }
322
323 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
324   :
325   fpHandler(src.fpHandler),
326   fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
327   fpAgent(src.fpAgent),
328   fBlocks()
329 {
330   // see header file for class documentation
331   *fpHandlerDesc=*src.fpHandlerDesc;
332   fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
333 }
334
335 AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
336 {
337   // see header file for class documentation
338   if (fpHandlerDesc) delete fpHandlerDesc;
339   fpHandlerDesc=NULL;
340 }
341
342 AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
343 {
344   // see header file for class documentation
345   fpHandler=src.fpHandler;
346   *fpHandlerDesc=*src.fpHandlerDesc;
347   fpAgent=src.fpAgent;
348   fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
349   return *this;
350 }
351
352 AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
353 {
354   // see header file for class documentation
355   return fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
356 }
357
358 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
359 {
360   // see header file for class documentation
361   assert(0); // not yet implemented
362   return false;
363 }
364
365 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
366 {
367   // see header file for class documentation
368   fBlocks.push_back(index);
369 }
370
371 bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index)
372 {
373   // see header file for class documentation
374   return false;
375 }
376
377 const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;