]> rtime.felk.cvut.cz Git - orte.git/blob - orte/include/ul_htimer.h
Added prerelease of ORTE-0.2 (Real Time Publisher Subscriber communication protocol...
[orte.git] / orte / include / ul_htimer.h
1 #ifndef _UL_HTIMER_H
2 #define _UL_HTIMER_H
3
4 #include "ul_htimdefs.h"
5
6 #include "ul_list.h"
7 #ifndef UL_HTIMER_WITH_HPTREE
8  #include "ul_gavl.h"
9 #else /*UL_HTIMER_WITH_HPTREE*/
10  #include "ul_hptree.h"
11 #endif /*UL_HTIMER_WITH_HPTREE*/
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 /**
18  * struct ul_htim_node - Timer queue entry base structure
19  * @node:    regular GAVL node structure for insertion into 
20  * @expires: time to trigger timer in &ul_htim_time_t type defined resolution
21  *
22  * This is basic type useful to define more complete timer types
23  */
24 typedef struct ul_htim_node {
25  #ifndef UL_HTIMER_WITH_HPTREE
26   gavl_node_t    node;
27  #else /*UL_HTIMER_WITH_HPTREE*/
28   ul_hpt_node_t    node;
29  #endif /*UL_HTIMER_WITH_HPTREE*/
30   ul_htim_time_t expires;
31 } ul_htim_node_t;
32
33 /**
34  * struct ul_htim_queue - Timer queue head/root base structure
35  * @timers:  root of FLES GAVL tree of timer entries 
36  * @first_changed: flag, which is set after each add, detach operation
37  *                 which concerning of firsts scheduled timer
38  *
39  * This is basic type useful to define more complete timer queues types
40  */
41 typedef struct ul_htim_queue {
42  #ifndef UL_HTIMER_WITH_HPTREE
43   gavl_fles_int_root_field_t timers;
44  #else /*UL_HTIMER_WITH_HPTREE*/
45   ul_hpt_root_field_t timers;
46  #endif /*UL_HTIMER_WITH_HPTREE*/
47   int first_changed;
48 } ul_htim_queue_t;
49
50 int ul_htim_queue_insert(ul_htim_queue_t *queue, ul_htim_node_t *htim);
51 int ul_htim_queue_delete(ul_htim_queue_t *queue, ul_htim_node_t *htim);
52 ul_htim_node_t *ul_htim_queue_cut_first(ul_htim_queue_t *queue);
53
54 #ifndef UL_HTIMER_WITH_HPTREE
55 void ul_htim_queue_init_root_field(ul_htim_queue_t *queue);
56
57 static inline void 
58 ul_htim_queue_init_detached(ul_htim_node_t *htim)
59   {htim->node.parent=NULL;}
60
61 static inline int
62 ul_htim_queue_inline_first(ul_htim_queue_t *queue, ul_htim_node_t **phtim)
63 {
64   /*little faster equivalent to ul_htim_queue_first(&queue->cust_queue_field);*/
65   gavl_node_t *gavl_node=queue->timers.first;
66   if(!gavl_node) return 0;
67   *phtim=UL_CONTAINEROF(gavl_node,ul_htim_node_t,node);
68   return 1;
69 }
70
71 #else /*UL_HTIMER_WITH_HPTREE*/
72 int ul_htim_queue_init_root_field(ul_htim_queue_t *queue);
73
74 static inline void 
75 ul_htim_queue_init_detached(ul_htim_node_t *htim)
76   {;}
77
78 static inline int
79 ul_htim_queue_inline_first(ul_htim_queue_t *queue, ul_htim_node_t **phtim)
80 {
81   if(!queue->timers.count) return 0;
82   *phtim=UL_CONTAINEROF(queue->timers.heaparr[ul_hpt_first_i],ul_htim_node_t,node);
83   return *phtim!=0;
84 }
85 #endif /*UL_HTIMER_WITH_HPTREE*/
86
87 #define UL_HTIMER_DEC(cust_prefix, cust_queue_t, cust_timer_t, \
88                 cust_queue_field, cust_timer_field) \
89 \
90 void cust_prefix##_init_queue(cust_queue_t *queue);\
91 cust_timer_t *cust_prefix##_cut_expired(cust_queue_t *queue, ul_htim_time_t *act_time);\
92 int cust_prefix##_next_expire(cust_queue_t *queue, ul_htim_time_t *act_time);\
93 static inline int \
94 cust_prefix##_add(cust_queue_t *queue, cust_timer_t *timer){ \
95   return ul_htim_queue_insert(&queue->cust_queue_field, &timer->cust_timer_field); \
96 } \
97 static inline int \
98 cust_prefix##_detach(cust_queue_t *queue, cust_timer_t *timer){ \
99   return ul_htim_queue_delete(&queue->cust_queue_field, &timer->cust_timer_field); \
100 }\
101 static inline int \
102 cust_prefix##_first_changed(cust_queue_t *queue){\
103   int first_changed=queue->cust_queue_field.first_changed;\
104   queue->cust_queue_field.first_changed=0;\
105   return first_changed;\
106 }\
107 static inline void \
108 cust_prefix##_init_detached(cust_timer_t *timer){\
109   ul_htim_queue_init_detached(&timer->cust_timer_field);\
110 }\
111 static inline void \
112 cust_prefix##_set_expire(cust_timer_t *timer, ul_htim_time_t expire){\
113   timer->cust_timer_field.expires=expire;\
114 }\
115 static inline ul_htim_time_t \
116 cust_prefix##_get_expire(cust_timer_t *timer){\
117   return timer->cust_timer_field.expires;\
118 }
119
120 #define UL_HTIMER_IMP(cust_prefix, cust_queue_t, cust_timer_t, \
121                 cust_queue_field, cust_timer_field) \
122 \
123 void cust_prefix##_init_queue(cust_queue_t *queue)\
124 {\
125   ul_htim_queue_init_root_field(&queue->cust_queue_field);\
126 }\
127 cust_timer_t *cust_prefix##_cut_expired(cust_queue_t *queue, ul_htim_time_t *pact_time)\
128 { /*little faster equivalent to ul_htim_queue_first(&queue->cust_queue_field);*/\
129   ul_htim_node_t *htim_node;\
130   if(!ul_htim_queue_inline_first(&queue->cust_queue_field,&htim_node))\
131     return 0;\
132   if(ul_htimer_cmp_fnc(&htim_node->expires,pact_time)>0) return NULL;\
133   htim_node=ul_htim_queue_cut_first(&queue->cust_queue_field);\
134   return UL_CONTAINEROF(htim_node,cust_timer_t,cust_timer_field);\
135 }\
136 int cust_prefix##_next_expire(cust_queue_t *queue, ul_htim_time_t *pnext_time)\
137 {\
138   /*same as above, allows also new timers without "ul_gavlflesint.h" explicit inclussion */\
139   ul_htim_node_t *htim_node;\
140   if(!ul_htim_queue_inline_first(&queue->cust_queue_field,&htim_node))\
141     return 0;\
142   *pnext_time=htim_node->expires;\
143   return 1;\
144 }
145
146 /*===========================================================*/
147 /*  Standard timer (ul_htimer) */
148
149 #ifdef UL_HTIMER_WITH_STD_TYPE
150
151 /**
152  * struct ul_htimer - Standard timer entry with callback function
153  * @htim:     basic timer queue entry
154  * @function: user provided function to call at trigger time
155  * @data:     user selected data
156  *
157  * This is standard timer type, which requires @data casting
158  * in many cases. The type of @function field has to be declared
159  * in "ul_htimdefs.h" header file.
160  */
161 typedef struct ul_htimer {
162   ul_htim_node_t htim;
163   ul_htimer_fnc_t *function;
164   unsigned long data;
165   UL_HTIMER_USER_FIELDS
166 } ul_htimer_t;
167
168 /**
169  * struct ul_htimer_queue - Standard timer queue
170  * @htim:     basic timer queue head
171  * @function: user provided function to call at trigger time
172  * @data:     user selected data
173  *
174  * This is standard timer type, wghich requires @data casting
175  * in many cases
176  */
177 typedef struct ul_htimer_queue {
178   ul_htim_queue_t htim_queue;
179 } ul_htimer_queue_t;
180
181 UL_HTIMER_DEC(ul_htimer, ul_htimer_queue_t, ul_htimer_t, htim_queue, htim) 
182
183 void ul_htimer_run_expired(ul_htimer_queue_t *queue, ul_htim_time_t *pact_time);
184 /* there are next usefull functions 
185  * void ul_htimer_init_queue(ul_htimer_queue_t *queue);
186  * int ul_htimer_add(ul_htimer_queue_t *queue, ul_htimer_t *timer);
187  * int ul_htimer_detach(ul_htimer_queue_t *queue, ul_htimer_t *timer);
188  * int ul_htimer_first_changed(ul_htimer_queue_t *queue);
189  * int ul_htimer_next_expire(ul_htimer_queue_t *queue, ul_htimer_time_t *pnext_time);
190  * ul_htimer_t *ul_htimer_cut_expired(ul_htimer_queue_t *queue, ul_htimer_time_t *pact_time);
191  * void ul_htimer_init_detached(ul_htimer_t *timer);
192  * void ul_htimer_set_expire(ul_htimer_t *timer, ul_htimer_time_t expire);
193  * ul_htimer_time_t ul_htimer_get_expire(ul_htimer_t *timer);
194  */
195
196 #endif /*UL_HTIMER_WITH_STD_TYPE*/
197
198 #ifdef UL_HTIMER_WITH_MSTIME
199 #ifdef UL_HTIMER_WITH_STD_TYPE
200 ul_htimer_queue_t ul_root_htimer;
201 #endif /*UL_HTIMER_WITH_STD_TYPE*/
202 ul_mstime_t ul_mstime_last;
203 ul_mstime_t ul_mstime_next;
204
205 void ul_mstime_update(void);
206 void ul_mstime_init(void);
207 void ul_get_log_time_str(char str[30]);
208 void ul_compute_mstime_next(void);
209
210 #endif /*UL_HTIMER_WITH_MSTIME*/
211
212 #ifdef __cplusplus
213 } /* extern "C"*/
214 #endif
215
216 #endif /* _UL_HTIMER_H */