rogue
Loading...
Searching...
No Matches
Slave.cpp
Go to the documentation of this file.
1
17#include "rogue/Directives.h"
18
20
21#include <memory>
22#include <string>
23
24#include "rogue/GeneralError.h"
25#include "rogue/GilRelease.h"
26#include "rogue/ScopedGil.h"
30
31#ifndef NO_PYTHON
32 #include <boost/python.hpp>
33namespace bp = boost::python;
34#endif
35
37
38// Init class counter
39uint32_t rim::Slave::classIdx_ = 0;
40
42std::mutex rim::Slave::classMtx_;
43
45rim::SlavePtr rim::Slave::create(uint32_t min, uint32_t max) {
46 rim::SlavePtr s = std::make_shared<rim::Slave>(min, max);
47 return (s);
48}
49
51rim::Slave::Slave(uint32_t min, uint32_t max) {
52 min_ = min;
53 max_ = max;
54
55 classMtx_.lock();
56 if (classIdx_ == 0) classIdx_ = 1;
57 id_ = classIdx_;
58 classIdx_++;
59 classMtx_.unlock();
60
61 name_ = std::string("Unnamed_") + std::to_string(id_);
62}
63
65rim::Slave::~Slave() {}
66
68void rim::Slave::stop() {}
69
71void rim::Slave::addTransaction(rim::TransactionPtr tran) {
73 std::lock_guard<std::mutex> lock(slaveMtx_);
74 tranMap_[tran->id()] = tran;
75}
76
78rim::TransactionPtr rim::Slave::getTransaction(uint32_t index) {
80 TransactionMap::iterator it;
81 TransactionMap::iterator exp;
82
84 std::lock_guard<std::mutex> lock(slaveMtx_);
85
86 if ((it = tranMap_.find(index)) != tranMap_.end()) {
87 ret = it->second;
88
89 // Remove from list
90 tranMap_.erase(it);
91
92 // Update any timers for transactions started after received transaction
93 exp = tranMap_.end();
94 for (it = tranMap_.begin(); it != tranMap_.end(); ++it) {
95 if (it->second->expired())
96 exp = it;
97 else
98 it->second->refreshTimer(ret);
99 }
100
101 // Clean up if we found an expired transaction, overtime this will clean up
102 // the list, even if it deletes one expired transaction per call
103 if (exp != tranMap_.end()) {
104 tranMap_.erase(exp);
105 }
106 }
107 return ret;
108}
109
111uint32_t rim::Slave::min() {
112 return min_;
113}
114
116uint32_t rim::Slave::max() {
117 return max_;
118}
119
121uint32_t rim::Slave::id() {
122 return id_;
123}
124
126std::string rim::Slave::name() {
127 return name_;
128}
129
131void rim::Slave::setName(std::string name) {
132 name_ = name;
133}
134
136uint32_t rim::Slave::doSlaveId() {
137 return (id());
138}
139
141std::string rim::Slave::doSlaveName() {
142 return (name());
143}
144
146uint32_t rim::Slave::doMinAccess() {
147 return (min());
148}
149
151uint32_t rim::Slave::doMaxAccess() {
152 return (max());
153}
154
156uint64_t rim::Slave::doAddress() {
157 return (0);
158}
159
161void rim::Slave::doTransaction(rim::TransactionPtr transaction) {
162 transaction->error("Unsupported transaction using unconnected memory bus");
163}
164
165void rim::Slave::setup_python() {
166#ifndef NO_PYTHON
167 bp::class_<rim::SlaveWrap, rim::SlaveWrapPtr, boost::noncopyable>("Slave", bp::init<uint32_t, uint32_t>())
168 .def("setName", &rim::Slave::setName)
169 .def("_addTransaction", &rim::Slave::addTransaction)
170 .def("_getTransaction", &rim::Slave::getTransaction)
171 .def("_doMinAccess", &rim::Slave::doMinAccess, &rim::SlaveWrap::defDoMinAccess)
172 .def("_doMaxAccess", &rim::Slave::doMaxAccess, &rim::SlaveWrap::defDoMaxAccess)
173 .def("_doAddress", &rim::Slave::doAddress, &rim::SlaveWrap::defDoAddress)
174 .def("_doTransaction", &rim::Slave::doTransaction, &rim::SlaveWrap::defDoTransaction)
175 .def("__lshift__", &rim::Slave::lshiftPy)
176 .def("_stop", &rim::Slave::stop);
177#endif
178}
179
180#ifndef NO_PYTHON
181
183rim::SlaveWrap::SlaveWrap(uint32_t min, uint32_t max) : rim::Slave(min, max) {}
184
186uint32_t rim::SlaveWrap::doMinAccess() {
187 {
189
190 if (boost::python::override pb = this->get_override("_doMinAccess")) {
191 try {
192 return (pb());
193 } catch (...) {
194 PyErr_Print();
195 }
196 }
197 }
198 return (rim::Slave::doMinAccess());
199}
200
202uint32_t rim::SlaveWrap::defDoMinAccess() {
203 return (rim::Slave::doMinAccess());
204}
205
207uint32_t rim::SlaveWrap::doMaxAccess() {
208 {
210
211 if (boost::python::override pb = this->get_override("_doMaxAccess")) {
212 try {
213 return (pb());
214 } catch (...) {
215 PyErr_Print();
216 }
217 }
218 }
219 return (rim::Slave::doMaxAccess());
220}
221
223uint32_t rim::SlaveWrap::defDoMaxAccess() {
224 return (rim::Slave::doMinAccess());
225}
226
228uint64_t rim::SlaveWrap::doAddress() {
229 {
231
232 if (boost::python::override pb = this->get_override("_doAddress")) {
233 try {
234 return (pb());
235 } catch (...) {
236 PyErr_Print();
237 }
238 }
239 }
240 return (rim::Slave::doAddress());
241}
242
244uint64_t rim::SlaveWrap::defDoAddress() {
245 return (rim::Slave::doAddress());
246}
247
249void rim::SlaveWrap::doTransaction(rim::TransactionPtr transaction) {
250 {
252
253 if (boost::python::override pb = this->get_override("_doTransaction")) {
254 try {
255 pb(transaction);
256 return;
257 } catch (...) {
258 PyErr_Print();
259 }
260 }
261 }
262 rim::Slave::doTransaction(transaction);
263}
264
266void rim::SlaveWrap::defDoTransaction(rim::TransactionPtr transaction) {
267 rim::Slave::doTransaction(transaction);
268}
269
270void rim::Slave::lshiftPy(boost::python::object p) {
271 rim::MasterPtr mst;
272
273 // First Attempt to access object as a memory master
274 boost::python::extract<rim::MasterPtr> get_master(p);
275
276 // Test extraction
277 if (get_master.check()) {
278 mst = get_master();
279
280 // Otherwise look for indirect call
281 } else if (PyObject_HasAttrString(p.ptr(), "_getMemoryMaster")) {
282 // Attempt to convert returned object to master pointer
283 boost::python::extract<rim::MasterPtr> get_master(p.attr("_getMemoryMaster")());
284
285 // Test extraction
286 if (get_master.check()) mst = get_master();
287 }
288
289 // Success
290 if (mst != NULL)
291 mst->setSlave(shared_from_this());
292 else
293 throw(rogue::GeneralError::create("memory::Slave::lshiftPy",
294 "Attempt to use << operator with incompatible memory master"));
295}
296
297#endif
298
300rim::MasterPtr& rim::Slave::operator<<(rim::MasterPtr& other) {
301 other->setSlave(shared_from_this());
302 return other;
303}
static GeneralError create(std::string src, const char *fmt,...)
Creates a formatted error instance.
RAII helper that releases the Python GIL for a scope.
Definition GilRelease.h:36
RAII helper that acquires the Python GIL for a scope.
Definition ScopedGil.h:35
Memory slave device.
Definition Slave.h:54
uint32_t max()
Returns configured maximum transaction size.
Definition Slave.cpp:116
uint32_t min()
Returns configured minimum transaction size.
Definition Slave.cpp:111
std::shared_ptr< rogue::interfaces::memory::Slave > SlavePtr
Shared pointer alias for Slave.
Definition Slave.h:310
std::shared_ptr< rogue::interfaces::memory::Master > MasterPtr
Shared pointer alias for Master.
Definition Master.h:410
std::shared_ptr< rogue::interfaces::memory::Transaction > TransactionPtr
Shared pointer alias for Transaction.