scanning of handlers for HLTOUT blocks added
[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   if ((iResult=GenerateIndex())>=0) {
72     if ((iResult=InitHandlers())>=0) {
73     }
74   }
75   return iResult;
76 }
77
78 int AliHLTOUT::GetNofDataBlocks()
79 {
80   // see header file for class documentation
81   return fBlockDescList.size();
82 }
83
84 int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
85                                     AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
86 {
87   // see header file for class documentation
88   if (CheckStatusFlag(kLocked)) return -EPERM;
89   fCurrent=fBlockDescList.begin();
90   fSearchDataType=dt;
91   fSearchSpecification=spec;
92   //fSearchHandlerType=handlerType;
93   return FindAndSelectDataBlock();
94 }
95
96 int AliHLTOUT::SelectNextDataBlock()
97 {
98   // see header file for class documentation
99   if (CheckStatusFlag(kLocked)) return -EPERM;
100   fCurrent++;
101   return FindAndSelectDataBlock();
102 }
103
104 int AliHLTOUT::FindAndSelectDataBlock()
105 {
106   // see header file for class documentation
107   if (CheckStatusFlag(kLocked)) return -EPERM;
108   int iResult=-ENOENT;
109   while (fCurrent!=fBlockDescList.end() && iResult==-ENOENT) {
110     if ((fSearchDataType==kAliHLTAnyDataType || (*fCurrent)==fSearchDataType) &&
111         fSearchSpecification==kAliHLTVoidDataSpec || (*fCurrent)==fSearchSpecification &&
112         1/*fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput*/) {
113       iResult=0;
114       // TODO: check the byte order on the current system and the byte order of the
115       // data block, print warning when missmatch and user did not check
116       //AliHLTOUTByteOrder_t blockBO=CheckByteOrder();
117       CheckByteOrder();
118       /*
119         if (blockBO!=fByteOrder) {
120         SetStatusFlag(kByteOrderWarning);
121
122         }
123        */
124       ClearStatusFlag(kByteOrderChecked);
125
126       // TODO: check the alignment on the current system and the alignment of the
127       // data block, print warning when missmatch and user did not check
128       ClearStatusFlag(kAlignmentChecked);
129     }
130     fCurrent++;
131   }
132   return iResult;
133 }
134
135 int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
136 {
137   // see header file for class documentation
138   int iResult=-ENOENT;
139   if (fCurrent!=fBlockDescList.end()) {
140     iResult=0;
141     dt=(*fCurrent);
142     spec=(*fCurrent);
143   }
144   return iResult;
145 }
146
147 AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
148 {
149   // see header file for class documentation
150   assert(0); // not implemented
151   return AliHLTOUTInvalidIndex;
152 }
153
154 int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
155 {
156   // see header file for class documentation
157   int iResult=-ENOENT;
158   pBuffer=NULL;
159   size=0;
160   if (fCurrent!=fBlockDescList.end()) {
161     if ((iResult=GetDataBuffer((*fCurrent).GetIndex(), pBuffer, size))>=0) {
162       fpBuffer=pBuffer;
163     }
164   }
165   return iResult;  
166 }
167
168 int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
169 {
170   // see header file for class documentation
171   int iResult=0;
172   if (pBuffer==fpBuffer) {
173     fpBuffer=NULL;
174   } else {
175     HLTWarning("buffer %p does not match the provided one %p", pBuffer, fpBuffer);
176   }
177   return iResult;  
178 }
179
180 int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
181 {
182   // see header file for class documentation
183   if (!CheckStatusFlag(kCollecting)) return -EPERM;
184   int iResult=0;
185   fBlockDescList.push_back(desc);
186   return iResult;  
187 }
188
189 AliHLTOUT::AliHLTOUTByteOrder_t AliHLTOUT::CheckByteOrder()
190 {
191   // see header file for class documentation
192   if (fCurrent!=fBlockDescList.end()) {
193     SetStatusFlag(kByteOrderChecked);
194     AliHLTOUT::AliHLTOUTByteOrder_t order=CheckBlockByteOrder((*fCurrent).GetIndex());
195     return order;
196   }
197   return kInvalidByteOrder;
198 }
199
200 int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType_t type)
201 {
202   // see header file for class documentation
203   if (fCurrent!=fBlockDescList.end()) {
204     SetStatusFlag(kAlignmentChecked);
205     int alignment=CheckBlockAlignment((*fCurrent).GetIndex(), type);
206     return alignment;
207   }
208   return -ENOENT;
209 }
210
211 int AliHLTOUT::InitHandlers()
212 {
213   // see header file for class documentation
214   int iResult=0;
215   AliHLTOUTIndexList remnants;
216   for (iResult=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); iResult>0; iResult=SelectNextDataBlock()) {
217     remnants.push_back(GetDataBlockIndex());
218     AliHLTComponentDataType dt=kAliHLTVoidDataType;
219     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
220     if ((iResult=GetDataBlockDescription(dt, spec))<0) break;
221     for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
222       AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
223       if (pAgent->GetHandlerDescription(dt, spec, &handlerDesc)>0) {
224         AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
225         iResult=InsertHandler(entry);
226         remnants.pop_back();
227         break;
228       }
229     }
230   }
231   if (remnants.size()>0) {
232     HLTWarning("no handlers found for %d data blocks out of %d", remnants.size(), GetNofDataBlocks());
233     vector<AliHLTOUTBlockDescriptor>::iterator block=fBlockDescList.begin();
234     for (AliHLTOUTIndexList::iterator element=remnants.begin(); element!=remnants.end(); element++) {
235       for (int trials=0; trials<2; trials++) {
236         do {
237           // we start searching the index from the current position in the block list
238           if ((*block).GetIndex()==*element) break;
239         } while ((++block)!=fBlockDescList.end());
240         if (block==fBlockDescList.end()) {
241           // rewind and try again
242           block=fBlockDescList.begin();
243         }
244       }
245       assert(block!=fBlockDescList.end());
246       if (block!=fBlockDescList.end()) {
247         HLTDebug("   %s", AliHLTComponent::DataType2Text((AliHLTComponentDataType)*block).c_str());
248       }
249     }
250   }
251   return iResult;
252 }
253
254 int AliHLTOUT::InsertHandler(const AliHLTOUTHandlerListEntry &entry)
255 {
256   // see header file for class documentation
257   int iResult=0;
258   vector<AliHLTOUTHandlerListEntry>::iterator element=fDataHandlers.begin();
259   while (element!=fDataHandlers.end()) {
260     if (entry==(*element)) break;
261     element++;
262   }
263   if (element==fDataHandlers.end()) {
264     fDataHandlers.push_back(entry);
265   } else {
266     
267   }
268   return iResult;
269 }
270
271 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler, 
272                                                                 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
273                                                                 AliHLTModuleAgent* pAgent,
274                                                                 AliHLTUInt32_t index)
275   :
276   fpHandler(pHandler),
277   fHandlerDesc(handlerDesc),
278   fpAgent(pAgent),
279   fBlocks()
280 {
281   // see header file for class documentation
282   fBlocks.push_back(index);
283 }
284
285 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
286   :
287   fpHandler(src.fpHandler),
288   fHandlerDesc(src.fHandlerDesc),
289   fpAgent(src.fpAgent),
290   fBlocks()
291 {
292   // see header file for class documentation
293   fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
294 }
295
296 AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
297 {
298   // see header file for class documentation
299   fpHandler=src.fpHandler;
300   fHandlerDesc=src.fHandlerDesc;
301   fpAgent=src.fpAgent;
302   fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
303   return *this;
304 }
305
306 AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const {
307   return fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
308 }
309
310 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index) {
311   fBlocks.push_back(index);
312 }