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/sim-exception.h> // SIM_clear_exception
21#include <simics/base/time.h> // SIM_object_clock
22
23#include <stdexcept>
24#include <string>
25#include <type_traits> // add_pointer_t
26
27#include "simics/conf-object.h"
30#include "simics/log.h"
31
32namespace simics {
33
34using ev_callback = std::add_pointer_t<void(conf_object_t *, void *)>;
36using ev_value_getter = std::add_pointer_t<attr_value_t(conf_object_t *obj,
37 void *data)>;
38using ev_value_setter = std::add_pointer_t<void *(conf_object_t *obj,
39 attr_value_t value)>;
40using ev_describe = std::add_pointer_t<char *(conf_object_t *obj,
41 void *data)>;
42
43/*
44 * Class provides information for event registration
45 * @see ConfClass *add(EventInfo &&event)
46 */
47struct EventInfo {
48 EventInfo(const std::string &name, event_class_flag_t flags,
49 event_class_t **ev, ev_callback callback, ev_destroy destroy,
52 EventInfo(const std::string &name, event_class_t **ev,
54
55 std::string name;
56 event_class_flag_t flags;
57 event_class_t **ev {nullptr};
63};
64
79class Event : public EventInterface {
80 public:
85 Event(ConfObject *obj, event_class_t *ev);
87 Event(ConfObject *obj, const std::string &name);
88
89 // EventInterface
90 void destroy(void *data) override;
91 attr_value_t get_value(void *data) override;
92 void *set_value(attr_value_t value) override;
93 char *describe(void *data) const override;
94
95 operator event_class_t *() const;
96
97 protected:
98 static int pointer_eq(void *data, void *match_data);
99
102 template <typename T> T *device_ptr() const {
103 static_assert(std::is_base_of<ConfObject, T>::value,
104 "T must be a descendant of ConfObject");
105 return static_cast<T *>(obj_);
106 }
107
108 const char *name() const;
109
110 ConfObject *obj_ {nullptr};
111 event_class_t *ev_ {nullptr};
114 conf_object_t *clock_ {nullptr};
115};
116
118template <typename T = ConfObject>
119class TimeEvent : public Event,
120 public TimeEventInterface {
121 public:
122 using Event::Event;
123
124 // TimeEventInterface
125 bool posted(void *match_data = nullptr) const override {
126 return next(match_data) >= 0.0;
127 }
128
129 void remove(void *match_data = nullptr) const override {
130 if (clock_) {
131 SIM_event_cancel_time(clock_, ev_, obj_->obj(),
132 Event::pointer_eq, match_data);
133 }
134 }
135
136 void post(double seconds, void *data = nullptr) override {
137 if (clock_ == nullptr) {
139 clock_ = SIM_object_clock(obj_->obj());
140 if (clock_ == nullptr) {
141 SIM_LOG_ERROR(obj_->obj(), 0,
142 "Queue not set, unable to post events");
143 return;
144 }
145 }
146 SIM_event_post_time(clock_, ev_, obj_->obj(), seconds, data);
147 if (SIM_clear_exception() != SimExc_No_Exception) {
148 SIM_LOG_ERROR(obj_->obj(), 0, "%s", SIM_last_error());
149 }
150 }
151
152 double next(void *match_data = nullptr) const override {
153 if (clock_ == nullptr) {
154 return -1.0;
155 }
156 return SIM_event_find_next_time(clock_, ev_, obj_->obj(),
157 Event::pointer_eq, match_data);
158 }
159
160 protected:
161 T *dev_ {device_ptr<T>()};
162};
163
165template <typename T = ConfObject>
166class CycleEvent : public Event,
167 public CycleEventInterface {
168 public:
169 using Event::Event;
170
171 // CycleEventInterface
172 bool posted(void *match_data = nullptr) const override {
173 return next(match_data) >= 0;
174 }
175
176 void remove(void *match_data = nullptr) const override {
177 if (clock_) {
178 // There is no SIM_event_cancel_cycle
179 SIM_event_cancel_time(clock_, ev_, obj_->obj(),
180 Event::pointer_eq, match_data);
181 }
182 }
183
184 void post(cycles_t cycles, void *data = nullptr) override {
185 if (clock_ == nullptr) {
187 clock_ = SIM_object_clock(obj_->obj());
188 }
189 SIM_event_post_cycle(clock_, ev_, obj_->obj(), cycles, data);
190 if (SIM_clear_exception() != SimExc_No_Exception) {
191 SIM_LOG_ERROR(obj_->obj(), 0, "%s", SIM_last_error());
192 }
193 }
194
195 cycles_t next(void *match_data = nullptr) const override {
196 if (clock_ == nullptr) {
197 return -1;
198 }
199 return SIM_event_find_next_cycle(clock_, ev_, obj_->obj(),
200 Event::pointer_eq, match_data);
201 }
202
203 protected:
204 T *dev_ {device_ptr<T>()};
205};
206
208template <typename T = ConfObject>
209class StepEvent : public Event,
210 public StepEventInterface {
211 public:
212 using Event::Event;
213
214 // StepEventInterface
215 bool posted(void *match_data = nullptr) const override {
216 return next(match_data) >= 0;
217 }
218
219 void remove(void *match_data = nullptr) const override {
220 if (clock_) {
221 SIM_event_cancel_step(clock_, ev_, obj_->obj(),
222 Event::pointer_eq, match_data);
223 }
224 }
225
226 void post(pc_step_t steps, void *data = nullptr) override {
227 if (clock_ == nullptr) {
229 clock_ = SIM_object_clock(obj_->obj());
230 }
231 SIM_event_post_step(clock_, ev_, obj_->obj(), steps, data);
232 if (SIM_clear_exception() != SimExc_No_Exception) {
233 SIM_LOG_ERROR(obj_->obj(), 0, "%s", SIM_last_error());
234 }
235 }
236
237 pc_step_t next(void *match_data = nullptr) const override {
238 if (clock_ == nullptr) {
239 return -1;
240 }
241 return SIM_event_find_next_step(clock_, ev_, obj_->obj(),
242 Event::pointer_eq, match_data);
243 }
244
245 protected:
246 T *dev_ {device_ptr<T>()};
247};
248
249} // namespace simics
250
251#endif
Base class for all Simics configuration objects.
Definition: conf-object.h:126
ConfObjectRef obj() const
Return a ConfObjectRef represents this object.
Definition: conf-object.h:137
Definition: event-interface.h:61
Cycle-based event type.
Definition: event.h:167
void post(cycles_t cycles, void *data=nullptr) override
Posts the event on the associated queue of the device.
Definition: event.h:184
T * dev_
Definition: event.h:204
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:195
bool posted(void *match_data=nullptr) const override
Returns true if the event is in the queue, and false otherwise.
Definition: event.h:172
void remove(void *match_data=nullptr) const override
Removes all events of this type with matching data from the queue.
Definition: event.h:176
An event is required to implement the interface.
Definition: event-interface.h:29
The Event class allows users to define callbacks that will be executed after a specified delay.
Definition: event.h:79
Event(ConfObject *obj, const std::string &name)
T * device_ptr() const
Definition: event.h:102
const char * name() const
void destroy(void *data) override
Called when the event is removed from the queue without being called.
conf_object_t * clock_
clock_ cannot be initialized here by SIM_object_clock, since attribute queue is not set yet
Definition: event.h:114
attr_value_t get_value(void *data) override
Called to convert the event data into a value that can be saved in a configuration.
void * set_value(attr_value_t value) override
Called to convert a configuration value into event data.
Event(ConfObject *obj, event_class_t *ev)
static int pointer_eq(void *data, void *match_data)
ConfObject * obj_
Definition: event.h:110
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...
event_class_t * ev_
Definition: event.h:111
Definition: event-interface.h:75
Not commonly used for device model. Step-based event type.
Definition: event.h:210
void remove(void *match_data=nullptr) const override
Removes all events of this type with matching data from the queue.
Definition: event.h:219
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:237
bool posted(void *match_data=nullptr) const override
Returns true if the event is in the queue, and false otherwise.
Definition: event.h:215
void post(pc_step_t steps, void *data=nullptr) override
Posts the event on the associated queue of the device.
Definition: event.h:226
T * dev_
Definition: event.h:246
Definition: event-interface.h:47
Time-based event type.
Definition: event.h:120
void post(double seconds, void *data=nullptr) override
Posts the event on the associated queue of the device.
Definition: event.h:136
T * dev_
Definition: event.h:161
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:152
bool posted(void *match_data=nullptr) const override
Returns true if the event is in the queue, and false otherwise.
Definition: event.h:125
void remove(void *match_data=nullptr) const override
Removes all events of this type with matching data from the queue.
Definition: event.h:129
Definition: after-bank.h:33
std::add_pointer_t< char *(conf_object_t *obj, void *data)> ev_describe
Definition: event.h:41
ev_callback ev_destroy
Definition: event.h:35
std::add_pointer_t< void *(conf_object_t *obj, attr_value_t value)> ev_value_setter
Definition: event.h:39
std::add_pointer_t< attr_value_t(conf_object_t *obj, void *data)> ev_value_getter
Definition: event.h:37
std::add_pointer_t< void(conf_object_t *, void *)> ev_callback
Definition: event.h:34
Definition: event.h:47
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)
event_class_t ** ev
Definition: event.h:57
EventInfo(const std::string &name, event_class_t **ev, ev_callback callback)
ev_value_getter get_value
Definition: event.h:60
ev_callback callback
Definition: event.h:58
event_class_flag_t flags
Definition: event.h:56
ev_describe describe
Definition: event.h:62
ev_destroy destroy
Definition: event.h:59
ev_value_setter set_value
Definition: event.h:61
std::string name
Definition: event.h:55