cross_module_gil_utils.cpp
Go to the documentation of this file.
1 /*
2  tests/cross_module_gil_utils.cpp -- tools for acquiring GIL from a different module
3 
4  Copyright (c) 2019 Google LLC
5 
6  All rights reserved. Use of this source code is governed by a
7  BSD-style license that can be found in the LICENSE file.
8 */
9 #if defined(PYBIND11_INTERNALS_VERSION)
10 # undef PYBIND11_INTERNALS_VERSION
11 #endif
12 #define PYBIND11_INTERNALS_VERSION 21814642 // Ensure this module has its own `internals` instance.
13 #include <pybind11/pybind11.h>
14 
15 #include <cstdint>
16 #include <string>
17 #include <thread>
18 
19 // This file mimics a DSO that makes pybind11 calls but does not define a
20 // PYBIND11_MODULE. The purpose is to test that such a DSO can create a
21 // py::gil_scoped_acquire when the running thread is in a GIL-released state.
22 //
23 // Note that we define a Python module here for convenience, but in general
24 // this need not be the case. The typical scenario would be a DSO that implements
25 // shared logic used internally by multiple pybind11 modules.
26 
27 namespace {
28 
29 namespace py = pybind11;
30 
31 void gil_acquire() { py::gil_scoped_acquire gil; }
32 
33 std::string gil_multi_acquire_release(unsigned bits) {
34  if ((bits & 0x1u) != 0u) {
35  py::gil_scoped_acquire gil;
36  }
37  if ((bits & 0x2u) != 0u) {
38  py::gil_scoped_release gil;
39  }
40  if ((bits & 0x4u) != 0u) {
41  py::gil_scoped_acquire gil;
42  }
43  if ((bits & 0x8u) != 0u) {
44  py::gil_scoped_release gil;
45  }
46  return PYBIND11_INTERNALS_ID;
47 }
48 
49 struct CustomAutoGIL {
50  CustomAutoGIL() : gstate(PyGILState_Ensure()) {}
51  ~CustomAutoGIL() { PyGILState_Release(gstate); }
52 
53  PyGILState_STATE gstate;
54 };
55 struct CustomAutoNoGIL {
56  CustomAutoNoGIL() : save(PyEval_SaveThread()) {}
57  ~CustomAutoNoGIL() { PyEval_RestoreThread(save); }
58 
59  PyThreadState *save;
60 };
61 
62 template <typename Acquire, typename Release>
63 void gil_acquire_inner() {
64  Acquire acquire_outer;
65  Acquire acquire_inner;
66  Release release;
67 }
68 
69 template <typename Acquire, typename Release>
70 void gil_acquire_nested() {
71  Acquire acquire_outer;
72  Acquire acquire_inner;
73  Release release;
74  auto thread = std::thread(&gil_acquire_inner<Acquire, Release>);
75  thread.join();
76 }
77 
78 constexpr char kModuleName[] = "cross_module_gil_utils";
79 
80 struct PyModuleDef moduledef = {
81  PyModuleDef_HEAD_INIT, kModuleName, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr};
82 
83 } // namespace
84 
85 #define ADD_FUNCTION(Name, ...) \
86  PyModule_AddObject(m, Name, PyLong_FromVoidPtr(reinterpret_cast<void *>(&__VA_ARGS__)));
87 
89 
90  PyObject *m = PyModule_Create(&moduledef);
91 
92  if (m != nullptr) {
93  static_assert(sizeof(&gil_acquire) == sizeof(void *),
94  "Function pointer must have the same size as void*");
95  ADD_FUNCTION("gil_acquire_funcaddr", gil_acquire)
96  ADD_FUNCTION("gil_multi_acquire_release_funcaddr", gil_multi_acquire_release)
97  ADD_FUNCTION("gil_acquire_inner_custom_funcaddr",
98  gil_acquire_inner<CustomAutoGIL, CustomAutoNoGIL>)
99  ADD_FUNCTION("gil_acquire_nested_custom_funcaddr",
100  gil_acquire_nested<CustomAutoGIL, CustomAutoNoGIL>)
101  ADD_FUNCTION("gil_acquire_inner_pybind11_funcaddr",
102  gil_acquire_inner<py::gil_scoped_acquire, py::gil_scoped_release>)
103  ADD_FUNCTION("gil_acquire_nested_pybind11_funcaddr",
104  gil_acquire_nested<py::gil_scoped_acquire, py::gil_scoped_release>)
105  }
106 
107  return m;
108 }
libsize.save
save
Definition: libsize.py:13
Eigen::internal::bits
Map< const Array< unsigned char, sizeof(T), 1 > > bits(const T &x)
Definition: packetmath_test_shared.h:28
PyInit_cross_module_gil_utils
PYBIND11_EXPORT PyObject * PyInit_cross_module_gil_utils()
Definition: cross_module_gil_utils.cpp:88
conf.release
release
Definition: gtsam/3rdparty/GeographicLib/python/doc/conf.py:69
PYBIND11_INTERNALS_ID
#define PYBIND11_INTERNALS_ID
Definition: internals.h:310
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
pybind11.h
PYBIND11_EXPORT
#define PYBIND11_EXPORT
Definition: wrap/pybind11/include/pybind11/detail/common.h:155
pybind11
Definition: wrap/pybind11/pybind11/__init__.py:1
ADD_FUNCTION
#define ADD_FUNCTION(Name,...)
Definition: cross_module_gil_utils.cpp:85


gtsam
Author(s):
autogenerated on Tue Jun 25 2024 03:00:42