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
58BEGIN_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*/
93typedef 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*/
137typedef 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*/
184typedef 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*/
232void 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*/
257cl_status_t
258cl_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*/
282cl_status_t
283cl_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*/
312void 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*/
338void 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*/
364cl_status_t
365cl_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*/
405void
406cl_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*/
437uint32_t
438cl_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
456END_C_DECLS
457#endif				/* !defined(_CL_EVENT_WHEEL_H_) */
458