blob: 21884665075d9ec019ccd39759b9782f150db5fb [file] [log] [blame]
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001/*
2 * Copyright (c) 2018 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef VPP_VCL_EVENT_H
17#define VPP_VCL_EVENT_H
18
19/**
20 * @file
21 * @brief VPP Communications Library (VCL) event handler.
22 *
23 * Declarations for generic event handling in VCL.
24 */
25
26#include <vppinfra/types.h>
27#include <vppinfra/lock.h>
28#include <pthread.h>
29
30typedef union vce_event_key_
31{
32 struct {
33 u32 eid;
34 u32 session_index;
35 };
36 u64 as_u64;
37} vce_event_key_t;
38
39typedef struct vce_event_
40{
41 vce_event_key_t evk;
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -070042 u32 recycle;
43 u64 data[2]; // Hard code size to avoid allocator thrashing.
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080044} vce_event_t;
45
46typedef void (*vce_event_callback_t) (void *reg /*vce_event_handler_reg_t* */);
47
48typedef struct vce_event_handler_reg_
49{
50 vce_event_callback_t handler_fn;
51 pthread_mutex_t handler_lock;
52 pthread_cond_t handler_cond;
53 u32 ev_idx;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -080054 u64 evk; //Event key
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080055 u32 replaced_handler_idx;
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -080056 void *handler_fn_args;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080057} vce_event_handler_reg_t;
58
59typedef struct vce_event_thread_
60{
61 pthread_t thread;
62 pthread_mutex_t generator_lock;
63 pthread_cond_t generator_cond;
64 u32 *event_index_fifo;
65 u8 recycle_event;
66 clib_spinlock_t events_lockp;
67 vce_event_t *vce_events; //pool
68 clib_spinlock_t handlers_lockp;
69 vce_event_handler_reg_t *vce_event_handlers; //pool
70 uword *handlers_index_by_event_key; //hash
71} vce_event_thread_t;
72
73/**
74 * @brief vce_generate_event
75 * - used to trigger an event in the event thread so that registered
76 * handlers are notified
77 *
78 * @param evt - vce_event_thread_t - event system state
79 * @param ev_idx - index to vce_event_thread_t vce_event pool
80 *
81 * @return success/failure rv
82 */
83int vce_generate_event (vce_event_thread_t *evt, u32 ev_idx);
84
85/**
86 * @brief vce_clear_event()
87 * - removes event from event_pool
88 *
89 * @param evt - vce_event_thread_t - event system state
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -070090 * @param ev_idx - u32 - index of event to remove
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080091 */
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -070092void vce_clear_event (vce_event_thread_t *evt, u32 ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080093
94/**
95 * @brief vce_get_event_from_index()
96 *
97 * @param evt - vce_event_thread_t - event system state
98 * @param ev_idx - index to vce_event_thread_t vce_event pool
99 *
100 * @return vce_event_t *
101 */
102vce_event_t * vce_get_event_from_index(vce_event_thread_t *evt, u32 ev_idx);
103
104/**
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700105 * @brief vce_get_event_data()
106 *
107 * @param ev - vce_event_t * - event
108 * @param data_size - u32 - required size of data
109 *
110 * @return vce_event_t *
111 */
112always_inline void * vce_get_event_data(vce_event_t *ev, u32 data_size)
113{
114 ASSERT(sizeof(ev->data) >= data_size);
115 return (&ev->data);
116}
117
118/**
Keith Burns (alagalah)7cf80e02018-03-08 16:46:25 -0800119 * @brief vce_get_event_handler()
120 * - returns handler if exists or 0
121 * @param evt - vce_event_thread_t - event system state
122 * @param evk - event key
123 * @return vce_event_handler_reg_t *
124 */
125vce_event_handler_reg_t * vce_get_event_handler (vce_event_thread_t *evt,
126 vce_event_key_t *evk);
127
128/**
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800129 * @brief vce_register_handler
130 * - used by functions who need to be notified that an event has occurred
131 * on a vce_event_key_t (i.e. event type (enum) and sessionID)
132 * - if a handler already exists, the index to the old handler is stored
133 * inside the new handler for re-instatement on vce_unregister_handler()
134
135 * @param evt - vce_event_thread_t - event system state
136 * @param evk - vce_event_key_t current an eventID from enum in consumer and
137 * sessionID
138 * @param cb - vce_event_callback_t function to handle event
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800139 * @param cb_args - args that the callback needs passed back to it.
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800140 * @return vce_handler_reg_t - the function that needs event notification
141 * needs to block on a condvar mutex to reduce spin. That is in here.
142 */
143vce_event_handler_reg_t * vce_register_handler (vce_event_thread_t *evt,
144 vce_event_key_t *evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800145 vce_event_callback_t cb,
146 void *cb_args);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800147
148/**
149 * @brief vce_unregister_handler
150 * - used by functions to remove need to be notified that an event has occurred
151 * on a vce_event_key_t (i.e. event type (enum) and sessionID)
152 * - if this handler replaced an existing one, re-instate it.
153 *
154 * @param evt - vce_event_thread_t - event system state
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800155 * @param handler - handler to be unregistered
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800156 * @return success/failure rv
157 */
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800158int vce_unregister_handler (vce_event_thread_t *evt,
159 vce_event_handler_reg_t *handler);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800160
161/**
162 * @brief vce_event_thread_fn
163 * - main event thread that waits on a generic condvar/mutex that a signal
164 * has been generated.
165 * - loops through all registered handlers for that vce_event_key_t
166 * (event enum + sessionID)
167 *
168 * @param arg - cast to type of event defined in consuming program.
169 * @return
170 */
171extern void * vce_event_thread_fn (void *arg);
172
173/**
174 * @brief vce_start_event_thread
175 * - as name suggests. What is important is that vce_event_thread_t is allocated
176 * on the same heap as "everything else". ie use clib_mem_alloc.
177 * @param evt - vce_event_thread_t - event system state
178 * @param max_events - depth of event FIFO for max number of outstanding events.
179 * @return succes/failure
180 */
181int vce_start_event_thread (vce_event_thread_t *evt, u8 max_events);
182
183#endif //VPP_VCL_EVENT_H