eRPC
nexus.h
1 #pragma once
2 
3 #include <unistd.h>
4 #include <unordered_map>
5 #include "common.h"
6 #include "heartbeat_mgr.h"
7 #include "session.h"
8 #include "sm_types.h"
9 #include "util/logger.h"
10 #include "util/mt_queue.h"
11 #include "util/tls_registry.h"
12 
13 namespace erpc {
14 
15 // Forward declaration for friendship
16 template <typename T>
17 class Rpc;
18 
22 class Nexus {
23  friend class Rpc<CTransport>;
24 
40  public:
41  Nexus(std::string local_uri, size_t numa_node, size_t num_bg_threads);
42 
43  ~Nexus();
44 
51  int register_req_func(uint8_t req_type, erpc_req_func_t req_func,
52  ReqFuncType req_func_type = ReqFuncType::kForeground);
53 
54  private:
55  enum class BgWorkItemType : bool { kReq, kResp };
56 
58  class BgWorkItem {
59  public:
60  BgWorkItem() {}
61 
62  static inline BgWorkItem make_req_item(void *context, SSlot *sslot) {
63  BgWorkItem ret;
64  ret.wi_type = BgWorkItemType::kReq;
65  ret.context = context;
66  ret.sslot = sslot;
67  return ret;
68  }
69 
70  static inline BgWorkItem make_resp_item(void *context,
71  erpc_cont_func_t cont_func,
72  void *tag) {
73  BgWorkItem ret;
74  ret.wi_type = BgWorkItemType::kResp;
75  ret.context = context;
76  ret.cont_func = cont_func;
77  ret.tag = tag;
78  return ret;
79  }
80 
81  BgWorkItemType wi_type;
82  void *context;
83 
84  // Fields for request handlers. For request handlers, we still have
85  // ownership of the request slot, so we can hold it until enqueue_response.
86  SSlot *sslot;
87 
88  // Fields for continuations. For continuations, we have lost ownership of
89  // the request slot, so the work item contains all needed info by value.
90  erpc_cont_func_t cont_func;
91  void *tag;
92 
93  bool is_req() const { return wi_type == BgWorkItemType::kReq; }
94  };
95 
97  class Hook {
98  public:
99  uint8_t rpc_id;
100 
102  MtQueue<BgWorkItem> *bg_req_queue_arr[kMaxBgThreads] = {nullptr};
103 
106  MtQueue<SmWorkItem> sm_rx_queue;
107  };
108 
111  bool rpc_id_exists(uint8_t rpc_id);
112 
114  void register_hook(Hook *hook);
115 
117  void unregister_hook(Hook *hook);
118 
120  class BgThreadCtx {
121  public:
122  volatile bool *kill_switch;
123 
128  std::array<ReqFunc, kReqTypeArraySize> *req_func_arr;
129 
130  TlsRegistry *tls_registry;
131  size_t bg_thread_index;
132  MtQueue<BgWorkItem> *bg_req_queue;
133  };
134 
136  class SmThreadCtx {
137  public:
138  // Installed by the Nexus
139  std::string hostname;
140  uint16_t sm_udp_port;
141  double freq_ghz;
142 
145  volatile bool *kill_switch;
146 
147  HeartbeatMgr *heartbeat_mgr;
148  volatile Hook **reg_hooks_arr;
149  std::mutex *reg_hooks_lock;
150  };
151 
153  static void bg_thread_func(BgThreadCtx ctx);
154 
156  static void sm_thread_func(SmThreadCtx ctx);
157 
159  const double freq_ghz;
160  const std::string hostname;
161  const uint16_t sm_udp_port;
162  const size_t numa_node;
163  const size_t num_bg_threads;
164  TlsRegistry tls_registry;
165 
167  std::array<ReqFunc, kReqTypeArraySize> req_func_arr;
168  const uint8_t pad[64] = {0};
169 
172  bool req_func_registration_allowed = true;
173 
175  Hook *reg_hooks_arr[kMaxRpcId + 1] = {nullptr};
176  std::mutex reg_hooks_lock;
177 
178  HeartbeatMgr heartbeat_mgr;
179  volatile bool kill_switch;
180 
181  std::thread sm_thread;
182  MtQueue<BgWorkItem> bg_req_queue[kMaxBgThreads];
183  std::thread bg_thread_arr[kMaxBgThreads];
184 };
185 } // namespace erpc
An Rpc object is the main communication end point in eRPC. Applications use it to create sessions wit...
Definition: nexus.h:17
int register_req_func(uint8_t req_type, erpc_req_func_t req_func, ReqFuncType req_func_type=ReqFuncType::kForeground)
Register application-defined request handler function. This must be done before any Rpc registers a h...
Nexus(std::string local_uri, size_t numa_node, size_t num_bg_threads)
Initialize eRPC for this process.
A per-process library object used for initializing eRPC.
Definition: nexus.h:22