]> rtime.felk.cvut.cz Git - ulut.git/blob - ulut/ul_htimer.h
Initialization of the first_changed field of timer queue added to make Valgrind happy.
[ulut.git] / ulut / ul_htimer.h
1 /*******************************************************************
2   uLan Utilities Library - C library of basic reusable constructions
3
4   ul_htimer.h  - hierarchical timer basic declarations
5
6   (C) Copyright 2003-2004 by Pavel Pisa - Originator
7
8   The uLan utilities library can be used, copied and modified under
9   next licenses
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.
19   
20   See files COPYING and README for details.
21
22  *******************************************************************/
23
24 #ifndef _UL_HTIMER_H
25 #define _UL_HTIMER_H
26
27 #include "ul_htimdefs.h"
28
29 #include "ul_list.h"
30 #ifndef UL_HTIMER_WITH_HPTREE
31  #include "ul_gavl.h"
32 #else /*UL_HTIMER_WITH_HPTREE*/
33  #include "ul_hptree.h"
34 #endif /*UL_HTIMER_WITH_HPTREE*/
35
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39
40 /**
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
44  *
45  * This is basic type useful to define more complete timer types
46  */
47 typedef struct ul_htim_node {
48  #ifndef UL_HTIMER_WITH_HPTREE
49   gavl_node_t    node;
50  #else /*UL_HTIMER_WITH_HPTREE*/
51   ul_hpt_node_t    node;
52  #endif /*UL_HTIMER_WITH_HPTREE*/
53   ul_htim_time_t expires;
54 } ul_htim_node_t;
55
56 /**
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
61  *
62  * This is basic type useful to define more complete timer queues types
63  */
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*/
70   int first_changed;
71 } ul_htim_queue_t;
72
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);
76
77 #ifndef UL_HTIMER_WITH_HPTREE
78 void ul_htim_queue_init_root_field(ul_htim_queue_t *queue);
79
80 static inline void 
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*/
85   ;
86 #endif /*UL_HTIMER_INC_FROM_BASE*/
87
88 static inline int
89 ul_htim_queue_inline_first(ul_htim_queue_t *queue, ul_htim_node_t **phtim)
90 {
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);
95   return 1;
96 }
97
98 #else /*UL_HTIMER_WITH_HPTREE*/
99 int ul_htim_queue_init_root_field(ul_htim_queue_t *queue);
100
101 static inline void 
102 ul_htim_queue_init_detached(ul_htim_node_t *htim)
103 #ifndef UL_HTIMER_INC_FROM_BASE
104   {;}
105 #else /*UL_HTIMER_INC_FROM_BASE*/
106   ;
107 #endif /*UL_HTIMER_INC_FROM_BASE*/
108
109 static inline int
110 ul_htim_queue_inline_first(ul_htim_queue_t *queue, ul_htim_node_t **phtim)
111 {
112   if(!queue->timers.count) return 0;
113   *phtim=UL_CONTAINEROF(queue->timers.heaparr[ul_hpt_first_i],ul_htim_node_t,node);
114   return *phtim!=0;
115 }
116 #endif /*UL_HTIMER_WITH_HPTREE*/
117
118 #define UL_HTIMER_DEC(cust_prefix, cust_queue_t, cust_timer_t, \
119                 cust_queue_field, cust_timer_field) \
120 \
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);\
124 static inline int \
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); \
127 } \
128 static inline int \
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); \
131 }\
132 static inline int \
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;\
137 }\
138 static inline void \
139 cust_prefix##_init_detached(cust_timer_t *timer){\
140   ul_htim_queue_init_detached(&timer->cust_timer_field);\
141 }\
142 static inline void \
143 cust_prefix##_set_expire(cust_timer_t *timer, ul_htim_time_t expire){\
144   timer->cust_timer_field.expires=expire;\
145 }\
146 static inline ul_htim_time_t \
147 cust_prefix##_get_expire(cust_timer_t *timer){\
148   return timer->cust_timer_field.expires;\
149 }
150
151 #define UL_HTIMER_IMP(cust_prefix, cust_queue_t, cust_timer_t, \
152                 cust_queue_field, cust_timer_field) \
153 \
154 void cust_prefix##_init_queue(cust_queue_t *queue)\
155 {\
156   ul_htim_queue_init_root_field(&queue->cust_queue_field);\
157   queue->cust_queue_field.first_changed=0;\
158 }\
159 cust_timer_t *cust_prefix##_cut_expired(cust_queue_t *queue, ul_htim_time_t *pact_time)\
160 { /*little faster equivalent to ul_htim_queue_first(&queue->cust_queue_field);*/\
161   ul_htim_node_t *htim_node;\
162   if(!ul_htim_queue_inline_first(&queue->cust_queue_field,&htim_node))\
163     return 0;\
164   if(ul_htimer_cmp_fnc(&htim_node->expires,pact_time)>0) return NULL;\
165   htim_node=ul_htim_queue_cut_first(&queue->cust_queue_field);\
166   return UL_CONTAINEROF(htim_node,cust_timer_t,cust_timer_field);\
167 }\
168 int cust_prefix##_next_expire(cust_queue_t *queue, ul_htim_time_t *pnext_time)\
169 {\
170   /*same as above, allows also new timers without "ul_gavlflesint.h" explicit inclussion */\
171   ul_htim_node_t *htim_node;\
172   if(!ul_htim_queue_inline_first(&queue->cust_queue_field,&htim_node))\
173     return 0;\
174   *pnext_time=htim_node->expires;\
175   return 1;\
176 }
177
178 /*===========================================================*/
179 /*  Standard timer (ul_htimer) */
180
181 #ifdef UL_HTIMER_WITH_STD_TYPE
182
183 /**
184  * struct ul_htimer - Standard timer entry with callback function
185  * @htim:     basic timer queue entry
186  * @function: user provided function to call at trigger time
187  * @data:     user selected data
188  *
189  * This is standard timer type, which requires @data casting
190  * in many cases. The type of @function field has to be declared
191  * in "ul_htimdefs.h" header file.
192  */
193 typedef struct ul_htimer {
194   ul_htim_node_t htim;
195   ul_htimer_fnc_t *function;
196   unsigned long data;
197   UL_HTIMER_USER_FIELDS
198 } ul_htimer_t;
199
200 /**
201  * struct ul_htimer_queue - Standard timer queue
202  * @htim_queue: the structure wraps &ul_htim_queue structure
203  *
204  * This is standard timer type, which requires @data casting
205  * in many cases
206  */
207 typedef struct ul_htimer_queue {
208   ul_htim_queue_t htim_queue;
209 } ul_htimer_queue_t;
210
211 UL_HTIMER_DEC(ul_htimer, ul_htimer_queue_t, ul_htimer_t, htim_queue, htim) 
212
213 void ul_htimer_run_expired(ul_htimer_queue_t *queue, ul_htim_time_t *pact_time);
214 /* there are next usefull functions 
215  * void ul_htimer_init_queue(ul_htimer_queue_t *queue);
216  * int ul_htimer_add(ul_htimer_queue_t *queue, ul_htimer_t *timer);
217  * int ul_htimer_detach(ul_htimer_queue_t *queue, ul_htimer_t *timer);
218  * int ul_htimer_first_changed(ul_htimer_queue_t *queue);
219  * int ul_htimer_next_expire(ul_htimer_queue_t *queue, ul_htimer_time_t *pnext_time);
220  * ul_htimer_t *ul_htimer_cut_expired(ul_htimer_queue_t *queue, ul_htimer_time_t *pact_time);
221  * void ul_htimer_init_detached(ul_htimer_t *timer);
222  * void ul_htimer_set_expire(ul_htimer_t *timer, ul_htimer_time_t expire);
223  * ul_htimer_time_t ul_htimer_get_expire(ul_htimer_t *timer);
224  */
225
226 #endif /*UL_HTIMER_WITH_STD_TYPE*/
227
228 #ifdef UL_HTIMER_WITH_MSTIME
229 #ifdef UL_HTIMER_WITH_STD_TYPE
230 ul_htimer_queue_t ul_root_htimer;
231 #endif /*UL_HTIMER_WITH_STD_TYPE*/
232 ul_mstime_t ul_mstime_last;
233 ul_mstime_t ul_mstime_next;
234
235 void ul_mstime_now(ul_mstime_t *mstm);
236 void ul_mstime_update(void);
237 void ul_mstime_init(void);
238 void ul_get_log_time_str(char str[30]);
239 void ul_compute_mstime_next(void);
240
241 #endif /*UL_HTIMER_WITH_MSTIME*/
242
243 #ifdef __cplusplus
244 } /* extern "C"*/
245 #endif
246
247 #endif /* _UL_HTIMER_H */