2019-06-08 16:31:23 +02:00
|
|
|
/*
|
2021-01-04 20:54:53 +01:00
|
|
|
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
2019-06-08 16:31:23 +02:00
|
|
|
*
|
2021-01-04 20:54:53 +01:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2019-06-08 16:31:23 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "PyScModule.h"
|
|
|
|
#define PY_SSIZE_T_CLEAN
|
2021-02-05 11:34:24 +01:00
|
|
|
#include <Python.h>
|
2019-06-08 16:31:23 +02:00
|
|
|
|
|
|
|
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::invoke_callback(const char* callback_name) {
|
|
|
|
// acquiring the GIL
|
|
|
|
PyGILState_STATE gstate;
|
|
|
|
gstate = PyGILState_Ensure();
|
|
|
|
if(PyObject_HasAttrString(self, callback_name)){
|
|
|
|
auto* func = PyObject_GetAttrString(self, callback_name);
|
|
|
|
PyObject_CallFunctionObjArgs(func, nullptr);
|
|
|
|
}
|
|
|
|
// Release the thread. No Python API allowed beyond this point.
|
|
|
|
PyGILState_Release(gstate);
|
|
|
|
}
|