]>
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 | ||
48abe484 | 448 | int AliHLTTask::ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType) |
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; | |
466 | ||
7a436c89 | 467 | // subscribe to all source tasks |
457ec821 | 468 | fBlockDataArray.clear(); |
7a436c89 | 469 | while (lnk && iResult>=0) { |
470 | pSrcTask=(AliHLTTask*)lnk->GetObject(); | |
471 | if (pSrcTask) { | |
472 | int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this); | |
457ec821 | 473 | if (iMatchingDB<0) { |
474 | HLTError("task %s (%p): error getting no of matching data blocks from task %s (%p), error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iMatchingDB); | |
475 | iResult=iMatchingDB; | |
476 | break; | |
477 | } else if (iMatchingDB==0) { | |
478 | HLTDebug("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this); | |
7a436c89 | 479 | } |
457ec821 | 480 | if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) { |
481 | iSOR=iEOR=-1; | |
482 | AliHLTComponentBlockDataList::iterator block=fBlockDataArray.begin(); | |
483 | for (int i=0; block!=fBlockDataArray.end(); i++) { | |
484 | bool bRemove=0; | |
485 | bRemove|=(*block).fDataType==kAliHLTDataTypeSOR && !(iSOR<0 && (iSOR=i)>=0); | |
486 | bRemove|=(*block).fDataType==kAliHLTDataTypeEOR && !(iEOR<0 && (iEOR=i)>=0); | |
487 | //HLTInfo("block %d, iSOR=%d iEOR=%d remove=%d", i, iSOR, iEOR, bRemove); | |
488 | if (i<iSourceDataBlock) { | |
489 | assert(!bRemove); | |
490 | } else if (bRemove) { | |
491 | HLTDebug("remove duplicated event %s (%d)", AliHLTComponent::DataType2Text((*block).fDataType).c_str(), i); | |
492 | pSrcTask->Release(&(*block), this); | |
493 | block=fBlockDataArray.erase(block); | |
494 | continue; | |
495 | } else { | |
496 | iInputDataVolume+=(*block).fSize; | |
7a436c89 | 497 | // put the source task as many times into the list as it provides data blocks |
498 | // makes the bookkeeping for the data release easier | |
b46ca65e | 499 | subscribedTaskList.push_back(pSrcTask); |
457ec821 | 500 | } |
501 | block++; | |
7a436c89 | 502 | } |
503 | HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask); | |
457ec821 | 504 | iSourceDataBlock=fBlockDataArray.size(); |
7a436c89 | 505 | iResult=0; |
506 | } else { | |
507 | HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult); | |
508 | iResult=-EFAULT; | |
509 | } | |
510 | } else { | |
511 | HLTFatal("fatal internal error in ROOT list handling"); | |
512 | iResult=-EFAULT; | |
513 | } | |
514 | lnk=lnk->Next(); | |
457ec821 | 515 | } |
7a436c89 | 516 | |
517 | // process the event | |
518 | int iNofTrial=0; // repeat processing if component returns -ENOSPC | |
3ee8781a | 519 | AliHLTUInt32_t iLastOutputDataSize=0; |
7a436c89 | 520 | if (iResult>=0) { |
521 | do { | |
032c5e5e | 522 | long unsigned int iOutputDataSize=0; |
523 | AliHLTConfiguration* pConf=GetConf(); | |
032c5e5e | 524 | // check if there was a buffer size specified, query output size |
525 | // estimator from component otherwize | |
526 | if (pConf && pConf->GetOutputBufferSize()>=0) { | |
527 | iOutputDataSize=pConf->GetOutputBufferSize(); | |
528 | } else { | |
7a436c89 | 529 | long unsigned int iConstBase=0; |
530 | double fInputMultiplier=0; | |
53f79557 | 531 | if (pComponent->GetComponentType()!=AliHLTComponent::kSink) { |
7a436c89 | 532 | pComponent->GetOutputDataSize(iConstBase, fInputMultiplier); |
53f79557 | 533 | // add a small margin to the buffer to allow optional component |
534 | // statistics | |
535 | iConstBase+=100; | |
ae962989 | 536 | #if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS) |
537 | for (AliHLTComponentBlockDataList::iterator element=fBlockDataArray.begin(); | |
538 | element!=fBlockDataArray.end(); element++) { | |
539 | if (element->fDataType==kAliHLTDataTypeComponentStatistics) { | |
540 | iConstBase+=element->fSize; | |
541 | } | |
542 | } | |
543 | #endif | |
53f79557 | 544 | } |
7a436c89 | 545 | if (fInputMultiplier<0) { |
546 | HLTWarning("ignoring negative input multiplier"); | |
547 | fInputMultiplier=0; | |
548 | } | |
032c5e5e | 549 | iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase; |
7a436c89 | 550 | //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize); |
032c5e5e | 551 | } |
7a436c89 | 552 | if (iNofTrial>0) { |
553 | // dont process again if the buffer size is the same | |
3ee8781a | 554 | if (iLastOutputDataSize==iOutputDataSize) break; |
97d2b87a | 555 | HLTImportant("processing event %d again with buffer size %d", eventNo, iOutputDataSize); |
7a436c89 | 556 | } |
557 | AliHLTUInt8_t* pTgtBuffer=NULL; | |
558 | if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize); | |
559 | //HLTDebug("provided raw buffer %p", pTgtBuffer); | |
560 | AliHLTComponentEventData evtData; | |
561 | AliHLTComponent::FillEventData(evtData); | |
48abe484 | 562 | if (eventNo>=0) |
563 | evtData.fEventID=(AliHLTEventID_t)eventNo; | |
dd5b6088 | 564 | evtData.fEventCreation_s=static_cast<AliHLTUInt32_t>(time(NULL)); |
7a436c89 | 565 | AliHLTComponentTriggerData trigData; |
804007a6 | 566 | trigData.fStructSize=sizeof(trigData); |
567 | trigData.fDataSize=0; | |
568 | trigData.fData=NULL; | |
3ee8781a | 569 | iLastOutputDataSize=iOutputDataSize; |
570 | AliHLTUInt32_t size=iOutputDataSize; | |
7a436c89 | 571 | AliHLTUInt32_t outputBlockCnt=0; |
572 | AliHLTComponentBlockData* outputBlocks=NULL; | |
a0aeb701 | 573 | AliHLTComponentEventDoneData* edd=NULL; |
7a436c89 | 574 | if (pTgtBuffer!=NULL || iOutputDataSize==0) { |
48abe484 | 575 | // add event type data block |
7e81df35 | 576 | // the block is removed immediately after processing from the list |
48abe484 | 577 | AliHLTComponentBlockData eventTypeBlock; |
578 | AliHLTComponent::FillBlockData(eventTypeBlock); | |
579 | // Note: no payload! | |
580 | eventTypeBlock.fDataType=kAliHLTDataTypeEvent; | |
581 | eventTypeBlock.fSpecification=eventType; | |
582 | fBlockDataArray.push_back(eventTypeBlock); | |
583 | ||
584 | // process | |
585 | evtData.fBlockCnt=fBlockDataArray.size(); | |
7a436c89 | 586 | iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd); |
97d2b87a | 587 | HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt); |
48abe484 | 588 | |
324ca3b4 | 589 | // EventDoneData is for the moment ignored in AliHLTSystem |
590 | if (edd) { | |
591 | HLTDebug("got EventDoneData size %d", edd->fDataSize); | |
592 | delete [] reinterpret_cast<char*>(edd); | |
593 | edd=NULL; | |
594 | } | |
595 | ||
48abe484 | 596 | // remove event data block |
597 | fBlockDataArray.pop_back(); | |
598 | ||
7e81df35 | 599 | // check for forwarded blocks. |
600 | // loop over all output blocks and check | |
601 | // 1. for duplicate blocks (pointing to same location in output buffer | |
602 | // or to the same buffer) | |
603 | // 2. for blocks forwarded from the input. | |
b46ca65e | 604 | if (iResult>=0 && outputBlocks) { |
457ec821 | 605 | if (fListTargets.First()!=NULL) { |
606 | AliHLTComponentBlockDataList segments; | |
607 | for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) { | |
7e81df35 | 608 | // consistency check for data reference |
0ad4ebd1 | 609 | if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer && |
610 | outputBlocks[oblock].fOffset!=0) { | |
7e81df35 | 611 | HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: " |
612 | "for new blocks use offset only, forwarded blocks have fPtr set only", | |
613 | AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(), | |
614 | outputBlocks[oblock].fSpecification, | |
615 | outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset); | |
616 | } | |
617 | ||
618 | // check for duplicates in the output | |
619 | AliHLTUInt32_t checkblock=0; | |
620 | for (; checkblock<oblock; checkblock++) { | |
0ad4ebd1 | 621 | if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer && |
622 | outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) { | |
7e81df35 | 623 | if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize || |
624 | outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) { | |
625 | HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p " | |
626 | "but differ in data type and/or size: %d vs. %d", | |
627 | oblock, | |
628 | AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(), | |
629 | outputBlocks[oblock].fSpecification, | |
630 | checkblock, | |
631 | AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(), | |
632 | outputBlocks[checkblock].fSpecification, | |
633 | outputBlocks[oblock].fPtr, | |
634 | outputBlocks[oblock].fSize, | |
635 | outputBlocks[checkblock].fSize); | |
636 | } | |
637 | // ignore from the second copy | |
638 | break; | |
639 | } | |
640 | } | |
641 | if (checkblock<oblock) continue; | |
642 | ||
643 | // search for the forwarded data blocks | |
644 | // new data blocks are announced to the data buffer, forwarded data blocks | |
645 | // to the publisher task. The publisher task of a forwarded data block is | |
646 | // removed from the list in order to keep the buffer open. It will be releases | |
647 | // when the subscribing task releases it | |
457ec821 | 648 | AliHLTUInt32_t iblock=0; |
48abe484 | 649 | for (; iblock<fBlockDataArray.size(); iblock++) { |
0ad4ebd1 | 650 | if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) { |
651 | // the event type data block is ignored if it was forwarded | |
0925276e | 652 | break; |
0ad4ebd1 | 653 | } |
457ec821 | 654 | if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) { |
655 | assert(subscribedTaskList[iblock]!=NULL); | |
656 | if (subscribedTaskList[iblock]==NULL) continue; | |
657 | HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer); | |
658 | fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]); | |
659 | subscribedTaskList[iblock]=NULL; // not to be released in the loop further down | |
660 | break; | |
661 | } | |
662 | } | |
48abe484 | 663 | if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]); |
042b7a5d | 664 | } |
665 | if (pTgtBuffer && segments.size()>0) { | |
666 | iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size()); | |
b46ca65e | 667 | } |
457ec821 | 668 | } else { |
669 | // no forwarding, actually we dont even need to keep the data, this is a | |
670 | // dead end (fListTargets empty) | |
671 | //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt); | |
b46ca65e | 672 | } |
7a436c89 | 673 | delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0; |
674 | } else { | |
675 | fpDataBuffer->Reset(); | |
676 | } | |
457ec821 | 677 | if (fListTargets.First()!=NULL) { |
678 | if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) { | |
679 | HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer); | |
680 | fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]); | |
681 | subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down | |
682 | } | |
683 | if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) { | |
684 | 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); | |
685 | fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]); | |
686 | subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down | |
687 | } | |
688 | } | |
7a436c89 | 689 | } else { |
97d2b87a | 690 | HLTError("no target buffer available"); |
7a436c89 | 691 | iResult=-EFAULT; |
692 | } | |
693 | } while (iResult==-ENOSPC && iNofTrial++<1); | |
694 | } | |
695 | ||
696 | // now release all buffers which we have subscribed to | |
697 | iSourceDataBlock=0; | |
b46ca65e | 698 | AliHLTTaskPList::iterator element; |
699 | while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) { | |
700 | pSrcTask=*element; | |
7a436c89 | 701 | if (pSrcTask) { |
702 | int iTempRes=0; | |
703 | if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) { | |
97d2b87a | 704 | HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask); |
7a436c89 | 705 | } else { |
97d2b87a | 706 | HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes); |
7a436c89 | 707 | } |
7a436c89 | 708 | } |
b46ca65e | 709 | subscribedTaskList.erase(element); |
7a436c89 | 710 | iSourceDataBlock++; |
711 | } | |
b46ca65e | 712 | if (subscribedTaskList.size()>0) { |
97d2b87a | 713 | HLTError("could not release all data buffers"); |
7a436c89 | 714 | } |
715 | } else { | |
97d2b87a | 716 | HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer); |
7a436c89 | 717 | iResult=-EFAULT; |
718 | } | |
719 | return iResult; | |
720 | } | |
721 | ||
722 | int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const | |
723 | { | |
724 | // see header file for function documentation | |
725 | int iResult=0; | |
726 | if (pConsumerTask) { | |
727 | if (fpDataBuffer) { | |
728 | iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL); | |
729 | } else { | |
730 | HLTFatal("internal data buffer missing"); | |
731 | iResult=-EFAULT; | |
732 | } | |
733 | } else { | |
734 | iResult=-EINVAL; | |
735 | } | |
736 | return iResult; | |
737 | } | |
738 | ||
739 | int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const | |
740 | { | |
741 | // see header file for function documentation | |
742 | int iResult=0; | |
743 | if (pConsumerTask) { | |
744 | AliHLTComponent* pComponent=GetComponent(); | |
745 | if (!pComponent) { | |
746 | // init ? | |
747 | HLTError("component not initialized"); | |
748 | iResult=-EFAULT; | |
749 | } | |
750 | if (pComponent) { | |
751 | iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL); | |
752 | } else { | |
753 | HLTFatal("task initialization failed"); | |
754 | iResult=-EFAULT; | |
755 | } | |
756 | } else { | |
757 | iResult=-EINVAL; | |
758 | } | |
759 | return iResult; | |
760 | } | |
761 | ||
457ec821 | 762 | int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList) |
7a436c89 | 763 | { |
764 | // see header file for function documentation | |
765 | int iResult=0; | |
766 | if (pConsumerTask) { | |
767 | if (fpDataBuffer) { | |
457ec821 | 768 | iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList); |
7a436c89 | 769 | } else { |
770 | HLTFatal("internal data buffer missing"); | |
771 | iResult=-EFAULT; | |
772 | } | |
773 | } else { | |
774 | iResult=-EINVAL; | |
775 | } | |
776 | return iResult; | |
777 | } | |
778 | ||
779 | int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask) | |
780 | { | |
781 | // see header file for function documentation | |
782 | int iResult=0; | |
783 | if (pConsumerTask && pBlockDesc) { | |
784 | if (fpDataBuffer) { | |
b46ca65e | 785 | iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this); |
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 | void AliHLTTask::PrintStatus() | |
797 | { | |
798 | // see header file for function documentation | |
799 | HLTLogKeyword("task properties"); | |
800 | AliHLTComponent* pComponent=GetComponent(); | |
801 | if (pComponent) { | |
802 | HLTMessage(" component: %s (%p)", pComponent->GetComponentID(), pComponent); | |
803 | } else { | |
804 | HLTMessage(" no component set!"); | |
805 | } | |
806 | if (fpConfiguration) { | |
807 | AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource(); | |
808 | while (pSrc) { | |
809 | const char* pQualifier="unresolved"; | |
810 | if (FindDependency(pSrc->GetName())) | |
811 | pQualifier="resolved"; | |
812 | HLTMessage(" source: %s (%s)", pSrc->GetName(), pQualifier); | |
813 | pSrc=fpConfiguration->GetNextSource(); | |
814 | } | |
815 | TObjLink* lnk = fListTargets.FirstLink(); | |
816 | while (lnk) { | |
817 | TObject *obj = lnk->GetObject(); | |
818 | HLTMessage(" target: %s", obj->GetName()); | |
819 | lnk = lnk->Next(); | |
820 | } | |
821 | } else { | |
97d2b87a | 822 | HLTMessage(" task not initialized"); |
7a436c89 | 823 | } |
824 | } | |
7131ea63 | 825 | |
826 | int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/) | |
827 | { | |
828 | // default implementation nothing to do | |
829 | return 0; | |
830 | } | |
831 | ||
832 | int AliHLTTask::CustomCleanup() | |
833 | { | |
834 | // default implementation nothing to do | |
835 | return 0; | |
836 | } | |
97d2b87a | 837 | |
838 | int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity, | |
839 | const char* originClass, const char* originFunc, | |
840 | const char* file, int line, ... ) const | |
841 | { | |
842 | // see header file for function documentation | |
843 | int iResult=0; | |
844 | ||
845 | va_list args; | |
846 | va_start(args, line); | |
847 | ||
848 | AliHLTLogging::SetLogString("%s (%p): ", GetName(), this); | |
849 | iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/)); | |
850 | va_end(args); | |
851 | ||
852 | return iResult; | |
853 | } |