Skip to content

Commit 47d2c4a

Browse files
committed
Call threading functions in C
1 parent 00e1eab commit 47d2c4a

6 files changed

Lines changed: 38 additions & 30 deletions

File tree

scorep/_instrumenters/scorep_cProfile.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,3 @@ class ScorepCProfile(scorep._bindings.CInstrumenter, ScorepInstrumenter):
66
def __init__(self, enable_instrumenter):
77
scorep._bindings.CInstrumenter.__init__(self, interface='Profile')
88
ScorepInstrumenter.__init__(self, enable_instrumenter)
9-
10-
def _enable_instrumenter(self):
11-
if self._threading:
12-
self._threading.setprofile(self)
13-
super()._enable_instrumenter()
14-
15-
def _disable_instrumenter(self):
16-
super()._disable_instrumenter()
17-
if self._threading:
18-
self._threading.setprofile(None)

scorep/_instrumenters/scorep_cTrace.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,3 @@ class ScorepCTrace(scorep._bindings.CInstrumenter, ScorepInstrumenter):
66
def __init__(self, enable_instrumenter):
77
scorep._bindings.CInstrumenter.__init__(self, interface='Trace')
88
ScorepInstrumenter.__init__(self, enable_instrumenter)
9-
10-
def _enable_instrumenter(self):
11-
if self._threading:
12-
self._threading.settrace(self)
13-
super()._enable_instrumenter()
14-
15-
def _disable_instrumenter(self):
16-
super()._disable_instrumenter()
17-
if self._threading:
18-
self._threading.settrace(None)

scorep/_instrumenters/scorep_instrumenter.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@ def __init__(self, enable_instrumenter=True):
1515
"""
1616
self._tracer_registered = False
1717
self._enabled = enable_instrumenter
18-
# TODO: Support other threading libs, e.g. greenlet?
19-
try:
20-
import threading
21-
self._threading = threading
22-
except ImportError:
23-
self._threading = None
2418

2519
@abc.abstractmethod
2620
def _enable_instrumenter(self):

src/classes.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ extern "C"
2424
return PyBaseObject_Type.tp_new(type, empty_tuple, empty_dict);
2525
}
2626

27+
static void CInstrumenter_dealloc(scorepy::CInstrumenter* self)
28+
{
29+
self->deinit();
30+
Py_TYPE(self)->tp_free(self->to_PyObject());
31+
}
32+
2733
static int CInstrumenter_init(scorepy::CInstrumenter* self, PyObject* args, PyObject* kwds)
2834
{
2935
static const char* kwlist[] = { "interface", nullptr };
@@ -110,6 +116,7 @@ PyTypeObject& getCInstrumenterType()
110116
};
111117
type.tp_new = call_object_new;
112118
type.tp_init = scorepy::cast_to_PyFunc(CInstrumenter_init);
119+
type.tp_dealloc = scorepy::cast_to_PyFunc(CInstrumenter_dealloc);
113120
type.tp_methods = methods;
114121
type.tp_call = scorepy::cast_to_PyFunc(CInstrumenter_call);
115122
type.tp_getset = getseters;

src/scorepy/cInstrumenter.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,33 @@
88
namespace scorepy
99
{
1010

11+
void CInstrumenter::init(InstrumenterInterface interface)
12+
{
13+
this->interface = interface;
14+
threading_module = PyImport_ImportModule("threading");
15+
if (threading_module)
16+
{
17+
const char* name = (interface == InstrumenterInterface::Trace) ? "settrace" : "setprofile";
18+
threading_set_instrumenter = PyObject_GetAttrString(threading_module, name);
19+
}
20+
}
21+
22+
void CInstrumenter::deinit()
23+
{
24+
Py_CLEAR(threading_module);
25+
Py_CLEAR(threading_set_instrumenter);
26+
}
27+
1128
void CInstrumenter::enable_instrumenter()
1229
{
1330
const auto callback = [](PyObject* obj, PyFrameObject* frame, int what, PyObject* arg) -> int {
1431
return from_PyObject(obj)->on_event(*frame, what, arg) ? 0 : -1;
1532
};
33+
if (threading_set_instrumenter)
34+
{
35+
PyRefObject result(PyObject_CallFunction(threading_set_instrumenter, "O", to_PyObject()),
36+
adopt_object);
37+
}
1638
if (interface == InstrumenterInterface::Trace)
1739
PyEval_SetTrace(callback, to_PyObject());
1840
else
@@ -25,6 +47,11 @@ void CInstrumenter::disable_instrumenter()
2547
PyEval_SetTrace(nullptr, nullptr);
2648
else
2749
PyEval_SetProfile(nullptr, nullptr);
50+
if (threading_set_instrumenter)
51+
{
52+
PyRefObject result(PyObject_CallFunction(threading_set_instrumenter, "O", Py_None),
53+
adopt_object);
54+
}
2855
}
2956

3057
/// Mapping of PyTrace_* to it's string representations

src/scorepy/cInstrumenter.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ struct CInstrumenter
1717
{
1818
PyObject_HEAD;
1919
InstrumenterInterface interface;
20+
PyObject* threading_module;
21+
PyObject* threading_set_instrumenter;
2022

21-
void init(InstrumenterInterface interface)
22-
{
23-
this->interface = interface;
24-
}
23+
void init(InstrumenterInterface interface);
24+
void deinit();
2525
void enable_instrumenter();
2626
void disable_instrumenter();
2727

0 commit comments

Comments
 (0)