65b01bcd837af1fab5bcea126c7ec4e2cafc5c7f
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTTask.h
1 //-*- Mode: C++ -*-
2 // $Id$
3
4 #ifndef ALIHLTTASK_H
5 #define ALIHLTTASK_H
6 ///* This file is property of and copyright by the                          * 
7 ///* ALICE Experiment at CERN, All rights reserved.                         *
8 ///* See cxx source for full Copyright notice                               *
9
10 /// @file   AliHLTTask.h
11 /// @author Matthias Richter
12 /// @date   
13 /// @brief  base class for HLT tasks
14 ///
15
16 #include <vector>
17 #include <TObject.h>
18 #include <TList.h>
19 #include "AliHLTDataTypes.h"
20 #include "AliHLTLogging.h"
21 #include "AliHLTDataBuffer.h"
22
23 using std::vector;
24
25 struct AliHLTComponentBlockData;
26 class AliHLTComponent;
27 class AliHLTComponentHandler;
28 class AliHLTConfiguration;
29 class AliHLTTask;
30
31 typedef vector<AliHLTTask*> AliHLTTaskPList;
32
33 /******************************************************************************/
34
35 /**
36  * @class AliHLTTask
37  * A task collects all the information which is necessary to process a certain
38  * step in the HLT data processing chain.
39  * - the instance of the component
40  *   the task object creates and deletes the component object
41  * - the data buffer which receives the result of the component and provides
42  *   the data to other tasks/components
43  * - a list of all dependencies
44  * - a list of consumers
45  * - the task object holds an external pointer to the configuration object; 
46  *   \b Note: the configuration object must exist through the existence of the
47  *   task object!!!
48  *  
49  *
50  * @note This class is only used for the @ref alihlt_system.
51  *
52  * @ingroup alihlt_system
53  */
54 class AliHLTTask : public TObject, public AliHLTLogging {
55  public:
56   /** standard constructor */
57   AliHLTTask();
58   /** constructor 
59       @param pConf pointer to configuration descriptor
60    */
61   AliHLTTask(AliHLTConfiguration* pConf);
62   /** destructor */
63   virtual ~AliHLTTask();
64
65   /**
66    * Initialize the task.
67    * The task is initialized with a configuration descriptor. It needs a
68    * component handler instance to create the analysis component. The
69    * component is created and initialized.
70    * @param pConf pointer to configuration descriptor, can be NULL if it
71    *              was already provided to the constructor
72    * @param pCH   the HLT component handler
73    */
74   int Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH);
75
76   /**
77    * Create the component.
78    * @param pConf    configuration descritption
79    * @param pCH      component handler
80    * @param pComponent [OUT] target to get the component instance
81    * @return component instance
82    */
83   virtual int CreateComponent(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH, AliHLTComponent*& pComponent) const;
84
85   /**
86    * De-Initialize the task.
87    * Final cleanup after the run. The @ref AliHLTComponent::Deinit method of
88    * the component is called. The analysis component is deleted.
89    */
90   int Deinit();
91
92   /**
93    * Get the name of the object.
94    * This is an overridden TObject function in order to return the configuration
95    * name instead of the class name. Enables use of TList standard functions.
96    * @return name of the configuration
97    */
98   const char *GetName() const;
99
100   /**
101    * Return pointer to configuration.
102    * The tasks holds internally the configuration object.
103    * @return pointer to configuration
104    */
105   AliHLTConfiguration* GetConf() const;
106
107   /**
108    * Return pointer to component, which the task internally holds.
109    * <b>Never delete this object!!!</b>
110    * @return instance of the component
111    */
112   AliHLTComponent* GetComponent() const;
113
114   /**
115    * Find a dependency with a certain <i>name id</i>. 
116    * Searches in the list of dependencies for a task.
117    * @param id      the id of the <b>CONFIGURATION</b><br>
118    *                <b>NOTE:</b> the id does NOT specify a COMPONENT
119    * @return pointer to task
120    */
121   AliHLTTask* FindDependency(const char* id);
122
123   /**
124    * Add a dependency for the task.
125    * The task maintains a list of other tasks it depends on.
126    * @param   pDep  pointer to a task descriptor
127    * @return 0 if suceeded, neg error code if failed <br>
128    *    -EEXIST : the dependencie exists already
129    *
130    */
131   int SetDependency(AliHLTTask* pDep);
132
133   /**
134    * Clear a dependency.
135    * The ROOT TList touches the object which is in the list, even though
136    * it shouldn't care about. Thats why all lists have to be cleared before
137    * objects are deleted.
138    */
139   int UnsetDependency(AliHLTTask* pDep);
140
141   /**
142    * Return number of unresolved dependencies.
143    * Iterate through all the configurations the task depends on and check
144    * whether a corresponding task is available in the list.
145    * @return number of unresolved dependencies
146    */
147   int CheckDependencies();
148
149   /**
150    * Check whether the current task depends on the task pTask.
151    * @param pTask pointer to Task descriptor
152    * @return 1 the current task depends on pTask <br>
153    *         0 no dependency <br>
154    *         neg. error code if failed
155    */
156   int Depends(AliHLTTask* pTask);
157
158   /**
159    * Find a target with a certain id.
160    * Tasks which depend on the current task are referred to be <i>targets</i>. 
161    * @param id      configuration id to search for
162    * @return pointer to task instance
163    */
164   AliHLTTask* FindTarget(const char* id);
165
166   /**
167    * Insert task into target list.
168    * The target list specifies all the tasks which depend on the current task.
169    * @param pDep    pointer task object
170    * @return >=0 if succeeded, neg. error code if failed 
171    */
172   int SetTarget(AliHLTTask* pDep);
173
174   /**
175    * Clear a target.
176    * The ROOT TList touches the object which is in the list, even though
177    * it shouldn't care about. Thats why all lists have to be cleared before
178    * objects are deleted.
179    */
180   int UnsetTarget(AliHLTTask* pTarget);
181
182   /**
183    * Prepare the task for event processing.
184    * The method initializes the Data Buffer and calls the
185    * @ref AliHLTComponent::Init method of the component.<br>
186    * The @ref ProcessTask method can be called an arbitrary number of times
187    * as soon as the task is in <i>running</i> mode. 
188    */
189   int StartRun();
190
191   /**
192    * Clean-up the task after event processing.
193    * The method cleans up internal structures.
194    */
195   int EndRun();
196
197   /**
198    * Process the task.
199    * If all dependencies are resolved the tasks subscribes to the data of 
200    * all source tasks, builds the block descriptor and calls the
201    * @ref AliHLTComponent::ProcessEvent method of the component, after
202    * processing, the data blocks are released. <br>
203    * The @ref StartRun method must be called before.
204    */
205   int ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType,
206                   AliHLTUInt64_t trgMask, AliHLTUInt32_t timestamp,
207                   AliHLTUInt32_t participatingDetectors = 0);
208
209   /**
210    * Determine the number of matching data block between the component and the
211    * data buffer of a consumer component. It checks which data types from the
212    * list of input data types of the consumer component can be provided by data
213    * blocks of the current component.
214    * @param pConsumerTask   the task which subscribes to the data
215    * @return number of matching data blocks
216    */
217   int GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const;
218
219   /**
220    * Determine the number of matching data types between the component and a
221    * consumer component. It checks which data types from the list of input data
222    * types of the consumer component can be provided by the current component.
223    * @param pConsumerTask   the task which subscribes to the data
224    * @return number of matching data types
225    */
226   int GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const;
227
228   /**
229    * Subscribe to the data of a source task.
230    * The function prepares the block descriptors for subsequent use with the
231    * @ref AliHLTComponent::ProcessEvent method, the method prepares all block
232    * descriptors which match the input data type of the consumer the function
233    * returns the number of blocks which would be prepared in case the target
234    * array is big enough.
235    * @param pConsumerTask   the task which subscribes to the data
236    * @param blockDescList   block descriptor list to be filled
237    * @return number of matching data blocks, negative error code if failed
238    */
239   int Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList);
240
241   /**
242    * Release a block descriptor.
243    * Notification from consumer task.  
244    * @param pBlockDesc      descriptor of the data segment
245    * @param pConsumerTask   the task which subscribed to the data
246    * @return: >0 if success, negative error code if failed
247    */
248   int Release(AliHLTComponentBlockData* pBlockDesc,
249               const AliHLTTask* pConsumerTask);
250
251   /**
252    * Cleanup function if the event processing is in error state.
253    * In order to handle in particular forwarded segments in the source
254    * tasks correctly the tasks of the chain have to subscribe to the
255    * parents even if the event is already in error state. This function
256    * is used instead of ProcessTask.
257    * Subscribes to all source tasks and releases them with out any event
258    * processing
259    */
260   int SubscribeSourcesAndSkip();
261
262   /**
263    * Print the status of the task with component, dependencies and targets.
264    */
265   void PrintStatus();
266
267   /**
268    * Overloaded from TObject
269    */
270   void Print(const char* options) const;
271
272   /**
273    * Search task dependency list recursively to find a dependency.
274    * @param id              id of the task to search for
275    * @param pTgtList        (optional) target list to receive dependency tree
276    * @return 0 if not found, >0 found in the n-th level, 
277              dependency list in the target list  
278    */
279   int FollowDependency(const char* id, TList* pTgtList=NULL);
280
281   /**
282    * Print the tree for a certain dependency either from the task or
283    * configuration list.
284    * Each task posseses two "link lists": The configurations are the origin
285    * of the  task list. In case of an error during the built of the task list,
286    * the dependencies for the task list might be incomplete. In this case the
287    * configurations can give infomation on the error reason.  
288    * @param id              id of the dependency to search for
289    * @param bMode           0 (default) from task dependency list, <br> 
290    *                        1 from configuration list
291    */
292   void PrintDependencyTree(const char* id, int bMode=0);
293
294   /**
295    * Get number of source tasks.
296    * @return number of source tasks
297    */
298   int GetNofSources() const {return fListDependencies.GetSize();}
299
300   /**
301    * Customized logging function.
302    * The task id and pointer is added at the beginning of each message.
303    */
304   int LoggingVarargs(AliHLTComponentLogSeverity severity, 
305                      const char* originClass, const char* originFunc,
306                      const char* file, int line, ... ) const;
307
308  private:
309   /** prohibited copy constructor */
310   AliHLTTask(const AliHLTTask&);
311   /** prohibited assignment operator */
312   AliHLTTask& operator=(const AliHLTTask&);
313
314   /**
315    * Custom initialization for child tasks.
316    */
317   virtual int CustomInit(AliHLTComponentHandler* pCH);
318
319   /**
320    * Custom clean up for child tasks.
321    */
322   virtual int CustomCleanup();
323
324  protected:
325   /** the configuration descriptor (external pointer) */
326   AliHLTConfiguration* fpConfiguration;                           //! transient
327   /** the component described by this task (created and deleted internally) */
328   AliHLTComponent* fpComponent;                                   //! transient
329   /** the data buffer for the component processing */
330   AliHLTDataBuffer* fpDataBuffer;                                 //! transient
331
332  private:
333   /** the list of targets (tasks which depend upon the current one) */
334   TList fListTargets;                                             // see above
335   /** the list of sources (tasks upon which the current one depends) */ 
336   TList fListDependencies;                                        // see above
337
338   /**
339    * block data array to be passed as argument to the 
340    * @ref AliHLTComponent::ProcessEvent method. 
341    * Filled through subscription to source tasks (@ref Subscribe).
342    */
343   vector<AliHLTComponentBlockData> fBlockDataArray;               //! transient
344
345   ClassDef(AliHLTTask, 0);
346 };
347
348 #endif