Line data Source code
1 : // $Id$
2 : //**************************************************************************
3 : //* This file is property of and copyright by the *
4 : //* ALICE Experiment at CERN, All rights reserved. *
5 : //* *
6 : //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 : //* for The ALICE HLT 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 : /// @file AliHLTTask.cxx
19 : /// @author Matthias Richter
20 : /// @date
21 : /// @brief Implementation of HLT tasks.
22 : ///
23 :
24 : #include <cerrno>
25 : #include <cassert>
26 : #include <iostream>
27 : #include <string>
28 : #include <ctime>
29 : #include "AliHLTTask.h"
30 : #include "AliHLTConfiguration.h"
31 : #include "AliHLTConfigurationHandler.h"
32 : #include "AliHLTComponent.h"
33 : #include "AliHLTComponentHandler.h"
34 : #include "TList.h"
35 : #include "AliHLTErrorGuard.h"
36 :
37 : using std::cout;
38 :
39 : /** ROOT macro for the implementation of ROOT specific class methods */
40 126 : ClassImp(AliHLTTask)
41 :
42 0 : AliHLTTask::AliHLTTask()
43 : :
44 0 : fpConfiguration(NULL),
45 0 : fpComponent(NULL),
46 0 : fpDataBuffer(NULL),
47 0 : fListTargets(),
48 0 : fListDependencies(),
49 0 : fBlockDataArray()
50 0 : {
51 : // see header file for class documentation
52 : // or
53 : // refer to README to build package
54 : // or
55 : // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
56 0 : }
57 :
58 0 : AliHLTTask::AliHLTTask(AliHLTConfiguration* pConf)
59 : :
60 0 : fpConfiguration(pConf),
61 0 : fpComponent(NULL),
62 0 : fpDataBuffer(NULL),
63 0 : fListTargets(),
64 0 : fListDependencies(),
65 0 : fBlockDataArray()
66 0 : {
67 : // see header file for function documentation
68 0 : }
69 :
70 0 : AliHLTTask::~AliHLTTask()
71 0 : {
72 : // see header file for function documentation
73 0 : TObjLink* lnk=fListDependencies.FirstLink();
74 :
75 0 : while (lnk!=NULL) {
76 0 : AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject();
77 0 : pTask->UnsetTarget(this);
78 0 : lnk=lnk->Next();
79 : }
80 0 : lnk=fListTargets.FirstLink();
81 :
82 0 : while (lnk!=NULL) {
83 0 : AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject();
84 0 : pTask->UnsetDependency(this);
85 0 : lnk=lnk->Next();
86 : }
87 :
88 0 : if (fpComponent) delete fpComponent;
89 0 : fpComponent=NULL;
90 0 : }
91 :
92 : int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH)
93 : {
94 : // see header file for function documentation
95 : int iResult=0;
96 0 : if (fpConfiguration!=NULL && pConf!=NULL && fpConfiguration!=pConf) {
97 0 : HLTWarning("overriding existing reference to configuration object %p by %p",
98 : fpConfiguration, pConf);
99 : }
100 0 : if (pConf!=NULL) fpConfiguration=pConf;
101 0 : iResult=CreateComponent(fpConfiguration, pCH, fpComponent);
102 0 : if (iResult>=0) {
103 0 : iResult=CustomInit(pCH);
104 0 : }
105 0 : return iResult;
106 : }
107 :
108 : int AliHLTTask::CreateComponent(AliHLTConfiguration* pConfiguration, AliHLTComponentHandler* pCH, AliHLTComponent*& pComponent) const
109 : {
110 : // see header file for class documentation
111 : int iResult=0;
112 0 : if (!pConfiguration) return -EINVAL;
113 :
114 0 : const AliHLTConfiguration* pConf=AliHLTConfigurationHandler::FindSubstitution(*pConfiguration);
115 0 : if (!pConf) pConf=pConfiguration;
116 0 : if (pConf) {
117 0 : if (pCH) {
118 : int argc=0;
119 0 : const char** argv=NULL;
120 0 : if ((iResult=pConf->GetArguments(&argv))>=0) {
121 : argc=iResult; // just to make it clear
122 : // TODO: we have to think about the optional environment parameter,
123 : // currently just set to NULL.
124 0 : iResult=pCH->CreateComponent(pConf->GetComponentID(), pComponent);
125 0 : if (pComponent && iResult>=0) {
126 0 : TString description;
127 0 : description.Form("chainid=%s", GetName());
128 0 : pComponent->SetComponentDescription(description.Data());
129 0 : const AliHLTAnalysisEnvironment* pEnv=pCH->GetEnvironment();
130 0 : if ((iResult=pComponent->Init(pEnv, NULL, argc, argv))>=0) {
131 : //HLTDebug("component %s (%p) created", pComponent->GetComponentID(), pComponent);
132 : } else {
133 0 : HLTError("Initialization of component \"%s\" failed with error %d", pComponent->GetComponentID(), iResult);
134 : }
135 0 : } else {
136 : //HLTError("can not find component \"%s\" (%d)", pConf->GetComponentID(), iResult);
137 : }
138 : } else {
139 0 : HLTError("can not get argument list for configuration %s (%s)", pConf->GetName(), pConf->GetComponentID());
140 : iResult=-EINVAL;
141 : }
142 0 : } else {
143 0 : HLTError("component handler instance needed for task initialization");
144 : iResult=-EINVAL;
145 : }
146 : } else {
147 0 : HLTError("configuration object instance needed for task initialization");
148 : iResult=-EINVAL;
149 : }
150 : return iResult;
151 0 : }
152 :
153 : int AliHLTTask::Deinit()
154 : {
155 : // see header file for function documentation
156 : int iResult=0;
157 0 : CustomCleanup();
158 0 : AliHLTComponent* pComponent=GetComponent();
159 0 : fpComponent=NULL;
160 0 : if (pComponent) {
161 : //HLTDebug("delete component %s (%p)", pComponent->GetComponentID(), pComponent);
162 0 : pComponent->Deinit();
163 0 : delete pComponent;
164 : } else {
165 0 : HLTWarning("task doesn't seem to be in initialized");
166 : }
167 0 : return iResult;
168 : }
169 :
170 : const char *AliHLTTask::GetName() const
171 : {
172 : // see header file for function documentation
173 0 : if (fpConfiguration)
174 0 : return fpConfiguration->GetName();
175 0 : return TObject::GetName();
176 0 : }
177 :
178 : AliHLTConfiguration* AliHLTTask::GetConf() const
179 : {
180 : // see header file for function documentation
181 0 : return fpConfiguration;
182 : }
183 :
184 : AliHLTComponent* AliHLTTask::GetComponent() const
185 : {
186 : // see header file for function documentation
187 0 : return fpComponent;
188 : }
189 :
190 : AliHLTTask* AliHLTTask::FindDependency(const char* id)
191 : {
192 : // see header file for function documentation
193 : AliHLTTask* pTask=NULL;
194 0 : if (id) {
195 0 : pTask=(AliHLTTask*)fListDependencies.FindObject(id);
196 0 : }
197 0 : return pTask;
198 : }
199 :
200 : int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
201 : {
202 : // see header file for function documentation
203 : int iResult=0;
204 0 : if (id) {
205 : AliHLTTask* pDep=NULL;
206 0 : if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
207 0 : if (pTgtList) pTgtList->Add(pDep);
208 : iResult++;
209 0 : } else {
210 0 : TObjLink* lnk=fListDependencies.FirstLink();
211 0 : while (lnk && iResult==0) {
212 0 : pDep=(AliHLTTask*)lnk->GetObject();
213 0 : if (pDep) {
214 0 : if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
215 0 : if (pTgtList) pTgtList->AddFirst(pDep);
216 0 : iResult++;
217 0 : }
218 : } else {
219 : iResult=-EFAULT;
220 : }
221 0 : lnk=lnk->Next();
222 : }
223 : }
224 0 : } else {
225 : iResult=-EINVAL;
226 : }
227 0 : return iResult;
228 : }
229 :
230 : void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
231 : {
232 : // see header file for function documentation
233 0 : HLTLogKeyword("task dependencies");
234 : int iResult=0;
235 0 : TList tgtList;
236 0 : if (bFromConfiguration) {
237 0 : if (fpConfiguration)
238 0 : iResult=fpConfiguration->FollowDependency(id, &tgtList);
239 : else
240 : iResult=-EFAULT;
241 : } else
242 0 : iResult=FollowDependency(id, &tgtList);
243 0 : if (iResult>0) {
244 0 : HLTMessage(" dependency level %d ", iResult);
245 0 : TObjLink* lnk=tgtList.FirstLink();
246 : int i=iResult;
247 0 : char* pSpace = new char[iResult+1];
248 0 : if (pSpace) {
249 0 : memset(pSpace, 32, iResult);
250 0 : pSpace[i]=0;
251 0 : while (lnk) {
252 0 : TObject* obj=lnk->GetObject();
253 0 : HLTMessage(" %s^-- %s ", &pSpace[i--], obj->GetName());
254 0 : lnk=lnk->Next();
255 : }
256 0 : delete [] pSpace;
257 : } else {
258 : iResult=-ENOMEM;
259 : }
260 0 : }
261 0 : }
262 :
263 : int AliHLTTask::SetDependency(AliHLTTask* pDep)
264 : {
265 : // see header file for function documentation
266 : int iResult=0;
267 0 : if (pDep) {
268 0 : if (FindDependency(pDep->GetName())==NULL) {
269 0 : fListDependencies.Add(pDep);
270 0 : } else {
271 : iResult=-EEXIST;
272 : }
273 : } else {
274 : iResult=-EINVAL;
275 : }
276 0 : return iResult;
277 : }
278 :
279 : int AliHLTTask::UnsetDependency(AliHLTTask* pDep)
280 : {
281 : // see header file for function documentation
282 0 : fListDependencies.Remove(pDep);
283 0 : if (fpConfiguration) {
284 0 : fpConfiguration->InvalidateSources();
285 0 : }
286 0 : return 0;
287 : }
288 :
289 : int AliHLTTask::CheckDependencies()
290 : {
291 : // see header file for function documentation
292 : int iResult=0;
293 0 : AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
294 0 : while (pSrc) {
295 0 : if (FindDependency(pSrc->GetName())==NULL) {
296 : //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
297 0 : iResult++;
298 0 : }
299 0 : pSrc=fpConfiguration->GetNextSource();
300 : }
301 0 : return iResult;
302 : }
303 :
304 :
305 : int AliHLTTask::Depends(AliHLTTask* pTask)
306 : {
307 : // see header file for function documentation
308 : int iResult=0;
309 0 : if (pTask) {
310 0 : if (fpConfiguration) {
311 0 : iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
312 : if (iResult>0) {
313 : //HLTDebug("task \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
314 : } else {
315 : //HLTDebug("task \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
316 : }
317 0 : } else {
318 : iResult=-EFAULT;
319 : }
320 : } else {
321 : iResult=-EINVAL;
322 : }
323 0 : return iResult;
324 : }
325 :
326 : AliHLTTask* AliHLTTask::FindTarget(const char* id)
327 : {
328 : // see header file for function documentation
329 : AliHLTTask* pTask=NULL;
330 0 : if (id) {
331 0 : pTask=(AliHLTTask*)fListTargets.FindObject(id);
332 0 : }
333 0 : return pTask;
334 : }
335 :
336 : int AliHLTTask::SetTarget(AliHLTTask* pTgt)
337 : {
338 : // see header file for function documentation
339 : int iResult=0;
340 0 : if (pTgt) {
341 0 : if (FindTarget(pTgt->GetName())==NULL) {
342 0 : fListTargets.Add(pTgt);
343 0 : } else {
344 : iResult=-EEXIST;
345 : }
346 : } else {
347 : iResult=-EINVAL;
348 : }
349 0 : return iResult;
350 : }
351 :
352 : int AliHLTTask::UnsetTarget(AliHLTTask* pTarget)
353 : {
354 : // see header file for function documentation
355 0 : fListTargets.Remove(pTarget);
356 0 : return 0;
357 : }
358 :
359 : int AliHLTTask::StartRun()
360 : {
361 : // see header file for function documentation
362 : int iResult=0;
363 : int iNofInputDataBlocks=0;
364 0 : AliHLTComponent* pComponent=GetComponent();
365 0 : if (pComponent) {
366 : // determine the number of input data blocks provided from the source tasks
367 : { // set scope for lnk as a local variable
368 0 : TObjLink* lnk=fListDependencies.FirstLink();
369 0 : while (lnk && iResult>=0) {
370 0 : AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
371 0 : if (pSrcTask) {
372 0 : if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
373 0 : iNofInputDataBlocks+=iResult;
374 0 : } else if (iResult==0) {
375 0 : HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
376 : } else {
377 0 : HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
378 : iResult=-EFAULT;
379 : }
380 : }
381 0 : lnk=lnk->Next();
382 : }
383 : }
384 0 : if (iResult>=0) {
385 0 : if (fBlockDataArray.size()>0) {
386 0 : HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
387 0 : fBlockDataArray.clear();
388 0 : }
389 :
390 : // component init
391 : // the initialization of the component is done by the ComponentHandler after creation
392 : // of the component.
393 : //iResult=Init( AliHLTAnalysisEnvironment* environ, void* environ_param, int argc, const char** argv );
394 :
395 : // allocate the data buffer, which controls the output buffer and subscriptions
396 0 : if (iResult>=0) {
397 0 : fpDataBuffer=new AliHLTDataBuffer;
398 0 : if (fpDataBuffer!=NULL) {
399 0 : fpDataBuffer->SetLocalLoggingLevel(GetLocalLoggingLevel());
400 : HLTDebug("created data buffer %p for task %s (%p)", fpDataBuffer, GetName(), this);
401 0 : TObjLink* lnk=fListTargets.FirstLink();
402 0 : while (lnk && iResult>=0) {
403 0 : AliHLTTask* pTgtTask=(AliHLTTask*)lnk->GetObject();
404 0 : if (pTgtTask) {
405 0 : if ((iResult=fpDataBuffer->SetConsumer(pTgtTask->GetComponent()))>=0) {
406 : }
407 : } else {
408 : iResult=-EFAULT;
409 0 : break;
410 : }
411 0 : lnk=lnk->Next();
412 0 : }
413 0 : } else {
414 0 : HLTFatal("can not create data buffer object, memory allocation failed");
415 : iResult=-ENOMEM;
416 : }
417 : }
418 : }
419 : if (iResult>=0) {
420 : // send the SOR event
421 :
422 : }
423 0 : } else {
424 0 : HLTError("task %s (%p) does not have a component", GetName(), this);
425 : iResult=-EFAULT;
426 : }
427 0 : return iResult;
428 0 : }
429 :
430 : int AliHLTTask::EndRun()
431 : {
432 : // see header file for function documentation
433 : int iResult=0;
434 0 : if (fBlockDataArray.size()>0) {
435 0 : fBlockDataArray.clear();
436 0 : }
437 0 : if (fpDataBuffer) {
438 : AliHLTDataBuffer* pBuffer=fpDataBuffer;
439 0 : fpDataBuffer=NULL;
440 0 : delete pBuffer;
441 0 : }
442 0 : return iResult;
443 : }
444 :
445 : int AliHLTTask::ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType, AliHLTTriggerMask_t trgMask,
446 : AliHLTUInt32_t timestamp, AliHLTUInt32_t participatingDetectors)
447 : {
448 : // see header file for function documentation
449 : int iResult=0;
450 0 : AliHLTComponent* pComponent=GetComponent();
451 0 : if (pComponent && fpDataBuffer) {
452 : HLTDebug("Processing task %s (%p) fpDataBuffer %p", GetName(), this, fpDataBuffer);
453 0 : fpDataBuffer->Reset();
454 : int iSourceDataBlock=0;
455 : int iInputDataVolume=0;
456 :
457 0 : AliHLTTask* pSrcTask=NULL;
458 0 : AliHLTTaskPList subscribedTaskList;
459 0 : TObjLink* lnk=fListDependencies.FirstLink();
460 :
461 : // instances of SOR and EOR events to be kept
462 : int iSOR=-1;
463 : int iEOR=-1;
464 : // TODO 2009-09-30
465 : // generalize handling of the special blocks to be forwarded on SOR and EOR
466 : // just adding a new specific handling for the ECS parameter block as a quick
467 : // solution
468 : int iECS=-1;
469 :
470 : // subscribe to all source tasks
471 0 : fBlockDataArray.clear();
472 0 : while (lnk && iResult>=0) {
473 0 : pSrcTask=(AliHLTTask*)lnk->GetObject();
474 0 : if (pSrcTask) {
475 0 : int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
476 0 : if (iMatchingDB<0) {
477 0 : HLTError("task %s (%p): error getting no of matching data blocks from task %s (%p), error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iMatchingDB);
478 : iResult=iMatchingDB;
479 0 : break;
480 : } else if (iMatchingDB==0) {
481 : HLTDebug("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
482 : }
483 0 : if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) {
484 : iSOR=iEOR=iECS=-1;
485 0 : AliHLTComponentBlockDataList::iterator block=fBlockDataArray.begin();
486 0 : for (int i=0; block!=fBlockDataArray.end(); i++) {
487 : bool bRemove=0;
488 0 : bRemove|=(*block).fDataType==kAliHLTDataTypeSOR && !(iSOR<0 && (iSOR=i)>=0);
489 0 : bRemove|=(*block).fDataType==kAliHLTDataTypeEOR && !(iEOR<0 && (iEOR=i)>=0);
490 0 : bRemove|=(*block).fDataType==kAliHLTDataTypeECSParam && !(iECS<0 && (iECS=i)>=0);
491 : //HLTInfo("block %d, iSOR=%d iEOR=%d remove=%d", i, iSOR, iEOR, bRemove);
492 0 : if (i<iSourceDataBlock) {
493 0 : assert(!bRemove);
494 0 : } else if (bRemove) {
495 : HLTDebug("remove duplicated event %s (%d)", AliHLTComponent::DataType2Text((*block).fDataType).c_str(), i);
496 0 : pSrcTask->Release(&(*block), this);
497 0 : block=fBlockDataArray.erase(block);
498 0 : continue;
499 : } else {
500 0 : iInputDataVolume+=(*block).fSize;
501 : // put the source task as many times into the list as it provides data blocks
502 : // makes the bookkeeping for the data release easier
503 0 : subscribedTaskList.push_back(pSrcTask);
504 : }
505 0 : block++;
506 0 : }
507 : HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
508 0 : iSourceDataBlock=fBlockDataArray.size();
509 : iResult=0;
510 0 : } else {
511 0 : HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
512 : iResult=-EFAULT;
513 : }
514 0 : } else {
515 0 : HLTFatal("fatal internal error in ROOT list handling");
516 : iResult=-EFAULT;
517 : }
518 0 : lnk=lnk->Next();
519 : }
520 :
521 : // process the event
522 : int iNofTrial=0; // repeat processing if component returns -ENOSPC
523 : AliHLTUInt32_t iLastOutputDataSize=0;
524 0 : if (iResult>=0) {
525 : do {
526 : long unsigned int iOutputDataSize=0;
527 0 : AliHLTConfiguration* pConf=GetConf();
528 : // check if there was a buffer size specified, query output size
529 : // estimator from component otherwize
530 0 : if (pConf && pConf->GetOutputBufferSize()>=0) {
531 0 : iOutputDataSize=pConf->GetOutputBufferSize();
532 0 : } else {
533 0 : long unsigned int iConstBase=0;
534 0 : double fInputMultiplier=0;
535 0 : if (pComponent->GetComponentType()!=AliHLTComponent::kSink) {
536 0 : pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
537 : // add a small margin to the buffer to allow optional component
538 : // statistics
539 0 : iConstBase+=100;
540 : #if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
541 : for (AliHLTComponentBlockDataList::iterator element=fBlockDataArray.begin();
542 : element!=fBlockDataArray.end(); element++) {
543 : if (element->fDataType==kAliHLTDataTypeComponentStatistics) {
544 : iConstBase+=element->fSize;
545 : }
546 : }
547 : #endif
548 0 : }
549 0 : if (fInputMultiplier<0) {
550 0 : HLTWarning("ignoring negative input multiplier");
551 0 : fInputMultiplier=0;
552 0 : }
553 0 : iOutputDataSize=(long unsigned int)(fInputMultiplier*iInputDataVolume) + iConstBase;
554 : //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
555 0 : }
556 0 : if (iNofTrial == 0 && fpDataBuffer->GetMaxBufferSize() < iOutputDataSize) {
557 : //If the estimated buffer size exceeds the maximum buffer size of AliHLTRawBuffer, decrease the buffer size.
558 : //The estimation is often quite high, and GetMaxBufferSize should usually return a size that is sufficient.
559 0 : HLTImportant("Reducing estimated output buffer size of %lu to maximum output buffer size\n", iOutputDataSize);
560 0 : iOutputDataSize = fpDataBuffer->GetMaxBufferSize();
561 0 : }
562 0 : if (iNofTrial>0) {
563 : // dont process again if the buffer size is the same
564 0 : if (iLastOutputDataSize>=iOutputDataSize) break;
565 0 : HLTImportant("processing event %d again with buffer size %d", eventNo, iOutputDataSize);
566 : }
567 : AliHLTUInt8_t* pTgtBuffer=NULL;
568 0 : if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
569 : //HLTDebug("provided raw buffer %p", pTgtBuffer);
570 0 : AliHLTComponentEventData evtData;
571 0 : AliHLTComponent::FillEventData(evtData);
572 0 : if (eventNo>=0)
573 0 : evtData.fEventID=(AliHLTEventID_t)eventNo;
574 0 : if (timestamp < kMaxUInt) evtData.fEventCreation_s=timestamp;
575 : else
576 0 : evtData.fEventCreation_s=static_cast<AliHLTUInt32_t>(time(NULL));
577 0 : AliHLTComponentTriggerData trigData;
578 0 : AliHLTEventTriggerData evtTrigData;
579 0 : trigData.fStructSize=sizeof(trigData);
580 0 : trigData.fDataSize=sizeof(AliHLTEventTriggerData);
581 0 : memset(&evtTrigData, 0, trigData.fDataSize);
582 : // Setup the CDH in the trigger data, based on the event type, CTP trigger
583 : // mask and participating detectors.
584 0 : evtTrigData.fCommonHeaderWordCnt=gkAliHLTCommonHeaderCount;
585 : AliHLTUInt8_t l1msg = 0x0;
586 0 : switch (eventType)
587 : {
588 0 : case gkAliEventTypeData: l1msg = 0x00; break;
589 0 : case gkAliEventTypeDataReplay: l1msg = 0x00; break;
590 0 : case gkAliEventTypeStartOfRun: l1msg = (0xE << 2) | 0x01; break;
591 0 : case gkAliEventTypeEndOfRun: l1msg = (0xF << 2) | 0x01; break;
592 0 : case gkAliEventTypeCalibration: l1msg = (0x1 << 6) | 0x01; break;
593 0 : case gkAliEventTypeSoftware: l1msg = 0x01; break;
594 : }
595 0 : evtTrigData.fCommonHeader[1] = (AliHLTUInt32_t(l1msg) << 14) | (0x03000000); //We have to set a CDH version, use 3 because we support 100 trigger classes below (0x03000000)
596 0 : evtTrigData.fCommonHeader[3] = ((l1msg & 0x1) == 0x1) ? (participatingDetectors & 0xFFFFFF) : 0x0;
597 0 : evtTrigData.fCommonHeader[5] = (trgMask & AliHLTTriggerMask_t(0xffffffff)).to_ulong();
598 0 : evtTrigData.fCommonHeader[6] = ((trgMask>>32) & AliHLTTriggerMask_t(0x3ffff)).to_ulong();
599 0 : evtTrigData.fCommonHeader[7] = ((trgMask>>50) & AliHLTTriggerMask_t(0xffffffff)).to_ulong();
600 0 : evtTrigData.fCommonHeader[8] = ((trgMask>>72) & AliHLTTriggerMask_t(0x3ffff)).to_ulong();
601 :
602 0 : trigData.fData=&evtTrigData;
603 0 : iLastOutputDataSize=iOutputDataSize;
604 0 : AliHLTUInt32_t size=iOutputDataSize;
605 0 : AliHLTUInt32_t outputBlockCnt=0;
606 0 : AliHLTComponentBlockData* outputBlocks=NULL;
607 0 : AliHLTComponentEventDoneData* edd=NULL;
608 0 : if (pTgtBuffer!=NULL || iOutputDataSize==0) {
609 : // add event type data block
610 : // the block is removed immediately after processing from the list
611 0 : AliHLTComponentBlockData eventTypeBlock;
612 0 : AliHLTComponent::FillBlockData(eventTypeBlock);
613 : // Note: no payload!
614 0 : eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
615 0 : eventTypeBlock.fSpecification=eventType;
616 0 : fBlockDataArray.push_back(eventTypeBlock);
617 :
618 0 : if (CheckFilter(kHLTLogDebug)) Print("proc");
619 :
620 : AliHLTUInt32_t iblock=0;
621 : // check input and output buffers for consistency
622 : // to be enabled after fixing bug with DataBuffer and forwarded SOR/EOR
623 : //for (iblock=0; iblock<fBlockDataArray.size(); iblock++) {
624 : // if ((AliHLTUInt8_t*)fBlockDataArray[iblock].fPtr >= pTgtBuffer+size) continue;
625 : // if (pTgtBuffer >= (AliHLTUInt8_t*)fBlockDataArray[iblock].fPtr+fBlockDataArray[iblock].fSize) continue;
626 : // HLTFatal("input and output buffer overlap for block descriptor %d (ptr %p size %d): output buffer %p %d",
627 : // iblock, fBlockDataArray[iblock].fPtr, fBlockDataArray[iblock].fSize,
628 : // pTgtBuffer, size);
629 : //}
630 :
631 : // process
632 0 : evtData.fBlockCnt=fBlockDataArray.size();
633 0 : iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
634 : HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt);
635 :
636 : // EventDoneData is for the moment ignored in AliHLTSystem
637 0 : if (edd) {
638 : HLTDebug("got EventDoneData size %d", edd->fDataSize);
639 0 : delete [] reinterpret_cast<char*>(edd);
640 0 : edd=NULL;
641 0 : }
642 :
643 : // remove event data block
644 0 : fBlockDataArray.pop_back();
645 :
646 : // check for forwarded blocks.
647 : // loop over all output blocks and check
648 : // 1. for duplicate blocks (pointing to same location in output buffer
649 : // or to the same buffer)
650 : // 2. for blocks forwarded from the input.
651 0 : if (iResult>=0 && outputBlocks) {
652 0 : if (fListTargets.First()!=NULL) {
653 0 : AliHLTComponentBlockDataList segments;
654 0 : for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
655 : // consistency check for data reference
656 0 : if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
657 0 : outputBlocks[oblock].fOffset!=0) {
658 0 : HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: "
659 : "for new blocks use offset only, forwarded blocks have fPtr set only",
660 : AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
661 : outputBlocks[oblock].fSpecification,
662 : outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset);
663 : }
664 :
665 : // check for duplicates in the output
666 : // this check applies for forwarded data blocks where
667 : // the ptr is not inside the target buffer
668 : AliHLTUInt32_t checkblock=0;
669 0 : for (; checkblock<oblock; checkblock++) {
670 0 : if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
671 0 : outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) {
672 0 : if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize ||
673 0 : outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) {
674 0 : HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p "
675 : "but differ in data type and/or size: %d vs. %d, ignoring block %d",
676 : oblock,
677 : AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
678 : outputBlocks[oblock].fSpecification,
679 : checkblock,
680 : AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(),
681 : outputBlocks[checkblock].fSpecification,
682 : outputBlocks[oblock].fPtr,
683 : outputBlocks[oblock].fSize,
684 : outputBlocks[checkblock].fSize,
685 : checkblock);
686 : }
687 : // ignore from the second copy
688 : break;
689 : }
690 : }
691 0 : if (checkblock<oblock) continue;
692 :
693 : // search for the forwarded data blocks
694 : // new data blocks are announced to the data buffer, forwarded data blocks
695 : // to the publisher task. The publisher task of a forwarded data block is
696 : // removed from the list in order to keep the buffer open. It will be releases
697 : // when the subscribing task releases it
698 : iblock=0;
699 0 : for (; iblock<fBlockDataArray.size(); iblock++) {
700 0 : if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) {
701 : // the event type data block is an artificial data block
702 : // ignore if it was forwarded
703 : break;
704 : }
705 0 : if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
706 0 : assert(subscribedTaskList[iblock]!=NULL);
707 0 : if (subscribedTaskList[iblock]==NULL) {
708 0 : ALIHLTERRORGUARD(1, "missing parent task for forwarded data block %s 0x%08x, original data block %s 0x%08x, subsequent errors are suppressed",
709 : AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
710 : outputBlocks[oblock].fSpecification,
711 : AliHLTComponent::DataType2Text(outputBlocks[iblock].fDataType).c_str(),
712 : outputBlocks[iblock].fSpecification);
713 : continue;
714 : }
715 : HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
716 0 : fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
717 0 : subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
718 0 : break;
719 : }
720 : }
721 0 : if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
722 0 : }
723 0 : if (pTgtBuffer && segments.size()>0) {
724 0 : iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
725 0 : }
726 0 : } else {
727 : // no forwarding, actually we dont even need to keep the data, this is a
728 : // dead end (fListTargets empty)
729 : //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
730 : }
731 0 : delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
732 0 : } else {
733 0 : fpDataBuffer->Reset();
734 : }
735 0 : if (fListTargets.First()!=NULL) {
736 0 : if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
737 : HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
738 0 : fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
739 0 : subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
740 0 : }
741 0 : if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
742 : HLTDebug("forward EOR event (%s) segment %d (source task %s %p) to data buffer %p", AliHLTComponent::DataType2Text(fBlockDataArray[iEOR].fDataType).c_str(), iEOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
743 0 : fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
744 0 : subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
745 0 : }
746 0 : if (iECS>=0 && subscribedTaskList[iECS]!=NULL) {
747 : HLTDebug("forward ECS event (%s) segment %d (source task %s %p) to data buffer %p", AliHLTComponent::DataType2Text(fBlockDataArray[iECS].fDataType).c_str(), iECS, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
748 0 : fpDataBuffer->Forward(subscribedTaskList[iECS], &fBlockDataArray[iECS]);
749 0 : subscribedTaskList[iECS]=NULL; // not to be released in the loop further down
750 0 : }
751 : }
752 0 : } else {
753 0 : HLTError("no target buffer available");
754 : iResult=-EFAULT;
755 : }
756 0 : } while (iResult==-ENOSPC && iNofTrial++<1);
757 : }
758 :
759 0 : fBlockDataArray.clear();
760 0 : if (CheckFilter(kHLTLogDebug)) Print("proc");
761 :
762 : // now release all buffers which we have subscribed to
763 : iSourceDataBlock=0;
764 0 : AliHLTTaskPList::iterator element;
765 0 : while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
766 0 : pSrcTask=*element;
767 0 : if (pSrcTask) {
768 : int iTempRes=0;
769 0 : if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
770 : HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
771 : } else {
772 0 : HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes);
773 : }
774 0 : }
775 0 : subscribedTaskList.erase(element);
776 0 : iSourceDataBlock++;
777 : }
778 0 : if (subscribedTaskList.size()>0) {
779 0 : HLTError("could not release all data buffers");
780 : }
781 0 : } else {
782 0 : HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer);
783 : iResult=-EFAULT;
784 : }
785 0 : return iResult;
786 0 : }
787 :
788 : int AliHLTTask::SubscribeSourcesAndSkip()
789 : {
790 : // function carries out the proper cleanup of the source components
791 : // by subscribing and releasing
792 : int iResult=0;
793 0 : AliHLTTask* pSrcTask=NULL;
794 0 : AliHLTTaskPList subscribedTaskList;
795 :
796 : // cleanup the data buffer
797 0 : if (fpDataBuffer) fpDataBuffer->Reset();
798 :
799 : // subscribe to all source tasks
800 0 : fBlockDataArray.clear();
801 0 : for (TObjLink* lnk=fListDependencies.FirstLink(); lnk!=NULL; lnk=lnk->Next()) {
802 0 : if (!lnk->GetObject()) continue;
803 0 : pSrcTask=dynamic_cast<AliHLTTask*>(lnk->GetObject());
804 0 : if (!pSrcTask) continue;
805 0 : unsigned iPosition=fBlockDataArray.size();
806 0 : if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>0) {
807 0 : for (unsigned i=iPosition; i<fBlockDataArray.size(); i++) {
808 0 : subscribedTaskList.push_back(pSrcTask);
809 : }
810 : HLTDebug("subscribed to %d blocks of task %s (%p)", iResult, pSrcTask->GetName(), pSrcTask, iResult);
811 0 : } else if (iResult<0) {
812 0 : HLTError("failed to subscribe to task %s (%p) with error %d", pSrcTask->GetName(), pSrcTask, iResult);
813 : }
814 0 : }
815 :
816 : unsigned iSourceDataBlock=0;
817 0 : AliHLTTaskPList::iterator element;
818 0 : while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
819 0 : assert(iSourceDataBlock<fBlockDataArray.size());
820 0 : pSrcTask=*element;
821 0 : if (pSrcTask && iSourceDataBlock<fBlockDataArray.size()) {
822 0 : if ((iResult=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
823 : HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
824 0 : } else if (iSourceDataBlock>=fBlockDataArray.size()) {
825 0 : HLTError("mismatch between list of subscribed tasks and block list in task %s (%p), can not release task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
826 : } else {
827 0 : HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iResult);
828 : }
829 : }
830 0 : subscribedTaskList.erase(element);
831 0 : iSourceDataBlock++;
832 : }
833 0 : if (iSourceDataBlock<fBlockDataArray.size()) {
834 0 : HLTWarning("not all subscriptions released for task %s (%p)", GetName(), this);
835 : }
836 :
837 : return 0;
838 0 : }
839 :
840 : int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
841 : {
842 : // see header file for function documentation
843 : int iResult=0;
844 0 : if (pConsumerTask) {
845 0 : if (fpDataBuffer) {
846 0 : iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
847 0 : } else {
848 0 : HLTFatal("internal data buffer missing");
849 : iResult=-EFAULT;
850 : }
851 : } else {
852 : iResult=-EINVAL;
853 : }
854 0 : return iResult;
855 : }
856 :
857 : int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
858 : {
859 : // see header file for function documentation
860 : int iResult=0;
861 0 : if (pConsumerTask) {
862 0 : AliHLTComponent* pComponent=GetComponent();
863 0 : if (!pComponent) {
864 : // init ?
865 0 : HLTError("component not initialized");
866 : iResult=-EFAULT;
867 0 : }
868 0 : if (pComponent) {
869 0 : iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
870 0 : } else {
871 0 : HLTFatal("task initialization failed");
872 : iResult=-EFAULT;
873 : }
874 0 : } else {
875 : iResult=-EINVAL;
876 : }
877 0 : return iResult;
878 : }
879 :
880 : int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
881 : {
882 : // see header file for function documentation
883 : int iResult=0;
884 0 : if (pConsumerTask) {
885 0 : if (fpDataBuffer) {
886 0 : iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
887 0 : } else {
888 0 : HLTFatal("internal data buffer missing");
889 : iResult=-EFAULT;
890 : }
891 : } else {
892 : iResult=-EINVAL;
893 : }
894 0 : return iResult;
895 : }
896 :
897 : int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
898 : {
899 : // see header file for function documentation
900 : int iResult=0;
901 0 : if (pConsumerTask && pBlockDesc) {
902 0 : if (fpDataBuffer) {
903 0 : iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
904 0 : } else {
905 0 : HLTFatal("internal data buffer missing");
906 : iResult=-EFAULT;
907 : }
908 : } else {
909 : iResult=-EINVAL;
910 : }
911 0 : return iResult;
912 : }
913 :
914 : void AliHLTTask::PrintStatus()
915 : {
916 : // see header file for function documentation
917 0 : HLTLogKeyword("task properties");
918 0 : AliHLTComponent* pComponent=GetComponent();
919 0 : if (pComponent) {
920 0 : HLTMessage(" component: %s (%p)", pComponent->GetComponentID(), pComponent);
921 : } else {
922 0 : HLTMessage(" no component set!");
923 : }
924 0 : if (fpConfiguration) {
925 0 : AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
926 0 : while (pSrc) {
927 : const char* pQualifier="unresolved";
928 0 : if (FindDependency(pSrc->GetName()))
929 0 : pQualifier="resolved";
930 0 : HLTMessage(" source: %s (%s)", pSrc->GetName(), pQualifier);
931 0 : pSrc=fpConfiguration->GetNextSource();
932 : }
933 0 : TObjLink* lnk = fListTargets.FirstLink();
934 0 : while (lnk) {
935 0 : TObject *obj = lnk->GetObject();
936 0 : HLTMessage(" target: %s", obj->GetName());
937 0 : lnk = lnk->Next();
938 : }
939 0 : } else {
940 0 : HLTMessage(" task not initialized");
941 : }
942 0 : }
943 :
944 : void AliHLTTask::Print(const char* options) const
945 : {
946 : // Overloaded from TObject
947 0 : if (strcmp(options, "proc")==0) {
948 : // print processing info
949 0 : HLTMessage("**********************************************");
950 0 : HLTMessage("******* AliHLTTask Processing info ***********");
951 0 : HLTMessage(" component: %p %s", fpComponent, (fpComponent?fpComponent->GetComponentID():""));
952 0 : HLTMessage(" data buffer: %p", fpDataBuffer);
953 0 : if (fpDataBuffer) fpDataBuffer->Print("");
954 0 : HLTMessage(" input block descriptors: %d", fBlockDataArray.size());
955 0 : for (unsigned i=0; i<fBlockDataArray.size(); i++) {
956 0 : HLTMessage(" %d: %s 0x%08x %p %d", i,
957 : AliHLTComponent::DataType2Text(fBlockDataArray[i].fDataType).c_str(),
958 : fBlockDataArray[i].fSpecification,
959 : fBlockDataArray[i].fPtr,
960 : fBlockDataArray[i].fSize
961 : );
962 : }
963 0 : HLTMessage("**** end of AliHLTTask Processing info *******");
964 0 : HLTMessage("**********************************************");
965 0 : return;
966 : }
967 :
968 0 : cout << "AliHLTTask " << GetName() << " " << this
969 0 : << " component " << fpComponent << " "
970 0 : << (fpComponent?fpComponent->GetComponentID():"")
971 0 : << endl;
972 0 : }
973 :
974 :
975 : int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
976 : {
977 : // default implementation nothing to do
978 0 : return 0;
979 : }
980 :
981 : int AliHLTTask::CustomCleanup()
982 : {
983 : // default implementation nothing to do
984 0 : return 0;
985 : }
986 :
987 : int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity,
988 : const char* originClass, const char* originFunc,
989 : const char* file, int line, ... ) const
990 : {
991 : // see header file for function documentation
992 : int iResult=0;
993 :
994 0 : va_list args;
995 0 : va_start(args, line);
996 :
997 0 : AliHLTLogging::SetLogString(this, " (%p)", "%s_pfmt_: ", GetName());
998 0 : iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
999 0 : va_end(args);
1000 :
1001 0 : return iResult;
1002 0 : }
|