1219820Sjeff/*
2219820Sjeff * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
3219820Sjeff * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5219820Sjeff *
6219820Sjeff * This software is available to you under a choice of one of two
7219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
8219820Sjeff * General Public License (GPL) Version 2, available from the file
9219820Sjeff * COPYING in the main directory of this source tree, or the
10219820Sjeff * OpenIB.org BSD license below:
11219820Sjeff *
12219820Sjeff *     Redistribution and use in source and binary forms, with or
13219820Sjeff *     without modification, are permitted provided that the following
14219820Sjeff *     conditions are met:
15219820Sjeff *
16219820Sjeff *      - Redistributions of source code must retain the above
17219820Sjeff *        copyright notice, this list of conditions and the following
18219820Sjeff *        disclaimer.
19219820Sjeff *
20219820Sjeff *      - Redistributions in binary form must reproduce the above
21219820Sjeff *        copyright notice, this list of conditions and the following
22219820Sjeff *        disclaimer in the documentation and/or other materials
23219820Sjeff *        provided with the distribution.
24219820Sjeff *
25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32219820Sjeff * SOFTWARE.
33219820Sjeff *
34219820Sjeff */
35219820Sjeff
36219820Sjeff/*
37219820Sjeff * Abstract:
38219820Sjeff * 	Declaration of event wheel abstraction.
39219820Sjeff */
40219820Sjeff
41219820Sjeff#ifndef _CL_EVENT_WHEEL_H_
42219820Sjeff#define _CL_EVENT_WHEEL_H_
43219820Sjeff
44219820Sjeff#include <complib/cl_atomic.h>
45219820Sjeff#include <complib/cl_qlist.h>
46219820Sjeff#include <complib/cl_qmap.h>
47219820Sjeff#include <complib/cl_timer.h>
48219820Sjeff#include <complib/cl_spinlock.h>
49219820Sjeff
50219820Sjeff#ifdef __cplusplus
51219820Sjeff#  define BEGIN_C_DECLS extern "C" {
52219820Sjeff#  define END_C_DECLS   }
53219820Sjeff#else				/* !__cplusplus */
54219820Sjeff#  define BEGIN_C_DECLS
55219820Sjeff#  define END_C_DECLS
56219820Sjeff#endif				/* __cplusplus */
57219820Sjeff
58219820SjeffBEGIN_C_DECLS
59219820Sjeff/****h* Component Library/Event_Wheel
60219820Sjeff* NAME
61219820Sjeff*	Event_Wheel
62219820Sjeff*
63219820Sjeff* DESCRIPTION
64219820Sjeff*	The Event_Wheel provides a facility for registering delayed events
65219820Sjeff*	and getting called once they timeout.
66219820Sjeff*
67219820Sjeff*	The Event_Wheel functions operate on a cl_event_wheel_t structure
68219820Sjeff*	which should be treated as opaque and should be manipulated
69219820Sjeff*	only through the provided functions.
70219820Sjeff*
71219820Sjeff* SEE ALSO
72219820Sjeff*	Structures:
73219820Sjeff*		cl_event_wheel_t
74219820Sjeff*
75219820Sjeff*	Initialization/Destruction:
76219820Sjeff*		cl_event_wheel_construct, cl_event_wheel_init, cl_event_wheel_destroy
77219820Sjeff*
78219820Sjeff*	Manipulation:
79219820Sjeff*		cl_event_wheel_reg, cl_event_wheel_unreg
80219820Sjeff*
81219820Sjeff*********/
82219820Sjeff/****f* Component Library: Event_Wheel/cl_pfn_event_aged_cb_t
83219820Sjeff* NAME
84219820Sjeff*	cl_pfn_event_aged_cb_t
85219820Sjeff*
86219820Sjeff* DESCRIPTION
87219820Sjeff*	This typedef defines the prototype for client functions invoked
88219820Sjeff*	by the Event_Wheel.  The Event_Wheel calls the corresponding
89219820Sjeff*	client function when the specific item has aged.
90219820Sjeff*
91219820Sjeff* SYNOPSIS
92219820Sjeff*/
93219820Sjefftypedef uint64_t
94219820Sjeff    (*cl_pfn_event_aged_cb_t) (IN uint64_t key,
95219820Sjeff			       IN uint32_t num_regs, IN void *context);
96219820Sjeff/*
97219820Sjeff* PARAMETERS
98219820Sjeff*  key
99219820Sjeff*     [in] The key used for registering the item in the call to
100219820Sjeff*     cl_event_wheel_reg
101219820Sjeff*
102219820Sjeff*  num_regs
103219820Sjeff*     [in] The number of times this event was registered (pushed in time).
104219820Sjeff*
105219820Sjeff*	context
106219820Sjeff*		[in] Client specific context specified in a call to
107219820Sjeff*		cl_event_wheel_reg
108219820Sjeff*
109219820Sjeff* RETURN VALUE
110219820Sjeff*	This function returns the abosolute time the event should fire in [usec].
111219820Sjeff*  If lower then current time means the event should be unregistered
112219820Sjeff*  immediatly.
113219820Sjeff*
114219820Sjeff* NOTES
115219820Sjeff*	This typedef provides a function prototype reference for
116219820Sjeff*	the function provided by Event_Wheel clients as a parameter
117219820Sjeff*	to the cl_event_wheel_reg function.
118219820Sjeff*
119219820Sjeff* SEE ALSO
120219820Sjeff*	Event_Wheel, cl_event_wheel_reg
121219820Sjeff*********/
122219820Sjeff
123219820Sjeff/****s* Component Library: Event_Wheel/cl_event_wheel_t
124219820Sjeff* NAME
125219820Sjeff*	cl_event_wheel_t
126219820Sjeff*
127219820Sjeff* DESCRIPTION
128219820Sjeff*	Event_Wheel structure.
129219820Sjeff*
130219820Sjeff*	The Event_Wheel is thread safe.
131219820Sjeff*
132219820Sjeff*	The cl_event_wheel_t structure should be treated as opaque and should
133219820Sjeff*	be manipulated only through the provided functions.
134219820Sjeff*
135219820Sjeff* SYNOPSIS
136219820Sjeff*/
137219820Sjefftypedef struct _cl_event_wheel {
138219820Sjeff	cl_spinlock_t lock;
139219820Sjeff	cl_spinlock_t *p_external_lock;
140219820Sjeff
141219820Sjeff	cl_qmap_t events_map;
142219820Sjeff	boolean_t closing;
143219820Sjeff	cl_qlist_t events_wheel;
144219820Sjeff	cl_timer_t timer;
145219820Sjeff} cl_event_wheel_t;
146219820Sjeff/*
147219820Sjeff* FIELDS
148219820Sjeff*	lock
149219820Sjeff*		Spinlock to guard internal structures.
150219820Sjeff*
151219820Sjeff*       p_external_lock
152219820Sjeff*               Reference to external spinlock to guard internal structures
153219820Sjeff*               if the event wheel is part of a larger object protected by its own lock
154219820Sjeff*
155219820Sjeff*	events_map
156219820Sjeff*		A Map holding all registered event items by their key.
157219820Sjeff*
158219820Sjeff*  closing
159219820Sjeff*     A flag indicating the event wheel is closing. This means that
160219820Sjeff*     callbacks that are called when closing == TRUE should just be ignored.
161219820Sjeff*
162219820Sjeff*	events_wheel
163219820Sjeff*		A list of the events sorted by expiration time.
164219820Sjeff*
165219820Sjeff*	timer
166219820Sjeff*		The timer scheduling event time propagation.
167219820Sjeff*
168219820Sjeff* SEE ALSO
169219820Sjeff*	Event_Wheel
170219820Sjeff*********/
171219820Sjeff
172219820Sjeff/****s* Component Library: Event_Wheel/cl_event_wheel_reg_info_t
173219820Sjeff* NAME
174219820Sjeff*	cl_event_wheel_reg_info_t
175219820Sjeff*
176219820Sjeff* DESCRIPTION
177219820Sjeff*	Defines the event_wheel registration object structure.
178219820Sjeff*
179219820Sjeff*	The cl_event_wheel_reg_info_t structure is for internal use by the
180219820Sjeff*	Event_Wheel only.
181219820Sjeff*
182219820Sjeff* SYNOPSIS
183219820Sjeff*/
184219820Sjefftypedef struct _cl_event_wheel_reg_info {
185219820Sjeff	cl_map_item_t map_item;
186219820Sjeff	cl_list_item_t list_item;
187219820Sjeff	uint64_t key;
188219820Sjeff	cl_pfn_event_aged_cb_t pfn_aged_callback;
189219820Sjeff	uint64_t aging_time;
190219820Sjeff	uint32_t num_regs;
191219820Sjeff	void *context;
192219820Sjeff	cl_event_wheel_t *p_event_wheel;
193219820Sjeff} cl_event_wheel_reg_info_t;
194219820Sjeff/*
195219820Sjeff* FIELDS
196219820Sjeff*  map_item
197219820Sjeff*     The map item of this event
198219820Sjeff*
199219820Sjeff*  list_item
200219820Sjeff*     The sorted by aging time list item
201219820Sjeff*
202219820Sjeff*  key
203219820Sjeff*     The key by which one can find the event
204219820Sjeff*
205219820Sjeff*	pfn_aged_callback
206219820Sjeff*		The clients Event-Aged callback
207219820Sjeff*
208219820Sjeff*  aging_time
209219820Sjeff*     The delta time [msec] for which the event should age.
210219820Sjeff*
211219820Sjeff*  num_regs
212219820Sjeff*     The number of times the same event (key) was registered
213219820Sjeff*
214219820Sjeff*	context
215219820Sjeff*		Client's context for event-aged callback.
216219820Sjeff*
217219820Sjeff*	p_event_wheel
218219820Sjeff*		Pointer to this event wheel object
219219820Sjeff*
220219820Sjeff* SEE ALSO
221219820Sjeff*********/
222219820Sjeff
223219820Sjeff/****f* Component Library: Event_Wheel/cl_event_wheel_construct
224219820Sjeff* NAME
225219820Sjeff*	cl_event_wheel_construct
226219820Sjeff*
227219820Sjeff* DESCRIPTION
228219820Sjeff*	This function constructs a Event_Wheel object.
229219820Sjeff*
230219820Sjeff* SYNOPSIS
231219820Sjeff*/
232219820Sjeffvoid cl_event_wheel_construct(IN cl_event_wheel_t * const p_event_wheel);
233219820Sjeff/*
234219820Sjeff* PARAMETERS
235219820Sjeff*	p_event_wheel
236219820Sjeff*		[in] Pointer to a Event_Wheel.
237219820Sjeff*
238219820Sjeff* RETURN VALUE
239219820Sjeff*	This function does not return a value.
240219820Sjeff*
241219820Sjeff* NOTES
242219820Sjeff*	Allows calling cl_event_wheel_init and cl_event_wheel_destroy.
243219820Sjeff*
244219820Sjeff* SEE ALSO
245219820Sjeff*	Event_Wheel, cl_event_wheel_init, cl_event_wheel_destroy
246219820Sjeff*********/
247219820Sjeff
248219820Sjeff/****f* Component Library: Event_Wheel/cl_event_wheel_init
249219820Sjeff* NAME
250219820Sjeff*	cl_event_wheel_init
251219820Sjeff*
252219820Sjeff* DESCRIPTION
253219820Sjeff*	This function initializes a Event_Wheel object.
254219820Sjeff*
255219820Sjeff* SYNOPSIS
256219820Sjeff*/
257219820Sjeffcl_status_t
258219820Sjeffcl_event_wheel_init(IN cl_event_wheel_t * const p_event_wheel);
259219820Sjeff
260219820Sjeff/*
261219820Sjeff* PARAMETERS
262219820Sjeff*	p_event_wheel
263219820Sjeff*		[in] Pointer to a Event_Wheel.
264219820Sjeff*
265219820Sjeff* RETURN VALUE
266219820Sjeff*	CL_SUCCESS if the operation is successful.
267219820Sjeff*
268219820Sjeff* SEE ALSO
269219820Sjeff*	Event_Wheel, cl_event_wheel_destoy, cl_event_wheel_reg, cl_event_wheel_unreg
270219820Sjeff*
271219820Sjeff*********/
272219820Sjeff
273219820Sjeff/****f* Component Library: Event_Wheel/cl_event_wheel_init
274219820Sjeff* NAME
275219820Sjeff*	cl_event_wheel_init
276219820Sjeff*
277219820Sjeff* DESCRIPTION
278219820Sjeff*	This function initializes a Event_Wheel object.
279219820Sjeff*
280219820Sjeff* SYNOPSIS
281219820Sjeff*/
282219820Sjeffcl_status_t
283219820Sjeffcl_event_wheel_init_ex(IN cl_event_wheel_t * const p_event_wheel,
284219820Sjeff		       IN cl_spinlock_t * p_external_lock);
285219820Sjeff
286219820Sjeff/*
287219820Sjeff* PARAMETERS
288219820Sjeff*  p_event_wheel
289219820Sjeff*     [in] Pointer to a Event_Wheel.
290219820Sjeff*
291219820Sjeff*  p_external_lock
292219820Sjeff*     [in] Reference to external spinlock to guard internal structures
293219820Sjeff*          if the event wheel is part of a larger object protected by its own lock
294219820Sjeff*
295219820Sjeff* RETURN VALUE
296219820Sjeff*	CL_SUCCESS if the operation is successful.
297219820Sjeff*
298219820Sjeff* SEE ALSO
299219820Sjeff*	Event_Wheel, cl_event_wheel_destoy, cl_event_wheel_reg, cl_event_wheel_unreg
300219820Sjeff*
301219820Sjeff*********/
302219820Sjeff
303219820Sjeff/****f* Component Library: Event_Wheel/cl_event_wheel_destroy
304219820Sjeff* NAME
305219820Sjeff*	cl_event_wheel_destroy
306219820Sjeff*
307219820Sjeff* DESCRIPTION
308219820Sjeff*	This function destroys a Event_Wheel object.
309219820Sjeff*
310219820Sjeff* SYNOPSIS
311219820Sjeff*/
312219820Sjeffvoid cl_event_wheel_destroy(IN cl_event_wheel_t * const p_event_wheel);
313219820Sjeff/*
314219820Sjeff* PARAMETERS
315219820Sjeff*	p_event_wheel
316219820Sjeff*		[in] Pointer to a Event_Wheel.
317219820Sjeff*
318219820Sjeff* RETURN VALUE
319219820Sjeff*	This function does not return a value.
320219820Sjeff*
321219820Sjeff* NOTES
322219820Sjeff*	This function does not returns until all client callback functions
323219820Sjeff*  been successfully finished.
324219820Sjeff*
325219820Sjeff* SEE ALSO
326219820Sjeff*	Event_Wheel, cl_event_wheel_construct, cl_event_wheel_init
327219820Sjeff*********/
328219820Sjeff
329219820Sjeff/****f* Component Library: Event_Wheel/cl_event_wheel_dump
330219820Sjeff* NAME
331219820Sjeff*	cl_event_wheel_dump
332219820Sjeff*
333219820Sjeff* DESCRIPTION
334219820Sjeff*	This function dumps the details of an Event_Whell object.
335219820Sjeff*
336219820Sjeff* SYNOPSIS
337219820Sjeff*/
338219820Sjeffvoid cl_event_wheel_dump(IN cl_event_wheel_t * const p_event_wheel);
339219820Sjeff/*
340219820Sjeff* PARAMETERS
341219820Sjeff*	p_event_wheel
342219820Sjeff*		[in] Pointer to a Event_Wheel.
343219820Sjeff*
344219820Sjeff* RETURN VALUE
345219820Sjeff*	This function does not return a value.
346219820Sjeff*
347219820Sjeff* NOTES
348219820Sjeff*	Note that this function should be called inside a lock of the event wheel!
349219820Sjeff*  It doesn't aquire the lock by itself.
350219820Sjeff*
351219820Sjeff* SEE ALSO
352219820Sjeff*	Event_Wheel, cl_event_wheel_construct, cl_event_wheel_init
353219820Sjeff*********/
354219820Sjeff
355219820Sjeff/****f* Component Library: Event_Wheel/cl_event_wheel_reg
356219820Sjeff* NAME
357219820Sjeff*	cl_event_wheel_reg
358219820Sjeff*
359219820Sjeff* DESCRIPTION
360219820Sjeff*	This function registers a client with a Event_Wheel object.
361219820Sjeff*
362219820Sjeff* SYNOPSIS
363219820Sjeff*/
364219820Sjeffcl_status_t
365219820Sjeffcl_event_wheel_reg(IN cl_event_wheel_t * const p_event_wheel,
366219820Sjeff		   IN const uint64_t key,
367219820Sjeff		   IN const uint64_t aging_time_usec,
368219820Sjeff		   IN cl_pfn_event_aged_cb_t pfn_callback,
369219820Sjeff		   IN void *const context);
370219820Sjeff/*
371219820Sjeff* PARAMETERS
372219820Sjeff*	p_event_wheel
373219820Sjeff*		[in] Pointer to a Event_Wheel.
374219820Sjeff*
375219820Sjeff*	key
376219820Sjeff*		[in] The specifc Key by which events are registered.
377219820Sjeff*
378219820Sjeff*  aging_time_usec
379219820Sjeff*     [in] The absolute time this event should age in usec
380219820Sjeff*
381219820Sjeff*	pfn_callback
382219820Sjeff*		[in] Event Aging callback.  The Event_Wheel calls this
383219820Sjeff*		function after the time the event has registed for has come.
384219820Sjeff*
385219820Sjeff*	context
386219820Sjeff*		[in] Client context value passed to the cl_pfn_event_aged_cb_t
387219820Sjeff*		function.
388219820Sjeff*
389219820Sjeff* RETURN VALUE
390219820Sjeff*	On success a Event_Wheel CL_SUCCESS or CL_ERROR otherwise.
391219820Sjeff*
392219820Sjeff* SEE ALSO
393219820Sjeff*	Event_Wheel, cl_event_wheel_unreg
394219820Sjeff*********/
395219820Sjeff
396219820Sjeff/****f* Component Library: Event_Wheel/cl_event_wheel_unreg
397219820Sjeff* NAME
398219820Sjeff*	cl_event_wheel_unreg
399219820Sjeff*
400219820Sjeff* DESCRIPTION
401219820Sjeff*	This function unregisters a client event from a Event_Wheel.
402219820Sjeff*
403219820Sjeff* SYNOPSIS
404219820Sjeff*/
405219820Sjeffvoid
406219820Sjeffcl_event_wheel_unreg(IN cl_event_wheel_t * const p_event_wheel,
407219820Sjeff		     IN uint64_t key);
408219820Sjeff/*
409219820Sjeff* PARAMETERS
410219820Sjeff*	p_event_wheel
411219820Sjeff*		[in] Pointer to a Event_Wheel.
412219820Sjeff*
413219820Sjeff*	key
414219820Sjeff*		[in] The key used for registering the event
415219820Sjeff*
416219820Sjeff* RETURN VALUE
417219820Sjeff*	This function does not return a value.
418219820Sjeff*
419219820Sjeff* NOTES
420219820Sjeff*  After the event has aged it is automatically removed from
421219820Sjeff*  the event wheel. So it should only be invoked when the need arises
422219820Sjeff*  to remove existing events before they age.
423219820Sjeff*
424219820Sjeff* SEE ALSO
425219820Sjeff*	Event_Wheel, cl_event_wheel_reg
426219820Sjeff*********/
427219820Sjeff
428219820Sjeff/****f* Component Library: Event_Wheel/cl_event_wheel_num_regs
429219820Sjeff* NAME
430219820Sjeff*	cl_event_wheel_num_regs
431219820Sjeff*
432219820Sjeff* DESCRIPTION
433219820Sjeff*	This function returns the number of times an event was registered.
434219820Sjeff*
435219820Sjeff* SYNOPSIS
436219820Sjeff*/
437219820Sjeffuint32_t
438219820Sjeffcl_event_wheel_num_regs(IN cl_event_wheel_t * const p_event_wheel,
439219820Sjeff			IN uint64_t key);
440219820Sjeff/*
441219820Sjeff* PARAMETERS
442219820Sjeff*	p_event_wheel
443219820Sjeff*		[in] Pointer to a Event_Wheel.
444219820Sjeff*
445219820Sjeff*	key
446219820Sjeff*		[in] The key used for registering the event
447219820Sjeff*
448219820Sjeff* RETURN VALUE
449219820Sjeff*	The number of times the event was registered.
450219820Sjeff*  0 if never registered or eventually aged.
451219820Sjeff*
452219820Sjeff* SEE ALSO
453219820Sjeff*	Event_Wheel, cl_event_wheel_reg, cl_event_wheel_unreg
454219820Sjeff*********/
455219820Sjeff
456219820SjeffEND_C_DECLS
457219820Sjeff#endif				/* !defined(_CL_EVENT_WHEEL_H_) */
458