1 /*
2  * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  */
35 
36 /*
37  * Abstract:
38  *	Declaration of event wheel abstraction.
39  */
40 
41 #ifndef _CL_EVENT_WHEEL_H_
42 #define _CL_EVENT_WHEEL_H_
43 
44 #include <complib/cl_atomic.h>
45 #include <complib/cl_qlist.h>
46 #include <complib/cl_qmap.h>
47 #include <complib/cl_timer.h>
48 #include <complib/cl_spinlock.h>
49 
50 #ifdef __cplusplus
51 #  define BEGIN_C_DECLS extern "C" {
52 #  define END_C_DECLS   }
53 #else				/* !__cplusplus */
54 #  define BEGIN_C_DECLS
55 #  define END_C_DECLS
56 #endif				/* __cplusplus */
57 
58 BEGIN_C_DECLS
59 /****h* Component Library/Event_Wheel
60 * NAME
61 *	Event_Wheel
62 *
63 * DESCRIPTION
64 *	The Event_Wheel provides a facility for registering delayed events
65 *  and getting called once they timeout.
66 *
67 *	The Event_Wheel functions operate on a cl_event_wheel_t structure
68 *  which should be treated as opaque and should be manipulated
69 *  only through the provided functions.
70 *
71 * SEE ALSO
72 *	Structures:
73 *		cl_event_wheel_t
74 *
75 *	Initialization/Destruction:
76 *		cl_event_wheel_construct, cl_event_wheel_init, cl_event_wheel_destroy
77 *
78 *	Manipulation:
79 *		cl_event_wheel_reg, cl_event_wheel_unreg
80 *
81 *********/
82 /****f* Component Library: Event_Wheel/cl_pfn_event_aged_cb_t
83 * NAME
84 *	cl_pfn_event_aged_cb_t
85 *
86 * DESCRIPTION
87 *	This typedef defines the prototype for client functions invoked
88 *  by the Event_Wheel.  The Event_Wheel calls the corresponding
89 *  client function when the specific item has aged.
90 *
91 * SYNOPSIS
92 */
93 typedef uint64_t
94     (*cl_pfn_event_aged_cb_t) (IN uint64_t key,
95 			       IN uint32_t num_regs, IN void *context);
96 /*
97 * PARAMETERS
98 *	key
99 *		[in] The key used for registering the item in the call to
100 *		cl_event_wheel_reg.
101 *
102 *	num_regs
103 *		[in] The number of times this event was registered (pushed in time).
104 *
105 *	context
106 *		[in] Client specific context specified in a call to
107 *		cl_event_wheel_reg
108 *
109 * RETURN VALUE
110 *	This function returns the abosolute time the event should fire in [usec].
111 *  If lower then current time means the event should be unregistered
112 *  immediatly.
113 *
114 * NOTES
115 *	This typedef provides a function prototype reference for
116 *  the function provided by Event_Wheel clients as a parameter
117 *  to the cl_event_wheel_reg function.
118 *
119 * SEE ALSO
120 *	Event_Wheel, cl_event_wheel_reg
121 *********/
122 
123 /****s* Component Library: Event_Wheel/cl_event_wheel_t
124 * NAME
125 *	cl_event_wheel_t
126 *
127 * DESCRIPTION
128 *	Event_Wheel structure.
129 *
130 *	The Event_Wheel is thread safe.
131 *
132 *	The cl_event_wheel_t structure should be treated as opaque and should
133 *  be manipulated only through the provided functions.
134 *
135 * SYNOPSIS
136 */
137 typedef struct _cl_event_wheel {
138 	cl_spinlock_t lock;
139 	cl_spinlock_t *p_external_lock;
140 
141 	cl_qmap_t events_map;
142 	boolean_t closing;
143 	cl_qlist_t events_wheel;
144 	cl_timer_t timer;
145 } cl_event_wheel_t;
146 /*
147 * FIELDS
148 *	lock
149 *		Spinlock to guard internal structures.
150 *
151 *	p_external_lock
152 *		Reference to external spinlock to guard internal structures
153 *		if the event wheel is part of a larger object protected by its own lock
154 *
155 *	events_map
156 *		A Map holding all registered event items by their key.
157 *
158 *	closing
159 *		A flag indicating the event wheel is closing. This means that
160 *		callbacks that are called when closing == TRUE should just be ignored.
161 *
162 *	events_wheel
163 *		A list of the events sorted by expiration time.
164 *
165 *	timer
166 *		The timer scheduling event time propagation.
167 *
168 * SEE ALSO
169 *	Event_Wheel
170 *********/
171 
172 /****s* Component Library: Event_Wheel/cl_event_wheel_reg_info_t
173 * NAME
174 *	cl_event_wheel_reg_info_t
175 *
176 * DESCRIPTION
177 *	Defines the event_wheel registration object structure.
178 *
179 *	The cl_event_wheel_reg_info_t structure is for internal use by the
180 *	Event_Wheel only.
181 *
182 * SYNOPSIS
183 */
184 typedef struct _cl_event_wheel_reg_info {
185 	cl_map_item_t map_item;
186 	cl_list_item_t list_item;
187 	uint64_t key;
188 	cl_pfn_event_aged_cb_t pfn_aged_callback;
189 	uint64_t aging_time;
190 	uint32_t num_regs;
191 	void *context;
192 	cl_event_wheel_t *p_event_wheel;
193 } cl_event_wheel_reg_info_t;
194 /*
195 * FIELDS
196 *	map_item
197 *		The map item of this event
198 *
199 *	list_item
200 *		The sorted by aging time list item
201 *
202 *	key
203 *		The key by which one can find the event
204 *
205 *	pfn_aged_callback
206 *		The clients Event-Aged callback
207 *
208 *	aging_time
209 *		The delta time [msec] for which the event should age.
210 *
211 *	num_regs
212 *		The number of times the same event (key) was registered
213 *
214 *	context
215 *		Client's context for event-aged callback.
216 *
217 *	p_event_wheel
218 *		Pointer to this event wheel object
219 *
220 * SEE ALSO
221 *********/
222 
223 /****f* Component Library: Event_Wheel/cl_event_wheel_construct
224 * NAME
225 *	cl_event_wheel_construct
226 *
227 * DESCRIPTION
228 *	This function constructs a Event_Wheel object.
229 *
230 * SYNOPSIS
231 */
232 void cl_event_wheel_construct(IN cl_event_wheel_t * const p_event_wheel);
233 /*
234 * PARAMETERS
235 *	p_event_wheel
236 *		[in] Pointer to a Event_Wheel.
237 *
238 * RETURN VALUE
239 *	This function does not return a value.
240 *
241 * NOTES
242 *	Allows calling cl_event_wheel_init and cl_event_wheel_destroy.
243 *
244 * SEE ALSO
245 *	Event_Wheel, cl_event_wheel_init, cl_event_wheel_destroy
246 *********/
247 
248 /****f* Component Library: Event_Wheel/cl_event_wheel_init
249 * NAME
250 *	cl_event_wheel_init
251 *
252 * DESCRIPTION
253 *	This function initializes a Event_Wheel object.
254 *
255 * SYNOPSIS
256 */
257 cl_status_t
258 cl_event_wheel_init(IN cl_event_wheel_t * const p_event_wheel);
259 
260 /*
261 * PARAMETERS
262 *	p_event_wheel
263 *		[in] Pointer to a Event_Wheel.
264 *
265 * RETURN VALUE
266 *	CL_SUCCESS if the operation is successful.
267 *
268 * SEE ALSO
269 *	Event_Wheel, cl_event_wheel_destoy, cl_event_wheel_reg, cl_event_wheel_unreg
270 *
271 *********/
272 
273 /****f* Component Library: Event_Wheel/cl_event_wheel_init
274 * NAME
275 *	cl_event_wheel_init
276 *
277 * DESCRIPTION
278 *	This function initializes a Event_Wheel object.
279 *
280 * SYNOPSIS
281 */
282 cl_status_t
283 cl_event_wheel_init_ex(IN cl_event_wheel_t * const p_event_wheel,
284 		       IN cl_spinlock_t * p_external_lock);
285 
286 /*
287 * PARAMETERS
288 *	p_event_wheel
289 *		[in] Pointer to a Event_Wheel.
290 *
291 *	p_external_lock
292 *		[in] Reference to external spinlock to guard internal structures
293 *		if the event wheel is part of a larger object protected by its own lock
294 *
295 * RETURN VALUE
296 *	CL_SUCCESS if the operation is successful.
297 *
298 * SEE ALSO
299 *	Event_Wheel, cl_event_wheel_destoy, cl_event_wheel_reg, cl_event_wheel_unreg
300 *
301 *********/
302 
303 /****f* Component Library: Event_Wheel/cl_event_wheel_destroy
304 * NAME
305 *	cl_event_wheel_destroy
306 *
307 * DESCRIPTION
308 *	This function destroys a Event_Wheel object.
309 *
310 * SYNOPSIS
311 */
312 void cl_event_wheel_destroy(IN cl_event_wheel_t * const p_event_wheel);
313 /*
314 * PARAMETERS
315 *	p_event_wheel
316 *		[in] Pointer to a Event_Wheel.
317 *
318 * RETURN VALUE
319 *	This function does not return a value.
320 *
321 * NOTES
322 *	This function does not returns until all client callback functions
323 *  been successfully finished.
324 *
325 * SEE ALSO
326 *	Event_Wheel, cl_event_wheel_construct, cl_event_wheel_init
327 *********/
328 
329 /****f* Component Library: Event_Wheel/cl_event_wheel_dump
330 * NAME
331 *	cl_event_wheel_dump
332 *
333 * DESCRIPTION
334 *	This function dumps the details of an Event_Whell object.
335 *
336 * SYNOPSIS
337 */
338 void cl_event_wheel_dump(IN cl_event_wheel_t * const p_event_wheel);
339 /*
340 * PARAMETERS
341 *	p_event_wheel
342 *		[in] Pointer to a Event_Wheel.
343 *
344 * RETURN VALUE
345 *	This function does not return a value.
346 *
347 * NOTES
348 *	Note that this function should be called inside a lock of the event wheel!
349 *  It doesn't aquire the lock by itself.
350 *
351 * SEE ALSO
352 *	Event_Wheel, cl_event_wheel_construct, cl_event_wheel_init
353 *********/
354 
355 /****f* Component Library: Event_Wheel/cl_event_wheel_reg
356 * NAME
357 *	cl_event_wheel_reg
358 *
359 * DESCRIPTION
360 *	This function registers a client with a Event_Wheel object.
361 *
362 * SYNOPSIS
363 */
364 cl_status_t
365 cl_event_wheel_reg(IN cl_event_wheel_t * const p_event_wheel,
366 		   IN const uint64_t key,
367 		   IN const uint64_t aging_time_usec,
368 		   IN cl_pfn_event_aged_cb_t pfn_callback,
369 		   IN void *const context);
370 /*
371 * PARAMETERS
372 *	p_event_wheel
373 *		[in] Pointer to a Event_Wheel.
374 *
375 *	key
376 *		[in] The specifc Key by which events are registered.
377 *
378 *	aging_time_usec
379 *		[in] The absolute time this event should age in usec
380 *
381 *	pfn_callback
382 *		[in] Event Aging callback.  The Event_Wheel calls this
383 *		function after the time the event has registed for has come.
384 *
385 *	context
386 *		[in] Client context value passed to the cl_pfn_event_aged_cb_t
387 *		function.
388 *
389 * RETURN VALUE
390 *	On success a Event_Wheel CL_SUCCESS or CL_ERROR otherwise.
391 *
392 * SEE ALSO
393 *	Event_Wheel, cl_event_wheel_unreg
394 *********/
395 
396 /****f* Component Library: Event_Wheel/cl_event_wheel_unreg
397 * NAME
398 *	cl_event_wheel_unreg
399 *
400 * DESCRIPTION
401 *	This function unregisters a client event from a Event_Wheel.
402 *
403 * SYNOPSIS
404 */
405 void
406 cl_event_wheel_unreg(IN cl_event_wheel_t * const p_event_wheel,
407 		     IN uint64_t key);
408 /*
409 * PARAMETERS
410 *	p_event_wheel
411 *		[in] Pointer to a Event_Wheel.
412 *
413 *	key
414 *		[in] The key used for registering the event
415 *
416 * RETURN VALUE
417 *	This function does not return a value.
418 *
419 * NOTES
420 *	After the event has aged it is automatically removed from
421 *  the event wheel. So it should only be invoked when the need arises
422 *  to remove existing events before they age.
423 *
424 * SEE ALSO
425 *	Event_Wheel, cl_event_wheel_reg
426 *********/
427 
428 /****f* Component Library: Event_Wheel/cl_event_wheel_num_regs
429 * NAME
430 *	cl_event_wheel_num_regs
431 *
432 * DESCRIPTION
433 *	This function returns the number of times an event was registered.
434 *
435 * SYNOPSIS
436 */
437 uint32_t
438 cl_event_wheel_num_regs(IN cl_event_wheel_t * const p_event_wheel,
439 			IN uint64_t key);
440 /*
441 * PARAMETERS
442 *	p_event_wheel
443 *		[in] Pointer to a Event_Wheel.
444 *
445 *	key
446 *		[in] The key used for registering the event
447 *
448 * RETURN VALUE
449 *	The number of times the event was registered.
450 *  0 if never registered or eventually aged.
451 *
452 * SEE ALSO
453 *	Event_Wheel, cl_event_wheel_reg, cl_event_wheel_unreg
454 *********/
455 
456 END_C_DECLS
457 #endif				/* !defined(_CL_EVENT_WHEEL_H_) */
458