Line data Source code
1 : // $Id$
2 :
3 : //**************************************************************************
4 : //* This file is property of and copyright by the *
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 :
25 : #include <cerrno>
26 : #include <cassert>
27 : #include "AliHLTOUT.h"
28 : #include "AliHLTMessage.h"
29 : #include "AliHLTMisc.h"
30 : #include "TSystem.h"
31 : #include "TClass.h"
32 : #include "TROOT.h"
33 : #include <sstream>
34 : #include <iomanip>
35 :
36 : using std::cout;
37 :
38 : /** ROOT macro for the implementation of ROOT specific class methods */
39 126 : ClassImp(AliHLTOUT)
40 :
41 : AliHLTOUT::AliHLTOUT()
42 : :
43 4 : fSearchDataType(kAliHLTVoidDataType),
44 4 : fSearchSpecification(kAliHLTVoidDataSpec),
45 4 : fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
46 4 : fFlags(kSkipProcessed),
47 4 : fBlockDescList(),
48 4 : fCurrent(0),
49 4 : fpBuffer(NULL),
50 4 : fDataHandlers(),
51 4 : fbVerbose(false),
52 4 : fLog()
53 4 : , fpDataObject(NULL)
54 4 : , fpObjectBuffer(NULL)
55 4 : , fObjectBufferSize(0)
56 4 : , fCurrentEventId(kAliHLTVoidEventID)
57 8 : {
58 : // constructor
59 : //
60 : // The control class for HLTOUT data
61 : // see header file for class documentation
62 : // author Matthias Richter
63 4 : }
64 :
65 : AliHLTOUT::~AliHLTOUT()
66 8 : {
67 : // destructor
68 4 : if (CheckStatusFlag(kIsSubCollection)) {
69 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "~AliHLTOUT" , __FILE__ , __LINE__ , "severe internal error: collection has not been released, potential crash due to invalid pointer");
70 : }
71 :
72 4 : if (fpDataObject) {
73 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
74 : }
75 4 : fpDataObject=NULL;
76 4 : }
77 : AliHLTOUT* AliHLTOUT::fgGlobalInstance=NULL;
78 :
79 : int AliHLTOUT::Init()
80 : {
81 : // see header file for class documentation
82 : int iResult=0;
83 :
84 : // ignore if already initialized
85 8 : if (fBlockDescList.size()>0) {
86 0 : return 0;
87 : }
88 :
89 4 : SetStatusFlag(kCollecting);
90 4 : if ((iResult=GenerateIndex())>=0) {
91 4 : if ((iResult=InitHandlers())>=0) {
92 : }
93 4 : }
94 4 : ClearStatusFlag(kCollecting);
95 4 : return iResult;
96 4 : }
97 :
98 : int AliHLTOUT::GetNofDataBlocks()
99 : {
100 : // get number of data blocks
101 8 : return fBlockDescList.size();
102 : }
103 :
104 : int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
105 : AliHLTModuleAgent::AliHLTOUTHandlerType handlerType,
106 : bool skipProcessed)
107 : {
108 : // select the first data block according to data type, specification and
109 : // handler type
110 4 : fCurrent=0;
111 4 : fSearchDataType=dt;
112 4 : fSearchSpecification=spec;
113 4 : fSearchHandlerType=handlerType;
114 8 : if (skipProcessed) SetStatusFlag(kSkipProcessed);
115 0 : else ClearStatusFlag(kSkipProcessed);
116 4 : return FindAndSelectDataBlock();
117 : }
118 :
119 : int AliHLTOUT::SelectNextDataBlock()
120 : {
121 : // select next data block according to selection criteria specified
122 : // for SelectFirstDataBlock
123 0 : if (fCurrent>=fBlockDescList.size()) return -ENOENT;
124 0 : fCurrent++;
125 0 : return FindAndSelectDataBlock();
126 0 : }
127 :
128 : int AliHLTOUT::FindAndSelectDataBlock()
129 : {
130 : // Select data block according to data type and specification, internal function
131 : // invoked by SelectFirstDataBlock/SelectNextDataBlock
132 8 : if (CheckStatusFlag(kLocked)) return -EPERM;
133 : int iResult=-ENOENT;
134 8 : while (fCurrent<fBlockDescList.size() && iResult==-ENOENT) {
135 0 : if (fBlockDescList[fCurrent]==fSearchDataType &&
136 0 : (fSearchSpecification==kAliHLTVoidDataSpec || fBlockDescList[fCurrent]==fSearchSpecification) &&
137 0 : (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent)==fSearchHandlerType) &&
138 0 : (!CheckStatusFlag(kBlockSelection) || fBlockDescList[fCurrent].IsSelected()) &&
139 0 : (!CheckStatusFlag(kSkipProcessed) || !fBlockDescList[fCurrent].IsProcessed())) {
140 0 : iResult=fBlockDescList[fCurrent].GetIndex();
141 : // TODO: check the byte order on the current system and the byte order of the
142 : // data block, print warning when mismatch and user did not check
143 : //AliHLTOUTByteOrder blockBO=CheckByteOrder();
144 0 : CheckByteOrder();
145 : /*
146 : if (blockBO!=fByteOrder) {
147 : SetStatusFlag(kByteOrderWarning);
148 :
149 : }
150 : */
151 0 : ClearStatusFlag(kByteOrderChecked);
152 :
153 : // TODO: check the alignment on the current system and the alignment of the
154 : // data block, print warning when mismatch and user did not check
155 0 : ClearStatusFlag(kAlignmentChecked);
156 :
157 0 : break;
158 : }
159 0 : fCurrent++;
160 : }
161 : return iResult;
162 4 : }
163 :
164 : int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
165 : {
166 : // fill data type and specification
167 : int iResult=-ENOENT;
168 0 : if (fCurrent<fBlockDescList.size()) {
169 : iResult=0;
170 0 : dt=fBlockDescList[fCurrent];
171 0 : spec=fBlockDescList[fCurrent];
172 0 : }
173 0 : return iResult;
174 : }
175 :
176 : const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
177 : {
178 : // Get handler descriptor of the selected data block.
179 0 : return FindHandlerDesc(fCurrent);
180 : }
181 :
182 : AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
183 : {
184 : // Get handler type of the selected data block.
185 0 : AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(fCurrent);
186 0 : AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
187 : return type;
188 0 : }
189 :
190 : AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
191 : {
192 : // Get the index of the current data block.
193 0 : if (fCurrent>=fBlockDescList.size()) return AliHLTOUTInvalidIndex;
194 0 : return fBlockDescList[fCurrent].GetIndex();
195 0 : }
196 :
197 : int AliHLTOUT::GetDataBuffer(AliHLTComponentBlockData& desc)
198 : {
199 : // fill block data descriptor and select the current data buffer
200 : // buffer has to be released using ReleaseDataBuffer
201 : int iResult=-ENOENT;
202 0 : if (fCurrent<fBlockDescList.size()) {
203 0 : AliHLTComponent::FillBlockData(desc);
204 0 : if ((iResult=fBlockDescList[fCurrent].GetDataBuffer(fpBuffer, desc.fSize))>=0) {
205 0 : desc.fPtr=const_cast<void*>(reinterpret_cast<const void*>(fpBuffer));
206 0 : desc.fDataType=fBlockDescList[fCurrent];
207 0 : desc.fSpecification=fBlockDescList[fCurrent];
208 0 : }
209 : }
210 0 : return iResult;
211 : }
212 :
213 : int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
214 : {
215 : // select and return the current data buffer
216 : // buffer has to be released using ReleaseDataBuffer
217 : int iResult=-ENOENT;
218 0 : pBuffer=NULL;
219 0 : size=0;
220 0 : if (fCurrent<fBlockDescList.size()) {
221 0 : if ((iResult=fBlockDescList[fCurrent].GetDataBuffer(fpBuffer, size))>=0) {
222 0 : pBuffer=fpBuffer;
223 0 : }
224 : }
225 0 : return iResult;
226 : }
227 :
228 : int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
229 : {
230 : // release data buffer, previously returned by GetDataBuffer
231 : int iResult=0;
232 0 : if (pBuffer==fpBuffer) {
233 0 : fpBuffer=NULL;
234 0 : } else {
235 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "ReleaseDataBuffer" , __FILE__ , __LINE__ , "buffer %p does not match the provided one %p", pBuffer, fpBuffer);
236 : }
237 0 : return iResult;
238 : }
239 :
240 : AliHLTModuleAgent* AliHLTOUT::GetAgent()
241 : {
242 : // get module agent of the selected data block
243 : AliHLTModuleAgent* pAgent=NULL;
244 0 : pAgent=FindHandlerDesc(fCurrent);
245 0 : return pAgent;
246 : }
247 :
248 : AliHLTOUTHandler* AliHLTOUT::GetHandler()
249 : {
250 : // get HLTOUT handler of the selected data block
251 : AliHLTOUTHandler* pHandler=NULL;
252 0 : pHandler=FindHandlerDesc(fCurrent);
253 0 : return pHandler;
254 : }
255 :
256 : int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
257 : {
258 : // default function, child must overload
259 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "WriteESD" , __FILE__ , __LINE__ , "method not implemented in base class");
260 0 : return -ENOSYS;
261 : }
262 :
263 : int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
264 : {
265 : // add new block descriptor
266 0 : if (!CheckStatusFlag(kCollecting)) return -EPERM;
267 : int iResult=0;
268 0 : fBlockDescList.push_back(desc);
269 : return iResult;
270 0 : }
271 :
272 : AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
273 : {
274 : // check the byte order of the current data block
275 : // NOTE: this functionality has not been tested and development was hardly finished
276 0 : if (fCurrent<fBlockDescList.size()) {
277 0 : SetStatusFlag(kByteOrderChecked);
278 0 : AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder(fBlockDescList[fCurrent].GetIndex());
279 : return order;
280 : }
281 0 : return kInvalidByteOrder;
282 0 : }
283 :
284 : int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
285 : {
286 : // check alignment of the current data block
287 : // NOTE: this functionality has not been tested and development was hardly finished
288 0 : if (fCurrent<fBlockDescList.size()) {
289 0 : SetStatusFlag(kAlignmentChecked);
290 0 : int alignment=CheckBlockAlignment(fBlockDescList[fCurrent].GetIndex(), type);
291 : return alignment;
292 : }
293 0 : return -ENOENT;
294 0 : }
295 :
296 : int AliHLTOUT::InitHandlers()
297 : {
298 : // init handlers for all registered blocks
299 : int iResult=0;
300 8 : AliHLTOUTIndexList remnants;
301 : int iCount=0;
302 :
303 : // -- Sergey Gorbunov
304 : // Clear list of handler pointers, created in previous event, because some of them may not exist anymore
305 : // --
306 4 : fDataHandlers.clear();
307 :
308 16 : for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
309 0 : iCount++;
310 0 : remnants.push_back(GetDataBlockIndex());
311 0 : AliHLTComponentDataType dt=kAliHLTVoidDataType;
312 0 : AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
313 0 : if (GetDataBlockDescription(dt, spec)<0) break;
314 : bool bHaveHandler=false;
315 0 : for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
316 0 : AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
317 0 : if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
318 0 : AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
319 0 : InsertHandler(fDataHandlers, entry);
320 0 : remnants.pop_back();
321 : bHaveHandler=true;
322 0 : if (fbVerbose) {
323 0 : stringstream sout;
324 0 : sout << "adding handler for block " << AliHLTComponent::DataType2Text(dt).c_str()
325 0 : << " 0x" << setfill('0') << setw(8) << hex << spec;
326 0 : cout << sout.str() << endl;
327 0 : }
328 : break;
329 0 : }
330 0 : }
331 0 : if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
332 : // ESDs are handled by the framework
333 0 : remnants.pop_back();
334 0 : }
335 0 : }
336 :
337 : // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
338 : // criterion
339 4 : if (GetNofDataBlocks()>iCount) {
340 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, GetNofDataBlocks());
341 : }
342 :
343 : // warning if handler not found
344 4 : if (remnants.size()>0) {
345 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "no handlers found for %d data blocks out of %d", remnants.size(), iCount);
346 0 : AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
347 0 : for (AliHLTOUTIndexList::iterator element=remnants.begin();
348 0 : element!=remnants.end() && block!=fBlockDescList.end();
349 0 : element++) {
350 0 : for (int trials=0; trials<2; trials++) {
351 : do {
352 : // we start searching the index from the current position in the block list
353 0 : if ((*block).GetIndex()==*element) break;
354 0 : } while ((++block)!=fBlockDescList.end());
355 0 : if (block==fBlockDescList.end()) {
356 : // rewind and try again
357 0 : block=fBlockDescList.begin();
358 0 : }
359 : }
360 0 : assert(block!=fBlockDescList.end());
361 : }
362 0 : }
363 :
364 4 : if (fbVerbose) Print();
365 :
366 : return iResult;
367 4 : }
368 :
369 : int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
370 : {
371 : // insert handler into list, called from child implementations
372 : int iResult=0;
373 0 : AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
374 0 : for (; element!=list.end();
375 0 : element++) {
376 0 : if (entry==(*element)) break;
377 : }
378 0 : if (element==list.end()) {
379 0 : list.push_back(entry);
380 0 : } else {
381 0 : element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
382 : }
383 0 : return iResult;
384 0 : }
385 :
386 : int AliHLTOUT::FillHandlerList(AliHLTOUTHandlerListEntryVector& list, AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
387 : {
388 : // fill a list according to specified handler type
389 : int iResult=0;
390 0 : for (iResult=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec, handlerType);
391 0 : iResult>=0;
392 0 : iResult=SelectNextDataBlock()) {
393 0 : AliHLTComponentDataType dt=kAliHLTVoidDataType;
394 0 : AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
395 0 : GetDataBlockDescription(dt, spec);
396 0 : AliHLTOUTHandler* pHandler=GetHandler();
397 0 : if (!pHandler) {
398 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "FillHandlerList" , __FILE__ , __LINE__ ,
399 : "missing HLTOUT handler for block of type kChain: agent %s, data type %s, specification %#x, ... skipping data block",
400 0 : GetAgent()?GetAgent()->GetModuleId():"invalid",
401 0 : AliHLTComponent::DataType2Text(dt).c_str(), spec);
402 0 : } else {
403 0 : InsertHandler(list, GetDataBlockHandlerDesc());
404 : }
405 0 : }
406 : // TODO: the return value of SelectFirst/NextDataBlock must be
407 : // changed in order to avoid this check
408 0 : if (iResult==-ENOENT) iResult=0;
409 :
410 0 : return iResult;
411 0 : }
412 :
413 : int AliHLTOUT::RemoveEmptyDuplicateHandlers(AliHLTOUTHandlerListEntryVector& list)
414 : {
415 : // remove empty handlers from list
416 : int iResult=0;
417 0 : AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
418 0 : while (element!=list.end()) {
419 0 : if (element->IsEmpty()) {
420 0 : AliHLTOUTHandler* pHandler=*element;
421 0 : AliHLTModuleAgent* pAgent=*element;
422 0 : AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*element;
423 0 : if (FindHandler(list, desc)>=0) {
424 0 : element=list.erase(element);
425 : if (pAgent) {
426 : // -- Sergey Gorbunov
427 : // Do not delete the handler here, only remove it from the input list.
428 : // When the pointer is deleted form AliHLTSystem::fpChainHandlers list, it is still kept in AliHLTOut::fDataHandlers list and may be used later
429 : // --
430 : // pAgent->DeleteOutputHandler(pHandler);
431 : }
432 : // we are already at the next element
433 0 : continue;
434 : }
435 0 : }
436 0 : element++;
437 : }
438 0 : return iResult;
439 0 : }
440 :
441 : int AliHLTOUT::FindHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc)
442 : {
443 : // find handler according to descriptor
444 0 : for (int i=0; i<(int)list.size(); i++) {
445 0 : if (list[i]==desc) return i;
446 : }
447 0 : return -ENOENT;
448 0 : }
449 :
450 : int AliHLTOUT::InvalidateBlocks(AliHLTOUTHandlerListEntryVector& list)
451 : {
452 : // invalidate all handlers in a list
453 0 : for (AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
454 0 : element!=list.end();
455 0 : element++) {
456 0 : element->InvalidateBlocks();
457 : }
458 0 : return 0;
459 : }
460 :
461 : const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
462 : {
463 : // get handler description
464 0 : if (blockIndex<fBlockDescList.size()) {
465 0 : return fBlockDescList[blockIndex].GetHandlerDesc();
466 : }
467 0 : return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::VoidHandlerListEntry());
468 0 : }
469 :
470 : AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
471 : :
472 126 : fpHandler(NULL),
473 63 : fpHandlerDesc(NULL),
474 63 : fpAgent(NULL),
475 63 : fBlocks()
476 126 : {
477 : // default constructor
478 126 : }
479 :
480 : AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler,
481 : AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
482 : AliHLTModuleAgent* pAgent,
483 : AliHLTUInt32_t index)
484 : :
485 0 : fpHandler(pHandler),
486 0 : fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
487 0 : fpAgent(pAgent),
488 0 : fBlocks()
489 0 : {
490 : // constructor
491 0 : *fpHandlerDesc=handlerDesc;
492 0 : fBlocks.push_back(index);
493 0 : }
494 :
495 : AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
496 : :
497 0 : fpHandler(src.fpHandler),
498 0 : fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
499 0 : fpAgent(src.fpAgent),
500 0 : fBlocks()
501 0 : {
502 : // copy constructor
503 0 : *fpHandlerDesc=*src.fpHandlerDesc;
504 0 : fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
505 0 : }
506 :
507 : AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
508 126 : {
509 : // destructor
510 126 : if (fpHandlerDesc) delete fpHandlerDesc;
511 63 : fpHandlerDesc=NULL;
512 126 : }
513 :
514 : AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
515 : {
516 : // assignment operator
517 0 : if (this==&src) return *this;
518 0 : fpHandler=src.fpHandler;
519 0 : if (src.fpHandlerDesc)
520 0 : *fpHandlerDesc=*src.fpHandlerDesc;
521 0 : fpAgent=src.fpAgent;
522 0 : fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
523 0 : return *this;
524 0 : }
525 :
526 : AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
527 : {
528 : // access operator
529 0 : return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
530 : }
531 :
532 : bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
533 : {
534 : // comparison operator
535 0 : if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
536 0 : assert(entry.fpAgent==fpAgent);
537 0 : if (entry.fpAgent!=fpAgent) return false;
538 0 : return true;
539 0 : }
540 :
541 : bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
542 : {
543 : // comparison operator
544 0 : if (!fpHandlerDesc) return false;
545 0 : return *fpHandlerDesc==handlerType;
546 0 : }
547 :
548 : bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc) const
549 : {
550 : // comparison operator
551 0 : if (!fpHandlerDesc) return false;
552 0 : return *fpHandlerDesc==desc;
553 0 : }
554 :
555 : void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(const AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
556 : {
557 : // add block index, a handler can serve multiple blocks
558 0 : AliHLTOUTIndexList::const_iterator element;
559 0 : for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
560 0 : AddIndex(*element);
561 : }
562 0 : }
563 :
564 : void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
565 : {
566 : // add block index, a handler can serve multiple blocks
567 0 : fBlocks.push_back(index);
568 0 : }
569 :
570 : bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index) const
571 : {
572 : // check if handler serves the specified block
573 0 : AliHLTOUTIndexList::iterator element;
574 0 : for (unsigned int i=0; i<fBlocks.size(); i++) {
575 0 : if (fBlocks[i]==index) return true;
576 : }
577 0 : return false;
578 0 : }
579 :
580 126 : const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
581 :
582 : AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
583 : {
584 : // swap a 64 bit number
585 0 : return ((src & 0xFFULL) << 56) |
586 0 : ((src & 0xFF00ULL) << 40) |
587 0 : ((src & 0xFF0000ULL) << 24) |
588 0 : ((src & 0xFF000000ULL) << 8) |
589 0 : ((src & 0xFF00000000ULL) >> 8) |
590 0 : ((src & 0xFF0000000000ULL) >> 24) |
591 0 : ((src & 0xFF000000000000ULL) >> 40) |
592 0 : ((src & 0xFF00000000000000ULL) >> 56);
593 : }
594 :
595 : AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
596 : {
597 : // swap a 32 bit number
598 0 : return ((src & 0xFFULL) << 24) |
599 0 : ((src & 0xFF00ULL) << 8) |
600 0 : ((src & 0xFF0000ULL) >> 8) |
601 0 : ((src & 0xFF000000ULL) >> 24);
602 : }
603 :
604 : AliHLTOUT* AliHLTOUT::New(AliRawReader* pRawReader)
605 : {
606 : // transparently create HLTOUT implementation for AliRawReader
607 0 : AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTRawReader", "libHLTrec.so");
608 0 : if (instance) {
609 0 : instance->SetParam(pRawReader);
610 0 : }
611 0 : return instance;
612 : }
613 :
614 : AliHLTOUT* AliHLTOUT::New(TTree* pDigitTree, int event)
615 : {
616 : // transparently create HLTOUT implementation for digit tree
617 0 : AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
618 0 : if (instance) {
619 0 : instance->SetParam(pDigitTree, event);
620 0 : }
621 0 : return instance;
622 : }
623 :
624 : AliHLTOUT* AliHLTOUT::New(const char* filename, int event)
625 : {
626 : // transparently create HLTOUT implementation for raw file
627 0 : AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
628 0 : if (instance) {
629 0 : instance->SetParam(filename, event);
630 0 : }
631 0 : return instance;
632 : }
633 :
634 : void AliHLTOUT::Delete(AliHLTOUT* pInstance)
635 : {
636 : // delete the HLTOUT instance
637 : // check if the library is still there in order to have the
638 : // destructor available
639 :
640 0 : if (!pInstance) return;
641 0 : if (pInstance==fgGlobalInstance) return;
642 :
643 0 : TClass* pCl1=TClass::GetClass("AliHLTOUTRawReader");
644 0 : TClass* pCl2=TClass::GetClass("AliHLTOUTDigitReader");
645 0 : if (!pCl1 && !pCl2) {
646 0 : AliHLTLogging log;
647 0 : log.Logging(kHLTLogError, "AliHLTOUT::Delete", "HLTOUT handling", "potential memory leak: libHLTrec library not available, skipping destruction %p", pInstance);
648 : return;
649 0 : }
650 :
651 0 : delete pInstance;
652 0 : }
653 :
654 : void AliHLTOUT::SetParam(AliRawReader* /*pRawReader*/)
655 : {
656 : // see header file for class documentation
657 : // default implementation, we should never get here
658 : // this function can only be called from the class itsself and
659 : // is intended to be used with the New functions. If we get into
660 : // the default implementation there is a class mismatch.
661 0 : assert(0);
662 : fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
663 : }
664 :
665 : void AliHLTOUT::SetParam(TTree* /*pDigitTree*/, int /*event*/)
666 : {
667 : // see header file for class documentation
668 : // default implementation, we should never get here
669 : // this function can only be called from the class itsself and
670 : // is intended to be used with the New functions. If we get into
671 : // the default implementation there is a class mismatch.
672 0 : assert(0);
673 : fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
674 : }
675 :
676 : void AliHLTOUT::SetParam(const char* /*filename*/, int /*event*/)
677 : {
678 : // see header file for class documentation
679 : // default implementation, we should never get here
680 : // this function can only be called from the class itsself and
681 : // is intended to be used with the New functions. If we get into
682 : // the default implementation there is a class mismatch.
683 0 : assert(0);
684 : fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
685 : }
686 :
687 : int AliHLTOUT::SelectDataBlock()
688 : {
689 : // mark the current data block for processing
690 : int iResult=0;
691 0 : if (fCurrent>=fBlockDescList.size()) return 0;
692 0 : fBlockDescList[fCurrent].Select(true);
693 0 : EnableBlockSelection();
694 0 : return iResult;
695 0 : }
696 :
697 : int AliHLTOUT::SelectDataBlocks(const AliHLTOUTHandlerListEntry* pHandlerEntry)
698 : {
699 : // mark all data blocks served by specified handler for processing
700 : int iResult=0;
701 0 : if (!pHandlerEntry) return 0;
702 :
703 0 : AliHLTModuleAgent* pAgent=*pHandlerEntry;
704 0 : AliHLTLogging log;
705 0 : log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", "selecting blocks for handler %s", pAgent->GetModuleId());
706 0 : AliHLTOUTBlockDescriptorVector::iterator element;
707 0 : for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
708 0 : block!=fBlockDescList.end();
709 0 : block++) {
710 0 : if (block->GetHandlerDesc()==*pHandlerEntry && pHandlerEntry->HasIndex(block->GetIndex())) {
711 0 : block->Select(true);
712 0 : log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " select block %s", AliHLTComponent::DataType2Text(*block).c_str());
713 0 : } else {
714 0 : log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " skip block %s", AliHLTComponent::DataType2Text(*block).c_str());
715 0 : block->Select(false);
716 : }
717 : }
718 0 : EnableBlockSelection();
719 :
720 : // Matthias 2009-07-03 bugfix: the fCurrent position was not reset at that
721 : // place. Also I think the data type and specification must be set in order
722 : // to make SelectFirst/NextDataBlock working on the selected collection
723 : // of data blocks
724 0 : AliHLTModuleAgent::AliHLTOUTHandlerDesc pHandlerDesc=*pHandlerEntry;
725 0 : fSearchDataType=pHandlerDesc;
726 0 : fSearchSpecification=kAliHLTVoidDataSpec;
727 0 : fSearchHandlerType=pHandlerDesc;
728 0 : fCurrent=0;
729 :
730 : return iResult;
731 0 : }
732 :
733 : int AliHLTOUT::EnableBlockSelection()
734 : {
735 : // enable block selection, in this mode only the blocks marked for
736 : // processing can be accessed
737 0 : SetStatusFlag(kBlockSelection);
738 0 : return 0;
739 : }
740 :
741 : int AliHLTOUT::DisableBlockSelection()
742 : {
743 : // disable block selection
744 0 : ClearStatusFlag(kBlockSelection);
745 0 : return 0;
746 : }
747 :
748 : int AliHLTOUT::ResetBlockSelection()
749 : {
750 : // reset the 'selected' flag for all blocks
751 0 : for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
752 0 : block!=fBlockDescList.end();
753 0 : block++) {
754 0 : block->Select(false);
755 : }
756 0 : return 0;
757 : }
758 :
759 : int AliHLTOUT::MarkDataBlockProcessed()
760 : {
761 : // mark the current data block as 'processed'
762 : int iResult=0;
763 0 : if (fCurrent>=fBlockDescList.size()) return 0;
764 0 : fBlockDescList[fCurrent].MarkProcessed();
765 0 : return iResult;
766 0 : }
767 :
768 : int AliHLTOUT::MarkDataBlocksProcessed(const AliHLTOUTHandlerListEntry* pHandlerDesc)
769 : {
770 : // mark all data blocks served by handler as processed
771 : int iResult=0;
772 0 : if (!pHandlerDesc) return 0;
773 :
774 0 : AliHLTOUTBlockDescriptorVector::iterator element;
775 0 : for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
776 0 : block!=fBlockDescList.end();
777 0 : block++) {
778 0 : if (block->GetHandlerDesc()==*pHandlerDesc && pHandlerDesc->HasIndex(block->GetIndex()))
779 0 : block->MarkProcessed();
780 : }
781 :
782 : return iResult;
783 0 : }
784 :
785 : int AliHLTOUT::AddSubCollection(AliHLTOUT* pCollection)
786 : {
787 : // add a sub-collection to the HLTOUT instance
788 : // all blocks of the sub-collection are accessed transparently through the master instance
789 : int iResult=0;
790 0 : if (!pCollection) return 0;
791 :
792 0 : SetStatusFlag(kCollecting);
793 : int index=-1;
794 0 : for (index=pCollection->SelectFirstDataBlock();
795 0 : index>=0;
796 0 : index=pCollection->SelectNextDataBlock()) {
797 0 : AliHLTComponentDataType dt=kAliHLTVoidDataType;
798 0 : AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
799 0 : pCollection->GetDataBlockDescription(dt, spec);
800 0 : AliHLTOUTBlockDescriptor desc(dt, spec, index, pCollection);
801 0 : AddBlockDescriptor(desc);
802 0 : iResult++;
803 0 : }
804 0 : if (iResult>0) {
805 0 : if (CheckStatusFlag(kIsSubCollection)) {
806 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "AddSubCollection" , __FILE__ , __LINE__ , "HLTOUT object %p has already been added as sub-collection", pCollection);
807 0 : } else {
808 0 : pCollection->SetStatusFlag(kIsSubCollection);
809 : }
810 : }
811 0 : ClearStatusFlag(kCollecting);
812 :
813 : return iResult;
814 0 : }
815 :
816 : int AliHLTOUT::ReleaseSubCollection(AliHLTOUT* pCollection)
817 : {
818 : // release a sub-collection
819 : int iResult=0;
820 0 : if (!pCollection) return 0;
821 :
822 0 : AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
823 0 : while (block!=fBlockDescList.end()) {
824 0 : if ((*block)==pCollection) {
825 0 : block=fBlockDescList.erase(block);
826 0 : continue;
827 : }
828 0 : block++;
829 : }
830 0 : pCollection->ClearStatusFlag(kIsSubCollection);
831 :
832 : return iResult;
833 0 : }
834 :
835 : int AliHLTOUT::Reset()
836 : {
837 : // reset HLTOUT instance
838 : // clears all blocks and handler descriptions
839 : int iResult=0;
840 8 : AliHLTOUTPVector subCollections;
841 4 : AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
842 8 : while (block!=fBlockDescList.end()) {
843 0 : if (!((*block)==this)) {
844 0 : AliHLTOUTPVector::iterator collection=subCollections.begin();
845 0 : for (; collection!=subCollections.end(); collection++)
846 0 : if((*block)==*collection) break;
847 0 : if (collection==subCollections.end())
848 0 : subCollections.push_back(block->GetCollection());
849 0 : }
850 0 : block=fBlockDescList.erase(block);
851 : }
852 :
853 12 : for (AliHLTOUTPVector::iterator collection=subCollections.begin();
854 4 : collection!=subCollections.end(); collection++) {
855 0 : (*collection)->Reset();
856 0 : (*collection)->ClearStatusFlag(kIsSubCollection);
857 : }
858 :
859 4 : ResetInput();
860 4 : fCurrentEventId=kAliHLTVoidEventID;
861 :
862 : return iResult;
863 4 : }
864 :
865 : int AliHLTOUT::ResetInput()
866 : {
867 : // default implementation, nothing to do
868 8 : return 0;
869 : }
870 :
871 : const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTBlockDescriptor::GetHandlerDesc()
872 : {
873 : // see header file for class documentation
874 0 : if (fpCollection) {
875 0 : AliHLTOUTHandlerListEntryVector::iterator element=fpCollection->fDataHandlers.begin();
876 0 : while (element!=fpCollection->fDataHandlers.end()) {
877 0 : if (element->HasIndex(GetIndex())) {
878 0 : return *element;
879 : }
880 0 : element++;
881 : }
882 0 : }
883 0 : return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::VoidHandlerListEntry());
884 0 : }
885 :
886 : TObject* AliHLTOUT::GetDataObject()
887 : {
888 : // check if the current block encodes a ROOT object and expand it
889 0 : if (fpDataObject) {
890 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
891 0 : ReleaseDataBuffer(fpObjectBuffer);
892 0 : }
893 0 : fpObjectBuffer=NULL;
894 0 : fObjectBufferSize=0;
895 0 : fpDataObject=NULL;
896 :
897 0 : if (GetDataBuffer(fpObjectBuffer, fObjectBufferSize)>=0) {
898 0 : fpDataObject=AliHLTMessage::Extract(fpObjectBuffer, fObjectBufferSize);
899 0 : } else {
900 0 : fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "can not fetch data buffer");
901 : }
902 :
903 0 : return fpDataObject;
904 : }
905 :
906 : int AliHLTOUT::ReleaseDataObject(TObject* pObject)
907 : {
908 : // release a ROOT object previously expanded from the currentr data block
909 0 : if (!pObject) return -EINVAL;
910 0 : if (pObject!=fpDataObject) {
911 0 : fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "attempt to release wrong data object %p, expected %p", pObject, fpDataObject);
912 0 : return -EINVAL;
913 : }
914 :
915 0 : delete fpDataObject;
916 0 : fpDataObject=NULL;
917 0 : ReleaseDataBuffer(fpObjectBuffer);
918 0 : fpObjectBuffer=NULL;
919 0 : fObjectBufferSize=0;
920 :
921 0 : return 0;
922 0 : }
923 :
924 : void AliHLTOUT::SetEventId(AliHLTUInt64_t id)
925 : {
926 : // set event id
927 0 : if (fCurrentEventId!=kAliHLTVoidEventID && fCurrentEventId!=id) {
928 0 : fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "SetEventId" , __FILE__ , __LINE__ , "event id was already set to 0x%llx, setting now to 0x%llx", fCurrentEventId, id);
929 0 : }
930 0 : fCurrentEventId=id;
931 0 : }
932 :
933 : void AliHLTOUT::Print(const char* option) const
934 : {
935 : // print info
936 : {
937 0 : for (AliHLTOUTBlockDescriptorVector::const_iterator i=fBlockDescList.begin();
938 0 : i!=fBlockDescList.end(); i++)
939 0 : i->Print(option);
940 : }
941 : {
942 0 : for (AliHLTOUTHandlerListEntryVector::const_iterator i=fDataHandlers.begin();
943 0 : i!=fDataHandlers.end(); i++)
944 0 : i->Print(option);
945 : }
946 0 : }
947 :
948 : void AliHLTOUT::AliHLTOUTBlockDescriptor::Print(const char* /*option*/) const
949 : {
950 : // print info
951 0 : stringstream sout;
952 0 : sout << "AliHLTOUTBlockDescriptor index 0x" << setfill('0') << setw(8) << hex << right << fIndex
953 0 : << ": " << AliHLTComponent::DataType2Text(fDataType).c_str()
954 0 : << " 0x" << setfill('0') << setw(8) << hex << fSpecification
955 0 : << " processed " << dec << fProcessed;
956 0 : cout << sout.str() << endl;
957 0 : }
958 :
959 : void AliHLTOUT::AliHLTOUTHandlerListEntry::Print(const char* /*option*/) const
960 : {
961 : // print info
962 0 : stringstream sout;
963 : AliHLTModuleAgent::AliHLTOUTHandlerType type=AliHLTModuleAgent::kUnknownOutput;
964 0 : AliHLTComponentDataType dt=kAliHLTVoidDataType;
965 0 : if (this->fpHandlerDesc) {
966 0 : type=*(this->fpHandlerDesc);
967 0 : dt=*(this->fpHandlerDesc);
968 0 : }
969 : const char* stype="";
970 0 : switch(type) {
971 0 : case AliHLTModuleAgent::kEsd: stype="ESD"; break;
972 0 : case AliHLTModuleAgent::kRawReader: stype="RawReader"; break;
973 0 : case AliHLTModuleAgent::kRawStream: stype="RawStream"; break;
974 0 : case AliHLTModuleAgent::kChain: stype="Chain"; break;
975 0 : case AliHLTModuleAgent::kProprietary: stype="Proprietary"; break;
976 : default: stype="unknown";
977 0 : }
978 0 : sout << "HLTOUT handler: "
979 0 : << " " << type << " (" << stype << ")"
980 0 : << " " << AliHLTComponent::DataType2Text(dt).c_str();
981 0 : cout << sout.str() << endl;
982 0 : }
|