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.
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:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
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.
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
38 * Declaration of dispatcher abstraction.
41 #ifndef _CL_DISPATCHER_H_
42 #define _CL_DISPATCHER_H_
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>
52 # define BEGIN_C_DECLS extern "C" {
53 # define END_C_DECLS }
54 #else /* !__cplusplus */
55 # define BEGIN_C_DECLS
57 #endif /* __cplusplus */
60 /****h* Component Library/Dispatcher
65 * The Dispatcher provides a facility for message routing to
66 * asynchronous worker threads.
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.
76 * Initialization/Destruction:
77 * cl_disp_construct, cl_disp_init, cl_disp_shutdown, cl_disp_destroy
80 * cl_disp_post, cl_disp_reset, cl_disp_wait_on
82 /****s* Component Library: Dispatcher/cl_disp_msgid_t
87 * Defines the type of dispatcher messages.
91 typedef uint32_t cl_disp_msgid_t;
94 /****s* Component Library: Dispatcher/CL_DISP_MSGID_NONE
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.
103 * No Dispatcher message is allowed to have this value.
107 #define CL_DISP_MSGID_NONE 0xFFFFFFFF
110 /****s* Component Library: Dispatcher/CL_DISP_INVALID_HANDLE
112 * CL_DISP_INVALID_HANDLE
115 * Defines the value of an invalid Dispatcher registration handle.
119 #define CL_DISP_INVALID_HANDLE ((cl_disp_reg_handle_t)0)
122 /****f* Component Library: Dispatcher/cl_pfn_msgrcv_cb_t
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.
131 * The client function must be reentrant if the user creates a
132 * Dispatcher with more than one worker thread.
137 (*cl_pfn_msgrcv_cb_t) (IN void *context, IN void *p_data);
141 * [in] Client specific context specified in a call to
145 * [in] Pointer to the client specific data payload
149 * This function does not return a value.
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.
157 * Dispatcher, cl_disp_register
160 /****f* Component Library: Dispatcher/cl_pfn_msgdone_cb_t
162 * cl_pfn_msgdone_cb_t
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.
169 * The client function must be reentrant if the user creates a
170 * Dispatcher with more than one worker thread.
175 (*cl_pfn_msgdone_cb_t) (IN void *context, IN void *p_data);
179 * [in] Client specific context specified in a call to
183 * [in] Pointer to the client specific data payload
187 * This function does not return a value.
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.
195 * Dispatcher, cl_disp_post
198 /****s* Component Library: Dispatcher/cl_dispatcher_t
203 * Dispatcher structure.
205 * The Dispatcher is thread safe.
207 * The cl_dispatcher_t structure should be treated as opaque and should
208 * be manipulated only through the provided functions.
212 typedef struct _cl_dispatcher {
214 cl_ptr_vector_t reg_vec;
216 cl_thread_pool_t worker_threads;
219 uint64_t last_msg_queue_time_us;
224 * Vector of registration info objects. Indexed by message msg_id.
227 * Spinlock to guard internal structures.
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.
235 * Thread pool of worker threads to dispose of posted messages.
238 * Pool of message objects to be processed through the FIFO.
241 * Count of the number of registrants.
244 * Indicates the state of the object.
246 * last_msg_queue_time_us
247 * The time that the last message spent in the Q in usec
253 /****s* Component Library: Dispatcher/cl_disp_reg_info_t
258 * Defines the dispatcher registration object structure.
260 * The cl_disp_reg_info_t structure is for internal use by the
265 typedef struct _cl_disp_reg_info {
266 cl_list_item_t list_item;
267 cl_pfn_msgrcv_cb_t pfn_rcv_callback;
270 cl_disp_msgid_t msg_id;
271 cl_dispatcher_t *p_disp;
272 } cl_disp_reg_info_t;
276 * Client's message receive callback.
279 * Client's context for message receive callback.
282 * Number of threads currently in the receive callback.
284 * msg_done_thread_count
285 * Number of threads currently in the message done callback.
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
294 * Dispatcher message msg_id value for this registration object.
297 * Pointer to parent Dispatcher.
302 /****s* Component Library: Dispatcher/cl_disp_msg_t
307 * Defines the dispatcher message structure.
309 * The cl_disp_msg_t structure is for internal use by the
314 typedef struct _cl_disp_msg {
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;
326 * List & Pool linkage. Must be first element in the structure!!
329 * The message's numberic ID value.
332 * Pointer to the data payload for this message. The payload
333 * is opaque to the Dispatcher.
336 * Pointer to the registration info of the sender.
339 * Client's message done callback.
342 * The absolute time the message was inserted into the queue
345 * Client's message done callback context.
350 /****s* Component Library: Dispatcher/cl_disp_reg_info_t
355 * Defines the Dispatcher registration handle. This handle
356 * should be treated as opaque by the client.
360 typedef const struct _cl_disp_reg_info *cl_disp_reg_handle_t;
363 /****f* Component Library: Dispatcher/cl_disp_construct
368 * This function constructs a Dispatcher object.
372 void cl_disp_construct(IN cl_dispatcher_t * const p_disp);
376 * [in] Pointer to a Dispatcher.
379 * This function does not return a value.
382 * Allows calling cl_disp_init and cl_disp_destroy.
385 * Dispatcher, cl_disp_init, cl_disp_destroy
388 /****f* Component Library: Dispatcher/cl_disp_init
393 * This function initializes a Dispatcher object.
398 cl_disp_init(IN cl_dispatcher_t * const p_disp,
399 IN const uint32_t thread_count, IN const char *const name);
403 * [in] Pointer to a Dispatcher.
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.
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.
419 * CL_SUCCESS if the operation is successful.
422 * Dispatcher, cl_disp_destoy, cl_disp_register, cl_disp_unregister,
426 /****f* Component Library: Dispatcher/cl_disp_shutdown
431 * This function shutdown a Dispatcher object. So it unreg all messages and
432 * clears the fifo and waits for the threads to exit
436 void cl_disp_shutdown(IN cl_dispatcher_t * const p_disp);
440 * [in] Pointer to a Dispatcher.
443 * This function does not return a value.
446 * This function does not returns until all worker threads
447 * have exited client callback functions and been successfully
451 * Dispatcher, cl_disp_construct, cl_disp_init
454 /****f* Component Library: Dispatcher/cl_disp_destroy
459 * This function destroys a Dispatcher object.
463 void cl_disp_destroy(IN cl_dispatcher_t * const p_disp);
467 * [in] Pointer to a Dispatcher.
470 * This function does not return a value.
473 * Dispatcher, cl_disp_construct, cl_disp_init
476 /****f* Component Library: Dispatcher/cl_disp_register
481 * This function registers a client with a Dispatcher object.
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);
493 * [in] Pointer to a Dispatcher.
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.
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.
509 * [in] Client context value passed to the cl_pfn_msgrcv_cb_t
513 * On success a Dispatcher registration handle.
514 * CL_CL_DISP_INVALID_HANDLE otherwise.
517 * Dispatcher, cl_disp_unregister, cl_disp_post
520 /****f* Component Library: Dispatcher/cl_disp_unregister
525 * This function unregisters a client from a Dispatcher.
529 void cl_disp_unregister(IN const cl_disp_reg_handle_t handle);
533 * [in] cl_disp_reg_handle_t value return by cl_disp_register.
536 * This function does not return a value.
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.
544 * Dispatcher, cl_disp_register
547 /****f* Component Library: Dispatcher/cl_disp_post
552 * This function posts a message to a Dispatcher object.
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);
565 * [in] cl_disp_reg_handle_t value return by cl_disp_register.
568 * [in] Numeric message msg_id value associated with this message.
571 * [in] Data payload for this message.
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.
581 * [in] Client context value passed to the cl_pfn_msgdone_cb_t
585 * CL_SUCCESS if the message was successfully queued in the Dispatcher.
588 * The caller must not modify the memory pointed to by p_data until
589 * the Dispatcher call the pfn_callback function.
595 /****f* Component Library: Dispatcher/cl_disp_get_queue_status
597 * cl_disp_get_queue_status
600 * This function posts a message to a Dispatcher object.
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);
611 * [in] cl_disp_reg_handle_t value return by cl_disp_register.
613 * p_last_msg_queue_time_ms
614 * [out] pointer to a variable to hold the time the last popped up message
618 * [out] number of messages in the queue
621 * Thr time the last popped up message stayed in the queue, in msec
624 * Extarnel Locking is not required.
631 #endif /* !defined(_CL_DISPATCHER_H_) */