1 /*******************************************************************
2 uLan Utilities Library - C library of basic reusable constructions
4 ul_htimer.h - hierarchical timer basic declarations
6 (C) Copyright 2003-2004 by Pavel Pisa - Originator
8 The uLan utilities library can be used, copied and modified under
10 - GPL - GNU General Public License
11 - LGPL - GNU Lesser General Public License
12 - MPL - Mozilla Public License
13 - and other licenses added by project originators
14 Code can be modified and re-distributed under any combination
15 of the above listed licenses. If contributor does not agree with
16 some of the licenses, he/she can delete appropriate line.
17 Warning, if you delete all lines, you are not allowed to
18 distribute source code and/or binaries utilizing code.
20 See files COPYING and README for details.
22 *******************************************************************/
27 #include "ul_htimdefs.h"
30 #ifndef UL_HTIMER_WITH_HPTREE
32 #else /*UL_HTIMER_WITH_HPTREE*/
33 #include "ul_hptree.h"
34 #endif /*UL_HTIMER_WITH_HPTREE*/
41 * struct ul_htim_node - Timer queue entry base structure
42 * @node: regular GAVL node structure for insertion into
43 * @expires: time to trigger timer in &ul_htim_time_t type defined resolution
45 * This is basic type useful to define more complete timer types
47 typedef struct ul_htim_node {
48 #ifndef UL_HTIMER_WITH_HPTREE
50 #else /*UL_HTIMER_WITH_HPTREE*/
52 #endif /*UL_HTIMER_WITH_HPTREE*/
53 ul_htim_time_t expires;
57 * struct ul_htim_queue - Timer queue head/root base structure
58 * @timers: root of FLES GAVL tree of timer entries
59 * @first_changed: flag, which is set after each add, detach operation
60 * which concerning of firsts scheduled timer
62 * This is basic type useful to define more complete timer queues types
64 typedef struct ul_htim_queue {
65 #ifndef UL_HTIMER_WITH_HPTREE
66 gavl_fles_int_root_field_t timers;
67 #else /*UL_HTIMER_WITH_HPTREE*/
68 ul_hpt_root_field_t timers;
69 #endif /*UL_HTIMER_WITH_HPTREE*/
73 int ul_htim_queue_insert(ul_htim_queue_t *queue, ul_htim_node_t *htim);
74 int ul_htim_queue_delete(ul_htim_queue_t *queue, ul_htim_node_t *htim);
75 ul_htim_node_t *ul_htim_queue_cut_first(ul_htim_queue_t *queue);
77 #ifndef UL_HTIMER_WITH_HPTREE
78 void ul_htim_queue_init_root_field(ul_htim_queue_t *queue);
81 ul_htim_queue_init_detached(ul_htim_node_t *htim)
82 #ifndef UL_HTIMER_INC_FROM_BASE
83 {htim->node.parent=NULL;}
84 #else /*UL_HTIMER_INC_FROM_BASE*/
86 #endif /*UL_HTIMER_INC_FROM_BASE*/
89 ul_htim_queue_inline_first(ul_htim_queue_t *queue, ul_htim_node_t **phtim)
91 /*little faster equivalent to ul_htim_queue_first(&queue->cust_queue_field);*/
92 gavl_node_t *gavl_node=queue->timers.first;
93 if(!gavl_node) return 0;
94 *phtim=UL_CONTAINEROF(gavl_node,ul_htim_node_t,node);
98 #else /*UL_HTIMER_WITH_HPTREE*/
99 int ul_htim_queue_init_root_field(ul_htim_queue_t *queue);
102 ul_htim_queue_init_detached(ul_htim_node_t *htim)
103 #ifndef UL_HTIMER_INC_FROM_BASE
105 #else /*UL_HTIMER_INC_FROM_BASE*/
107 #endif /*UL_HTIMER_INC_FROM_BASE*/
110 ul_htim_queue_inline_first(ul_htim_queue_t *queue, ul_htim_node_t **phtim)
112 if(!queue->timers.count) return 0;
113 *phtim=UL_CONTAINEROF(queue->timers.heaparr[ul_hpt_first_i],ul_htim_node_t,node);
116 #endif /*UL_HTIMER_WITH_HPTREE*/
118 #define UL_HTIMER_DEC(cust_prefix, cust_queue_t, cust_timer_t, \
119 cust_queue_field, cust_timer_field) \
121 void cust_prefix##_init_queue(cust_queue_t *queue);\
122 cust_timer_t *cust_prefix##_cut_expired(cust_queue_t *queue, ul_htim_time_t *act_time);\
123 int cust_prefix##_next_expire(cust_queue_t *queue, ul_htim_time_t *act_time);\
125 cust_prefix##_add(cust_queue_t *queue, cust_timer_t *timer){ \
126 return ul_htim_queue_insert(&queue->cust_queue_field, &timer->cust_timer_field); \
129 cust_prefix##_detach(cust_queue_t *queue, cust_timer_t *timer){ \
130 return ul_htim_queue_delete(&queue->cust_queue_field, &timer->cust_timer_field); \
133 cust_prefix##_first_changed(cust_queue_t *queue){\
134 int first_changed=queue->cust_queue_field.first_changed;\
135 queue->cust_queue_field.first_changed=0;\
136 return first_changed;\
139 cust_prefix##_init_detached(cust_timer_t *timer){\
140 ul_htim_queue_init_detached(&timer->cust_timer_field);\
143 cust_prefix##_set_expire(cust_timer_t *timer, ul_htim_time_t expire){\
144 timer->cust_timer_field.expires=expire;\
146 static inline ul_htim_time_t \
147 cust_prefix##_get_expire(cust_timer_t *timer){\
148 return timer->cust_timer_field.expires;\
151 #define UL_HTIMER_IMP(cust_prefix, cust_queue_t, cust_timer_t, \
152 cust_queue_field, cust_timer_field) \
154 void cust_prefix##_init_queue(cust_queue_t *queue)\
156 ul_htim_queue_init_root_field(&queue->cust_queue_field);\
158 cust_timer_t *cust_prefix##_cut_expired(cust_queue_t *queue, ul_htim_time_t *pact_time)\
159 { /*little faster equivalent to ul_htim_queue_first(&queue->cust_queue_field);*/\
160 ul_htim_node_t *htim_node;\
161 if(!ul_htim_queue_inline_first(&queue->cust_queue_field,&htim_node))\
163 if(ul_htimer_cmp_fnc(&htim_node->expires,pact_time)>0) return NULL;\
164 htim_node=ul_htim_queue_cut_first(&queue->cust_queue_field);\
165 return UL_CONTAINEROF(htim_node,cust_timer_t,cust_timer_field);\
167 int cust_prefix##_next_expire(cust_queue_t *queue, ul_htim_time_t *pnext_time)\
169 /*same as above, allows also new timers without "ul_gavlflesint.h" explicit inclussion */\
170 ul_htim_node_t *htim_node;\
171 if(!ul_htim_queue_inline_first(&queue->cust_queue_field,&htim_node))\
173 *pnext_time=htim_node->expires;\
177 /*===========================================================*/
178 /* Standard timer (ul_htimer) */
180 #ifdef UL_HTIMER_WITH_STD_TYPE
183 * struct ul_htimer - Standard timer entry with callback function
184 * @htim: basic timer queue entry
185 * @function: user provided function to call at trigger time
186 * @data: user selected data
188 * This is standard timer type, which requires @data casting
189 * in many cases. The type of @function field has to be declared
190 * in "ul_htimdefs.h" header file.
192 typedef struct ul_htimer {
194 ul_htimer_fnc_t *function;
196 UL_HTIMER_USER_FIELDS
200 * struct ul_htimer_queue - Standard timer queue
201 * @htim_queue: the structure wraps &ul_htim_queue structure
203 * This is standard timer type, which requires @data casting
206 typedef struct ul_htimer_queue {
207 ul_htim_queue_t htim_queue;
210 UL_HTIMER_DEC(ul_htimer, ul_htimer_queue_t, ul_htimer_t, htim_queue, htim)
212 void ul_htimer_run_expired(ul_htimer_queue_t *queue, ul_htim_time_t *pact_time);
213 /* there are next usefull functions
214 * void ul_htimer_init_queue(ul_htimer_queue_t *queue);
215 * int ul_htimer_add(ul_htimer_queue_t *queue, ul_htimer_t *timer);
216 * int ul_htimer_detach(ul_htimer_queue_t *queue, ul_htimer_t *timer);
217 * int ul_htimer_first_changed(ul_htimer_queue_t *queue);
218 * int ul_htimer_next_expire(ul_htimer_queue_t *queue, ul_htimer_time_t *pnext_time);
219 * ul_htimer_t *ul_htimer_cut_expired(ul_htimer_queue_t *queue, ul_htimer_time_t *pact_time);
220 * void ul_htimer_init_detached(ul_htimer_t *timer);
221 * void ul_htimer_set_expire(ul_htimer_t *timer, ul_htimer_time_t expire);
222 * ul_htimer_time_t ul_htimer_get_expire(ul_htimer_t *timer);
225 #endif /*UL_HTIMER_WITH_STD_TYPE*/
227 #ifdef UL_HTIMER_WITH_MSTIME
228 #ifdef UL_HTIMER_WITH_STD_TYPE
229 ul_htimer_queue_t ul_root_htimer;
230 #endif /*UL_HTIMER_WITH_STD_TYPE*/
231 ul_mstime_t ul_mstime_last;
232 ul_mstime_t ul_mstime_next;
234 void ul_mstime_now(ul_mstime_t *mstm);
235 void ul_mstime_update(void);
236 void ul_mstime_init(void);
237 void ul_get_log_time_str(char str[30]);
238 void ul_compute_mstime_next(void);
240 #endif /*UL_HTIMER_WITH_MSTIME*/
246 #endif /* _UL_HTIMER_H */