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