-
Notifications
You must be signed in to change notification settings - Fork 6
/
PyScModule.cpp
138 lines (117 loc) · 3.9 KB
/
PyScModule.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#define SC_INCLUDE_DYNAMIC_PROCESSES
#include "PyScModule.h"
#define PY_SSIZE_T_CLEAN
#include <Python.h>
class TPyScriptThreadLocker {
PyGILState_STATE m_state;
public:
TPyScriptThreadLocker(): m_state(PyGILState_Ensure()) {}
~TPyScriptThreadLocker() { PyGILState_Release(m_state); }
};
scc::PyScModule::PyScModule(PyObject* self, const sc_core::sc_module_name& nm)
: sc_core::sc_module(nm)
, self(self)
{
if (! PyEval_ThreadsInitialized())
PyEval_InitThreads();
Py_INCREF(self);
}
scc::PyScModule::~PyScModule() {
Py_DECREF(self);
}
void scc::PyScModule::before_end_of_elaboration(){
invoke_callback("BeforeEndOfElaboration");
}
void scc::PyScModule::end_of_elaboration(){
invoke_callback("EndOfElaboration");
}
void scc::PyScModule::start_of_simulation(){
invoke_callback("StartOfSimulation");
}
void scc::PyScModule::end_of_simulation(){
invoke_callback("EndOfSimulation");
}
void scc::PyScModule::ScThread(std::string fname) {
sc_core::sc_spawn_options opts;
auto run_handle = sc_core::sc_spawn([this, fname](){
invoke_callback(fname);
}, nullptr, &opts);
this->sensitive << run_handle;
this->sensitive_pos << run_handle;
this->sensitive_neg << run_handle;
}
void scc::PyScModule::invoke_callback(std::string const& callback_name) {
if(PyObject_HasAttrString(self, callback_name.c_str())){
// acquiring the GIL
gstate = PyGILState_Ensure();
auto* func = PyObject_GetAttrString(self, callback_name.c_str());
PyObject_CallFunctionObjArgs(func, nullptr);
// Release the thread. No Python API allowed beyond this point.
PyGILState_Release(gstate);
}
}
void scc::PyScModule::ScWait() {
PyGILState_Release(gstate);
sc_core::sc_module::wait();
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(const sc_core::sc_event& e){
PyGILState_Release(gstate);
sc_core::sc_module::wait(e);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(const sc_core::sc_event_or_list &el) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(el);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(const sc_core::sc_event_and_list &el) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(el);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(const sc_core::sc_time &t) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(t);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(double v, sc_core::sc_time_unit tu) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(v, tu);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(const sc_core::sc_time &t, const sc_core::sc_event &e) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(t, e);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(double v, sc_core::sc_time_unit tu, const sc_core::sc_event &e) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(v, tu, e);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(const sc_core::sc_time &t, const sc_core::sc_event_or_list &el) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(t, el);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(double v, sc_core::sc_time_unit tu, const sc_core::sc_event_or_list &el) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(v, tu, el);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(const sc_core::sc_time &t, const sc_core::sc_event_and_list &el) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(t, el);
gstate = PyGILState_Ensure();
}
void scc::PyScModule::ScWait(double v, sc_core::sc_time_unit tu, const sc_core::sc_event_and_list &el) {
PyGILState_Release(gstate);
sc_core::sc_module::wait(v, tu, el);
gstate = PyGILState_Ensure();
}