]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/management/opensm/include/complib/cl_dispatcher.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ofed / management / opensm / include / complib / cl_dispatcher.h
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 dispatcher abstraction.
39  */
40
41 #ifndef _CL_DISPATCHER_H_
42 #define _CL_DISPATCHER_H_
43
44 #include <complib/cl_atomic.h>
45 #include <complib/cl_threadpool.h>
46 #include <complib/cl_qlist.h>
47 #include <complib/cl_qpool.h>
48 #include <complib/cl_spinlock.h>
49 #include <complib/cl_ptr_vector.h>
50
51 #ifdef __cplusplus
52 #  define BEGIN_C_DECLS extern "C" {
53 #  define END_C_DECLS   }
54 #else                           /* !__cplusplus */
55 #  define BEGIN_C_DECLS
56 #  define END_C_DECLS
57 #endif                          /* __cplusplus */
58
59 BEGIN_C_DECLS
60 /****h* Component Library/Dispatcher
61 * NAME
62 *       Dispatcher
63 *
64 * DESCRIPTION
65 *       The Dispatcher provides a facility for message routing to
66 *       asynchronous worker threads.
67 *
68 *       The Dispatcher functions operate on a cl_dispatcher_t structure
69 *       which should be treated as opaque and should be manipulated
70 *       only through the provided functions.
71 *
72 * SEE ALSO
73 *       Structures:
74 *               cl_dispatcher_t
75 *
76 *       Initialization/Destruction:
77 *               cl_disp_construct, cl_disp_init, cl_disp_shutdown, cl_disp_destroy
78 *
79 *       Manipulation:
80 *               cl_disp_post, cl_disp_reset, cl_disp_wait_on
81 *********/
82 /****s* Component Library: Dispatcher/cl_disp_msgid_t
83 * NAME
84 *       cl_disp_msgid_t
85 *
86 * DESCRIPTION
87 *       Defines the type of dispatcher messages.
88 *
89 * SYNOPSIS
90 */
91 typedef uint32_t cl_disp_msgid_t;
92 /**********/
93
94 /****s* Component Library: Dispatcher/CL_DISP_MSGID_NONE
95 * NAME
96 *       CL_DISP_MSGID_NONE
97 *
98 * DESCRIPTION
99 *       Defines a message value that means "no message".
100 *       This value is used during registration by Dispatcher clients
101 *       that do not wish to receive messages.
102 *
103 *       No Dispatcher message is allowed to have this value.
104 *
105 * SYNOPSIS
106 */
107 #define CL_DISP_MSGID_NONE      0xFFFFFFFF
108 /**********/
109
110 /****s* Component Library: Dispatcher/CL_DISP_INVALID_HANDLE
111 * NAME
112 *       CL_DISP_INVALID_HANDLE
113 *
114 * DESCRIPTION
115 *       Defines the value of an invalid Dispatcher registration handle.
116 *
117 * SYNOPSIS
118 */
119 #define CL_DISP_INVALID_HANDLE ((cl_disp_reg_handle_t)0)
120 /*********/
121
122 /****f* Component Library: Dispatcher/cl_pfn_msgrcv_cb_t
123 * NAME
124 *       cl_pfn_msgrcv_cb_t
125 *
126 * DESCRIPTION
127 *       This typedef defines the prototype for client functions invoked
128 *       by the Dispatcher.  The Dispatcher calls the corresponding
129 *       client function when delivering a message to the client.
130 *
131 *       The client function must be reentrant if the user creates a
132 *       Dispatcher with more than one worker thread.
133 *
134 * SYNOPSIS
135 */
136 typedef void
137  (*cl_pfn_msgrcv_cb_t) (IN void *context, IN void *p_data);
138 /*
139 * PARAMETERS
140 *       context
141 *               [in] Client specific context specified in a call to
142 *               cl_disp_register
143 *
144 *       p_data
145 *               [in] Pointer to the client specific data payload
146 *               of this message.
147 *
148 * RETURN VALUE
149 *       This function does not return a value.
150 *
151 * NOTES
152 *       This typedef provides a function prototype reference for
153 *       the function provided by Dispatcher clients as a parameter
154 *       to the cl_disp_register function.
155 *
156 * SEE ALSO
157 *       Dispatcher, cl_disp_register
158 *********/
159
160 /****f* Component Library: Dispatcher/cl_pfn_msgdone_cb_t
161 * NAME
162 *       cl_pfn_msgdone_cb_t
163 *
164 * DESCRIPTION
165 *       This typedef defines the prototype for client functions invoked
166 *       by the Dispatcher.  The Dispatcher calls the corresponding
167 *       client function after completing delivery of a message.
168 *
169 *       The client function must be reentrant if the user creates a
170 *       Dispatcher with more than one worker thread.
171 *
172 * SYNOPSIS
173 */
174 typedef void
175  (*cl_pfn_msgdone_cb_t) (IN void *context, IN void *p_data);
176 /*
177 * PARAMETERS
178 *       context
179 *               [in] Client specific context specified in a call to
180 *               cl_disp_post
181 *
182 *       p_data
183 *               [in] Pointer to the client specific data payload
184 *               of this message.
185 *
186 * RETURN VALUE
187 *       This function does not return a value.
188 *
189 * NOTES
190 *       This typedef provides a function prototype reference for
191 *       the function provided by Dispatcher clients as a parameter
192 *       to the cl_disp_post function.
193 *
194 * SEE ALSO
195 *       Dispatcher, cl_disp_post
196 *********/
197
198 /****s* Component Library: Dispatcher/cl_dispatcher_t
199 * NAME
200 *       cl_dispatcher_t
201 *
202 * DESCRIPTION
203 *       Dispatcher structure.
204 *
205 *       The Dispatcher is thread safe.
206 *
207 *       The cl_dispatcher_t structure should be treated as opaque and should
208 *       be manipulated only through the provided functions.
209 *
210 * SYNOPSIS
211 */
212 typedef struct _cl_dispatcher {
213         cl_spinlock_t lock;
214         cl_ptr_vector_t reg_vec;
215         cl_qlist_t reg_list;
216         cl_thread_pool_t worker_threads;
217         cl_qlist_t msg_fifo;
218         cl_qpool_t msg_pool;
219         uint64_t last_msg_queue_time_us;
220 } cl_dispatcher_t;
221 /*
222 * FIELDS
223 *       reg_vec
224 *               Vector of registration info objects.  Indexed by message msg_id.
225 *
226 *       lock
227 *               Spinlock to guard internal structures.
228 *
229 *       msg_fifo
230 *               FIFO of messages being processed by the Dispatcher.  New
231 *               messages are posted to the tail of the FIFO.  Worker threads
232 *               pull messages from the front.
233 *
234 *       worker_threads
235 *               Thread pool of worker threads to dispose of posted messages.
236 *
237 *       msg_pool
238 *               Pool of message objects to be processed through the FIFO.
239 *
240 *       reg_count
241 *               Count of the number of registrants.
242 *
243 *       state
244 *               Indicates the state of the object.
245 *
246 *       last_msg_queue_time_us
247 *               The time that the last message spent in the Q in usec
248 *
249 * SEE ALSO
250 *       Dispatcher
251 *********/
252
253 /****s* Component Library: Dispatcher/cl_disp_reg_info_t
254 * NAME
255 *       cl_disp_reg_info_t
256 *
257 * DESCRIPTION
258 *       Defines the dispatcher registration object structure.
259 *
260 *       The cl_disp_reg_info_t structure is for internal use by the
261 *       Dispatcher only.
262 *
263 * SYNOPSIS
264 */
265 typedef struct _cl_disp_reg_info {
266         cl_list_item_t list_item;
267         cl_pfn_msgrcv_cb_t pfn_rcv_callback;
268         const void *context;
269         atomic32_t ref_cnt;
270         cl_disp_msgid_t msg_id;
271         cl_dispatcher_t *p_disp;
272 } cl_disp_reg_info_t;
273 /*
274 * FIELDS
275 *       pfn_rcv_callback
276 *               Client's message receive callback.
277 *
278 *       context
279 *               Client's context for message receive callback.
280 *
281 *       rcv_thread_count
282 *               Number of threads currently in the receive callback.
283 *
284 *       msg_done_thread_count
285 *               Number of threads currently in the message done callback.
286 *
287 *       state
288 *               State of this registration object.
289 *                       DISP_REGSTATE_INIT: initialized and inactive
290 *                       DISP_REGSTATE_ACTIVE: in active use
291 *                       DISP_REGSTATE_UNREGPEND: unregistration is pending
292 *
293 *       msg_id
294 *               Dispatcher message msg_id value for this registration object.
295 *
296 *       p_disp
297 *               Pointer to parent Dispatcher.
298 *
299 * SEE ALSO
300 *********/
301
302 /****s* Component Library: Dispatcher/cl_disp_msg_t
303 * NAME
304 *       cl_disp_msg_t
305 *
306 * DESCRIPTION
307 *       Defines the dispatcher message structure.
308 *
309 *       The cl_disp_msg_t structure is for internal use by the
310 *       Dispatcher only.
311 *
312 * SYNOPSIS
313 */
314 typedef struct _cl_disp_msg {
315         cl_pool_item_t item;
316         const void *p_data;
317         cl_disp_reg_info_t *p_src_reg;
318         cl_disp_reg_info_t *p_dest_reg;
319         cl_pfn_msgdone_cb_t pfn_xmt_callback;
320         uint64_t in_time;
321         const void *context;
322 } cl_disp_msg_t;
323 /*
324 * FIELDS
325 *       item
326 *               List & Pool linkage.  Must be first element in the structure!!
327 *
328 *       msg_id
329 *               The message's numberic ID value.
330 *
331 *       p_data
332 *               Pointer to the data payload for this message.  The payload
333 *               is opaque to the Dispatcher.
334 *
335 *       p_reg_info
336 *               Pointer to the registration info of the sender.
337 *
338 *       pfn_xmt_callback
339 *               Client's message done callback.
340 *
341 *       in_time
342 *               The absolute time the message was inserted into the queue
343 *
344 *       context
345 *               Client's message done callback context.
346 *
347 * SEE ALSO
348 *********/
349
350 /****s* Component Library: Dispatcher/cl_disp_reg_info_t
351 * NAME
352 *       cl_disp_reg_info_t
353 *
354 * DESCRIPTION
355 *       Defines the Dispatcher registration handle.  This handle
356 *       should be treated as opaque by the client.
357 *
358 * SYNOPSIS
359 */
360 typedef const struct _cl_disp_reg_info *cl_disp_reg_handle_t;
361 /**********/
362
363 /****f* Component Library: Dispatcher/cl_disp_construct
364 * NAME
365 *       cl_disp_construct
366 *
367 * DESCRIPTION
368 *       This function constructs a Dispatcher object.
369 *
370 * SYNOPSIS
371 */
372 void cl_disp_construct(IN cl_dispatcher_t * const p_disp);
373 /*
374 * PARAMETERS
375 *       p_disp
376 *               [in] Pointer to a Dispatcher.
377 *
378 * RETURN VALUE
379 *       This function does not return a value.
380 *
381 * NOTES
382 *       Allows calling cl_disp_init and cl_disp_destroy.
383 *
384 * SEE ALSO
385 *       Dispatcher, cl_disp_init, cl_disp_destroy
386 *********/
387
388 /****f* Component Library: Dispatcher/cl_disp_init
389 * NAME
390 *       cl_disp_init
391 *
392 * DESCRIPTION
393 *       This function initializes a Dispatcher object.
394 *
395 * SYNOPSIS
396 */
397 cl_status_t
398 cl_disp_init(IN cl_dispatcher_t * const p_disp,
399              IN const uint32_t thread_count, IN const char *const name);
400 /*
401 * PARAMETERS
402 *       p_disp
403 *               [in] Pointer to a Dispatcher.
404 *
405 *       thread_count
406 *               [in] The number of worker threads to create in this Dispatcher.
407 *               A value of 0 causes the Dispatcher to create one worker thread
408 *               per CPU in the system.  When the Dispatcher is created with
409 *               only one thread, the Dispatcher guarantees to deliver posted
410 *               messages in order.  When the Dispatcher is created with more
411 *               than one thread, messages may be delivered out of order.
412 *
413 *       name
414 *               [in] Name to associate with the threads.  The name may be up to 16
415 *               characters, including a terminating null character.  All threads
416 *               created in the Dispatcher have the same name.
417 *
418 * RETURN VALUE
419 *       CL_SUCCESS if the operation is successful.
420 *
421 * SEE ALSO
422 *       Dispatcher, cl_disp_destoy, cl_disp_register, cl_disp_unregister,
423 *       cl_disp_post
424 *********/
425
426 /****f* Component Library: Dispatcher/cl_disp_shutdown
427 * NAME
428 *       cl_disp_shutdown
429 *
430 * DESCRIPTION
431 *       This function shutdown a Dispatcher object. So it unreg all messages and
432 *  clears the fifo and waits for the threads to exit
433 *
434 * SYNOPSIS
435 */
436 void cl_disp_shutdown(IN cl_dispatcher_t * const p_disp);
437 /*
438 * PARAMETERS
439 *       p_disp
440 *               [in] Pointer to a Dispatcher.
441 *
442 * RETURN VALUE
443 *       This function does not return a value.
444 *
445 * NOTES
446 *       This function does not returns until all worker threads
447 *       have exited client callback functions and been successfully
448 *       shutdowned.
449 *
450 * SEE ALSO
451 *       Dispatcher, cl_disp_construct, cl_disp_init
452 *********/
453
454 /****f* Component Library: Dispatcher/cl_disp_destroy
455 * NAME
456 *       cl_disp_destroy
457 *
458 * DESCRIPTION
459 *       This function destroys a Dispatcher object.
460 *
461 * SYNOPSIS
462 */
463 void cl_disp_destroy(IN cl_dispatcher_t * const p_disp);
464 /*
465 * PARAMETERS
466 *       p_disp
467 *               [in] Pointer to a Dispatcher.
468 *
469 * RETURN VALUE
470 *       This function does not return a value.
471 *
472 * SEE ALSO
473 *       Dispatcher, cl_disp_construct, cl_disp_init
474 *********/
475
476 /****f* Component Library: Dispatcher/cl_disp_register
477 * NAME
478 *       cl_disp_register
479 *
480 * DESCRIPTION
481 *       This function registers a client with a Dispatcher object.
482 *
483 * SYNOPSIS
484 */
485 cl_disp_reg_handle_t
486 cl_disp_register(IN cl_dispatcher_t * const p_disp,
487                  IN const cl_disp_msgid_t msg_id,
488                  IN cl_pfn_msgrcv_cb_t pfn_callback OPTIONAL,
489                  IN const void *const context);
490 /*
491 * PARAMETERS
492 *       p_disp
493 *               [in] Pointer to a Dispatcher.
494 *
495 *       msg_id
496 *               [in] Numberic message ID for which the client is registering.
497 *               If the client does not wish to receive any messages,
498 *               (a send-only client) then the caller should set this value
499 *               to CL_DISP_MSGID_NONE.  For efficiency, numeric message msg_id
500 *               values should start with 0 and should be contiguous, or nearly so.
501 *
502 *       pfn_callback
503 *               [in] Message receive callback.  The Dispatcher calls this
504 *               function after receiving a posted message with the
505 *               appropriate message msg_id value.  Send-only clients may specify
506 *               NULL for this value.
507 *
508 *       context
509 *               [in] Client context value passed to the cl_pfn_msgrcv_cb_t
510 *               function.
511 *
512 * RETURN VALUE
513 *       On success a Dispatcher registration handle.
514 *       CL_CL_DISP_INVALID_HANDLE otherwise.
515 *
516 * SEE ALSO
517 *       Dispatcher, cl_disp_unregister, cl_disp_post
518 *********/
519
520 /****f* Component Library: Dispatcher/cl_disp_unregister
521 * NAME
522 *       cl_disp_unregister
523 *
524 * DESCRIPTION
525 *       This function unregisters a client from a Dispatcher.
526 *
527 * SYNOPSIS
528 */
529 void cl_disp_unregister(IN const cl_disp_reg_handle_t handle);
530 /*
531 * PARAMETERS
532 *       handle
533 *               [in] cl_disp_reg_handle_t value return by cl_disp_register.
534 *
535 * RETURN VALUE
536 *       This function does not return a value.
537 *
538 * NOTES
539 *       This function will not return until worker threads have exited
540 *       the callback functions for this client.  Do not invoke this
541 *       function from a callback.
542 *
543 * SEE ALSO
544 *       Dispatcher, cl_disp_register
545 *********/
546
547 /****f* Component Library: Dispatcher/cl_disp_post
548 * NAME
549 *       cl_disp_post
550 *
551 * DESCRIPTION
552 *       This function posts a message to a Dispatcher object.
553 *
554 * SYNOPSIS
555 */
556 cl_status_t
557 cl_disp_post(IN const cl_disp_reg_handle_t handle,
558              IN const cl_disp_msgid_t msg_id,
559              IN const void *const p_data,
560              IN cl_pfn_msgdone_cb_t pfn_callback OPTIONAL,
561              IN const void *const context);
562 /*
563 * PARAMETERS
564 *       handle
565 *               [in] cl_disp_reg_handle_t value return by cl_disp_register.
566 *
567 *       msg_id
568 *               [in] Numeric message msg_id value associated with this message.
569 *
570 *       p_data
571 *               [in] Data payload for this message.
572 *
573 *       pfn_callback
574 *               [in] Pointer to a cl_pfn_msgdone_cb_t function.
575 *               The Dispatcher calls this function after the message has been
576 *               processed by the recipient.
577 *               The caller may pass NULL for this value, which indicates no
578 *               message done callback is necessary.
579 *
580 *       context
581 *               [in] Client context value passed to the cl_pfn_msgdone_cb_t
582 *               function.
583 *
584 * RETURN VALUE
585 *       CL_SUCCESS if the message was successfully queued in the Dispatcher.
586 *
587 * NOTES
588 *       The caller must not modify the memory pointed to by p_data until
589 *       the Dispatcher call the pfn_callback function.
590 *
591 * SEE ALSO
592 *       Dispatcher
593 *********/
594
595 /****f* Component Library: Dispatcher/cl_disp_get_queue_status
596 * NAME
597 *       cl_disp_get_queue_status
598 *
599 * DESCRIPTION
600 *       This function posts a message to a Dispatcher object.
601 *
602 * SYNOPSIS
603 */
604 void
605 cl_disp_get_queue_status(IN const cl_disp_reg_handle_t handle,
606                          OUT uint32_t * p_num_queued_msgs,
607                          OUT uint64_t * p_last_msg_queue_time_ms);
608 /*
609 * PARAMETERS
610 *   handle
611 *     [in] cl_disp_reg_handle_t value return by cl_disp_register.
612 *
613 *   p_last_msg_queue_time_ms
614 *     [out] pointer to a variable to hold the time the last popped up message
615 *           spent in the queue
616 *
617 *   p_num_queued_msgs
618 *     [out] number of messages in the queue
619 *
620 * RETURN VALUE
621 *       Thr time the last popped up message stayed in the queue, in msec
622 *
623 * NOTES
624 *       Extarnel Locking is not required.
625 *
626 * SEE ALSO
627 *       Dispatcher
628 *********/
629
630 END_C_DECLS
631 #endif                          /* !defined(_CL_DISPATCHER_H_) */