CIRCT  19.0.0git
Endpoint.h
Go to the documentation of this file.
1 //===- Endpoint.h - Cosim endpoint server -----------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Declare the class which is used to model DPI endpoints.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef COSIM_ENDPOINT_H
14 #define COSIM_ENDPOINT_H
15 
16 #include "esi/Common.h"
17 
18 #include <functional>
19 #include <map>
20 #include <memory>
21 #include <mutex>
22 #include <queue>
23 #include <string>
24 
25 namespace esi {
26 namespace cosim {
27 
28 /// Implements a bi-directional, thread-safe bridge between the RPC server and
29 /// DPI functions.
30 ///
31 /// Several of the methods below are inline with the declaration to make them
32 /// candidates for inlining during compilation. This is particularly important
33 /// on the simulation side since polling happens at each clock and we do not
34 /// want to slow down the simulation any more than necessary.
35 class Endpoint {
36 public:
37  /// Representing messages as shared pointers to vectors may be a performance
38  /// issue in the future but it is the easiest way to ensure memory
39  /// correctness.
40  using MessageDataPtr = std::unique_ptr<MessageData>;
41 
42  /// Construct an endpoint which knows and the type IDs in both directions.
43  Endpoint(std::string fromHostTypeId, std::string toHostTypeId);
44  ~Endpoint();
45  /// Disallow copying. There is only ONE endpoint object per logical endpoint
46  /// so copying is almost always a bug.
47  Endpoint(const Endpoint &) = delete;
48 
49  std::string getSendTypeId() const { return fromHostTypeId; }
50  std::string getRecvTypeId() const { return toHostTypeId; }
51 
52  /// These two are used to set and unset the inUse flag, to ensure that an open
53  /// endpoint is not opened again.
54  bool setInUse();
55  void returnForUse();
56 
57  /// Queue message to the simulation.
59  Lock g(m);
60  toCosim.push(std::move(msg));
61  }
62 
63  /// Pop from the to-simulator queue. Return true if there was a message in the
64  /// queue.
66  Lock g(m);
67  if (toCosim.empty())
68  return false;
69  msg = std::move(toCosim.front());
70  toCosim.pop();
71  return true;
72  }
73 
74  /// Queue message to the RPC client.
76  Lock g(m);
77  toClient.push(std::move(msg));
78  }
79 
80  /// Pop from the to-RPC-client queue. Return true if there was a message in
81  /// the queue.
83  Lock g(m);
84  if (toClient.empty())
85  return false;
86  msg = std::move(toClient.front());
87  toClient.pop();
88  return true;
89  }
90 
91 private:
92  const std::string fromHostTypeId;
93  const std::string toHostTypeId;
94  bool inUse;
95 
96  using Lock = std::lock_guard<std::mutex>;
97 
98  /// This class needs to be thread-safe. All of the mutable member variables
99  /// are protected with this object-wide lock. This may be a performance issue
100  /// in the future.
101  std::mutex m;
102  /// Message queue from RPC client to the simulation.
103  std::queue<MessageDataPtr> toCosim;
104  /// Message queue to RPC client from the simulation.
105  std::queue<MessageDataPtr> toClient;
106 };
107 
108 /// The Endpoint registry is where Endpoints report their existence (register)
109 /// and they are looked up by RPC clients.
111 public:
112  /// Register an Endpoint. Creates the Endpoint object and owns it. Returns
113  /// false if unsuccessful.
114  bool registerEndpoint(std::string epId, std::string fromHostTypeId,
115  std::string toHostTypeId);
116 
117  /// Get the specified endpoint. Return nullptr if it does not exist. This
118  /// method is defined inline so it can be inlined at compile time. Performance
119  /// is important here since this method is used in the polling call from the
120  /// simulator. Returns nullptr if the endpoint cannot be found.
121  Endpoint *operator[](const std::string &epId) {
122  Lock g(m);
123  auto it = endpoints.find(epId);
124  if (it == endpoints.end())
125  return nullptr;
126  return &it->second;
127  }
128 
129  /// Iterate over the list of endpoints, calling the provided function for each
130  /// endpoint.
131  void iterateEndpoints(
132  const std::function<void(std::string id, const Endpoint &)> &f) const;
133  /// Return the number of endpoints.
134  size_t size() const;
135 
136 private:
137  using Lock = std::lock_guard<std::mutex>;
138 
139  /// This object needs to be thread-safe. An object-wide mutex is sufficient.
140  std::mutex m;
141 
142  /// Endpoint ID to object pointer mapping.
143  std::map<std::string, Endpoint> endpoints;
144 };
145 
146 } // namespace cosim
147 } // namespace esi
148 
149 #endif
The Endpoint registry is where Endpoints report their existence (register) and they are looked up by ...
Definition: Endpoint.h:110
bool registerEndpoint(std::string epId, std::string fromHostTypeId, std::string toHostTypeId)
Register an Endpoint.
Definition: Endpoint.cpp:37
std::mutex m
This object needs to be thread-safe. An object-wide mutex is sufficient.
Definition: Endpoint.h:140
void iterateEndpoints(const std::function< void(std::string id, const Endpoint &)> &f) const
Iterate over the list of endpoints, calling the provided function for each endpoint.
Definition: Endpoint.cpp:55
Endpoint * operator[](const std::string &epId)
Get the specified endpoint.
Definition: Endpoint.h:121
size_t size() const
Return the number of endpoints.
Definition: Endpoint.cpp:65
std::lock_guard< std::mutex > Lock
Definition: Endpoint.h:137
std::map< std::string, Endpoint > endpoints
Endpoint ID to object pointer mapping.
Definition: Endpoint.h:143
Implements a bi-directional, thread-safe bridge between the RPC server and DPI functions.
Definition: Endpoint.h:35
std::unique_ptr< MessageData > MessageDataPtr
Representing messages as shared pointers to vectors may be a performance issue in the future but it i...
Definition: Endpoint.h:40
std::string getSendTypeId() const
Definition: Endpoint.h:49
std::queue< MessageDataPtr > toCosim
Message queue from RPC client to the simulation.
Definition: Endpoint.h:103
bool setInUse()
These two are used to set and unset the inUse flag, to ensure that an open endpoint is not opened aga...
Definition: Endpoint.cpp:22
std::string getRecvTypeId() const
Definition: Endpoint.h:50
void pushMessageToSim(MessageDataPtr msg)
Queue message to the simulation.
Definition: Endpoint.h:58
void pushMessageToClient(MessageDataPtr msg)
Queue message to the RPC client.
Definition: Endpoint.h:75
std::lock_guard< std::mutex > Lock
Definition: Endpoint.h:96
std::queue< MessageDataPtr > toClient
Message queue to RPC client from the simulation.
Definition: Endpoint.h:105
bool getMessageToClient(MessageDataPtr &msg)
Pop from the to-RPC-client queue.
Definition: Endpoint.h:82
const std::string fromHostTypeId
Definition: Endpoint.h:92
const std::string toHostTypeId
Definition: Endpoint.h:93
std::mutex m
This class needs to be thread-safe.
Definition: Endpoint.h:101
bool getMessageToSim(MessageDataPtr &msg)
Pop from the to-simulator queue.
Definition: Endpoint.h:65
Endpoint(const Endpoint &)=delete
Disallow copying.
Endpoint(std::string fromHostTypeId, std::string toHostTypeId)
Construct an endpoint which knows and the type IDs in both directions.
Definition: Endpoint.cpp:17
Definition: esi.py:1