C++ Device API Reference Manual
Reference documentation for the Simics C++ Device API.
 
Loading...
Searching...
No Matches
event.h
Go to the documentation of this file.
1// -*- mode: C++; c-file-style: "virtutech-c++" -*-
2
3/*
4 © 2023 Intel Corporation
5
6 This software and the related documents are Intel copyrighted materials, and
7 your use of them is governed by the express license under which they were
8 provided to you ("License"). Unless the License provides otherwise, you may
9 not use, modify, copy, publish, distribute, disclose or transmit this software
10 or the related documents without Intel's prior written permission.
11
12 This software and the related documents are provided as is, with no express or
13 implied warranties, other than those that are expressly stated in the License.
14*/
15
16#ifndef SIMICS_EVENT_H
17#define SIMICS_EVENT_H
18
19#include <simics/base/event.h> // event_class_flag_t
20#include <simics/base/time.h> // SIM_object_clock
21#include <simics/base/sim-exception.h> // SIM_clear_exception
22#include <string>
23#include <stdexcept>
24#include <type_traits> // add_pointer_t
25
26#include "conf-object.h"
27#include "log.h"
29#include "detail/event-helper.h"
30
31namespace simics {
32
33using ev_callback = std::add_pointer_t<void(conf_object_t *, void *)>;
35using ev_value_getter = std::add_pointer_t<attr_value_t(conf_object_t *obj,
36 void *data)>;
37using ev_value_setter = std::add_pointer_t<void *(conf_object_t *obj,
38 attr_value_t value)>;
39using ev_describe = std::add_pointer_t<char *(conf_object_t *obj,
40 void *data)>;
41
42/*
43 * Class provides information for event registration
44 * @see ConfClass *add(EventInfo &&event)
45 */
46struct EventInfo {
47 EventInfo(const std::string &name, event_class_flag_t flags,
48 event_class_t **ev, ev_callback callback, ev_destroy destroy,
49 ev_value_getter get_value, ev_value_setter set_value,
50 ev_describe describe)
51 : name_(name), flags_(flags), ev_(ev), callback_(callback),
52 destroy_(destroy), get_value_(get_value), set_value_(set_value),
53 describe_(describe) {
54 if (name.empty()) {
55 throw std::invalid_argument {
56 "Event name cannot be empty"
57 };
58 }
59 if (ev == nullptr) {
60 throw std::invalid_argument {
61 "Pointer of event class pointer for event " + name + \
62 " is missing"
63 };
64 }
65 if (callback == nullptr) {
66 throw std::invalid_argument {
67 "Callback function for event " + name + " is missing"
68 };
69 }
70 }
71
72 EventInfo(const std::string &name, event_class_t **ev,
73 ev_callback callback)
74 : EventInfo(name, Sim_EC_No_Flags, ev, callback,
75 nullptr, nullptr, nullptr, nullptr) {
76 }
77
78 std::string name_;
79 event_class_flag_t flags_ {Sim_EC_No_Flags};
80 event_class_t **ev_ {nullptr};
86};
87
88/*
89 * Base class for all events that can be posted on a processor time
90 * queue. Use TimeEvent/CycleEvent/StepEvent based on the event type.
91 *
92 * @see event_class_t
93 */
95 public:
98 Event(ConfObject *obj, event_class_t *ev) : obj_(obj), ev_(ev) {
99 if (obj == nullptr) {
100 throw std::invalid_argument {
101 "Device object can't be NULL"
102 };
103 }
104
105 if (ev == nullptr) {
106 throw std::invalid_argument {
107 "Event is not registered yet. Call add() from the"
108 " device class"
109 };
110 }
111 }
112
113 // EventInterface
114 void destroy(void *data) override {}
115 attr_value_t get_value(void *data) override {
116 return SIM_make_attr_nil();
117 }
118 void *set_value(attr_value_t value) override {
119 return nullptr;
120 }
121 char *describe(void *data) const override {
122 return nullptr;
123 }
124
125 operator event_class_t *() const { return ev_; }
126
127 protected:
128 static int pointer_eq(void *data, void *match_data) {
129 return data == match_data;
130 }
131
134 template <typename T>
135 T *device_ptr() const {
136 static_assert(std::is_base_of<ConfObject, T>::value,
137 "T must be a descendant of ConfObject");
138 return static_cast<T *>(obj_);
139 }
140
141 const char *name() const {
142 return ev_->name;
143 }
144
145 ConfObject *obj_ {nullptr};
146 event_class_t *ev_ {nullptr};
150};
151
153template <typename T = ConfObject>
154class TimeEvent : public Event,
156 public:
157 using Event::Event;
158
159 // TimeEventInterface
160 bool posted(void *match_data = nullptr) const override {
161 return next(match_data) >= 0.0;
162 }
163
164 void remove(void *match_data = nullptr) const override {
165 if (clock_) {
166 SIM_event_cancel_time(clock_, ev_, obj_->obj(),
167 Event::pointer_eq, match_data);
168 }
169 }
170
171 void post(double seconds, void *data = nullptr) override {
172 if (clock_ == nullptr) {
174 clock_ = SIM_object_clock(obj_->obj());
175 if (clock_ == nullptr) {
176 SIM_LOG_ERROR(obj_->obj(), 0,
177 "Queue not set, unable to post events");
178 return;
179 }
180 }
181 SIM_event_post_time(clock_, ev_, obj_->obj(), seconds, data);
182 if (SIM_clear_exception() != SimExc_No_Exception) {
183 SIM_LOG_ERROR(obj_->obj(), 0, "%s", SIM_last_error());
184 }
185 }
186
187 double next(void *match_data = nullptr) const override {
188 if (clock_ == nullptr) {
189 return -1.0;
190 }
191 return SIM_event_find_next_time(clock_, ev_, obj_->obj(),
192 Event::pointer_eq, match_data);
193 }
194
195 protected:
196 T *dev_ {device_ptr<T>()};
197};
198
200template <typename T = ConfObject>
201class CycleEvent : public Event,
203 public:
204 using Event::Event;
205
206 // CycleEventInterface
207 bool posted(void *match_data = nullptr) const override {
208 return next(match_data) >= 0;
209 }
210
211 void remove(void *match_data = nullptr) const override {
212 if (clock_) {
213 // There is no SIM_event_cancel_cycle
214 SIM_event_cancel_time(clock_, ev_, obj_->obj(),
215 Event::pointer_eq, match_data);
216 }
217 }
218
219 void post(cycles_t cycles, void *data = nullptr) override {
220 if (clock_ == nullptr) {
222 clock_ = SIM_object_clock(obj_->obj());
223 }
224 SIM_event_post_cycle(clock_, ev_, obj_->obj(), cycles, data);
225 if (SIM_clear_exception() != SimExc_No_Exception) {
226 SIM_LOG_ERROR(obj_->obj(), 0, "%s", SIM_last_error());
227 }
228 }
229
230 cycles_t next(void *match_data = nullptr) const override {
231 if (clock_ == nullptr) {
232 return -1;
233 }
234 return SIM_event_find_next_cycle(clock_, ev_, obj_->obj(),
235 Event::pointer_eq, match_data);
236 }
237
238 protected:
239 T *dev_ {device_ptr<T>()};
240};
241
243template <typename T = ConfObject>
244class StepEvent : public Event,
246 public:
247 using Event::Event;
248
249 // StepEventInterface
250 bool posted(void *match_data = nullptr) const override {
251 return next(match_data) >= 0;
252 }
253
254 void remove(void *match_data = nullptr) const override {
255 if (clock_) {
256 SIM_event_cancel_step(clock_, ev_, obj_->obj(),
257 Event::pointer_eq, match_data);
258 }
259 }
260
261 void post(pc_step_t steps, void *data = nullptr) override {
262 if (clock_ == nullptr) {
264 clock_ = SIM_object_clock(obj_->obj());
265 }
266 SIM_event_post_step(clock_, ev_, obj_->obj(), steps, data);
267 if (SIM_clear_exception() != SimExc_No_Exception) {
268 SIM_LOG_ERROR(obj_->obj(), 0, "%s", SIM_last_error());
269 }
270 }
271
272 pc_step_t next(void *match_data = nullptr) const override {
273 if (clock_ == nullptr) {
274 return -1;
275 }
276 return SIM_event_find_next_step(clock_, ev_, obj_->obj(),
277 Event::pointer_eq, match_data);
278 }
279
280 protected:
281 T *dev_ {device_ptr<T>()};
282};
283
284} // namespace simics
285
286#endif
struct conf_object conf_object_t
Definition: bank-issue-callbacks-interface.h:23
A class inherited by a model class to support Simics configuration.
Definition: conf-object.h:114
ConfObjectRef obj() const
Return a ConfObjectRef represents this object.
Definition: conf-object.h:134
Cycle-based event type.
Definition: event.h:202
void post(cycles_t cycles, void *data=nullptr) override
Posts the event on the associated queue of the device.
Definition: event.h:219
T * dev_
Definition: event.h:239
cycles_t next(void *match_data=nullptr) const override
Returns the cycles to the next occurrence of the event in the queue (relative to the current time)
Definition: event.h:230
bool posted(void *match_data=nullptr) const override
Returns true if the event is in the queue, and false otherwise.
Definition: event.h:207
void remove(void *match_data=nullptr) const override
Removes all events of this type with matching data from the queue.
Definition: event.h:211
Definition: event.h:94
T * device_ptr() const
Definition: event.h:135
const char * name() const
Definition: event.h:141
void destroy(void *data) override
Called when the event is removed from the queue without being called.
Definition: event.h:114
conf_object_t * clock_
clock_ cannot be initialized here by SIM_object_clock, since attribute queue is not set yet
Definition: event.h:149
attr_value_t get_value(void *data) override
Called to convert the event data into a value that can be saved in a configuration.
Definition: event.h:115
void * set_value(attr_value_t value) override
Called to convert a configuration value into event data.
Definition: event.h:118
Event(ConfObject *obj, event_class_t *ev)
Definition: event.h:98
static int pointer_eq(void *data, void *match_data)
Definition: event.h:128
ConfObject * obj_
Definition: event.h:145
char * describe(void *data) const override
Called to generate a human-readable description of the event to be used in the print-event-queue comm...
Definition: event.h:121
event_class_t * ev_
Definition: event.h:146
Not commonly used for device model. Step-based event type.
Definition: event.h:245
void remove(void *match_data=nullptr) const override
Removes all events of this type with matching data from the queue.
Definition: event.h:254
pc_step_t next(void *match_data=nullptr) const override
Returns the steps to the next occurrence of the event in the queue (relative to the current time)
Definition: event.h:272
bool posted(void *match_data=nullptr) const override
Returns true if the event is in the queue, and false otherwise.
Definition: event.h:250
void post(pc_step_t steps, void *data=nullptr) override
Posts the event on the associated queue of the device.
Definition: event.h:261
T * dev_
Definition: event.h:281
Time-based event type.
Definition: event.h:155
void post(double seconds, void *data=nullptr) override
Posts the event on the associated queue of the device.
Definition: event.h:171
T * dev_
Definition: event.h:196
double next(void *match_data=nullptr) const override
Returns the time to the next occurrence of the event in the queue (relative to the current time)
Definition: event.h:187
bool posted(void *match_data=nullptr) const override
Returns true if the event is in the queue, and false otherwise.
Definition: event.h:160
void remove(void *match_data=nullptr) const override
Removes all events of this type with matching data from the queue.
Definition: event.h:164
Definition: event-interface.h:61
An event is required to implement the interface.
Definition: event-interface.h:29
Definition: event-interface.h:75
Definition: event-interface.h:47
Definition: attr-value.h:23
std::add_pointer_t< char *(conf_object_t *obj, void *data)> ev_describe
Definition: event.h:40
ev_callback ev_destroy
Definition: event.h:34
std::add_pointer_t< void *(conf_object_t *obj, attr_value_t value)> ev_value_setter
Definition: event.h:38
std::add_pointer_t< attr_value_t(conf_object_t *obj, void *data)> ev_value_getter
Definition: event.h:36
std::add_pointer_t< void(conf_object_t *, void *)> ev_callback
Definition: event.h:33
Definition: event.h:46
EventInfo(const std::string &name, event_class_flag_t flags, event_class_t **ev, ev_callback callback, ev_destroy destroy, ev_value_getter get_value, ev_value_setter set_value, ev_describe describe)
Definition: event.h:47
ev_describe describe_
Definition: event.h:85
EventInfo(const std::string &name, event_class_t **ev, ev_callback callback)
Definition: event.h:72
event_class_t ** ev_
Definition: event.h:80
ev_destroy destroy_
Definition: event.h:82
ev_value_setter set_value_
Definition: event.h:84
ev_callback callback_
Definition: event.h:81
std::string name_
Definition: event.h:78
ev_value_getter get_value_
Definition: event.h:83
event_class_flag_t flags_
Definition: event.h:79