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