Skip to content

Commit

Permalink
Add freethreading_compatible directive to set Py_mod_gil slot
Browse files Browse the repository at this point in the history
  • Loading branch information
lysnikolaou committed Jun 12, 2024
1 parent 50fb5cf commit 9272e60
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Cython/Compiler/ModuleNode.py
Original file line number Diff line number Diff line change
Expand Up @@ -3566,6 +3566,8 @@ def generate_pymoduledef_struct(self, env, code):
else:
cleanup_func = 'NULL'

freethreading_compatible = env.directives['freethreading_compatible']

code.putln("")
code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
exec_func_cname = self.module_init_func_cname()
Expand All @@ -3576,6 +3578,12 @@ def generate_pymoduledef_struct(self, env, code):
code.putln("static PyModuleDef_Slot %s[] = {" % Naming.pymoduledef_slots_cname)
code.putln("{Py_mod_create, (void*)%s}," % Naming.pymodule_create_func_cname)
code.putln("{Py_mod_exec, (void*)%s}," % exec_func_cname)
code.putln("#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING")
if freethreading_compatible:
code.putln("{Py_mod_gil, Py_MOD_GIL_NOT_USED},")
else:
code.putln("{Py_mod_gil, Py_MOD_GIL_USED},")
code.putln("#endif")
code.putln("{0, NULL}")
code.putln("};")
if not env.module_name.isascii():
Expand Down Expand Up @@ -3630,6 +3638,8 @@ def generate_module_creation_code(self, env, code):
else:
doc = "0"

freethreading_compatible = env.directives['freethreading_compatible']

code.putln("#if CYTHON_PEP489_MULTI_PHASE_INIT")
code.putln("%s = %s;" % (
env.module_cname,
Expand Down Expand Up @@ -3664,6 +3674,12 @@ def generate_module_creation_code(self, env, code):
env.module_cname,
Naming.pymoduledef_cname))
code.putln(code.error_goto_if_null(env.module_cname, self.pos))
code.putln("#endif") # CYTHON_USE_MODULE_STATE
code.putln("#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING")
if freethreading_compatible:
code.putln("PyUnstable_Module_SetGIL(%s, Py_MOD_GIL_NOT_USED);" % env.module_cname)
else:
code.putln("PyUnstable_Module_SetGIL(%s, Py_MOD_GIL_USED);" % env.module_cname)
code.putln("#endif")
code.putln("#endif") # CYTHON_PEP489_MULTI_PHASE_INIT
code.putln("CYTHON_UNUSED_VAR(%s);" % module_temp) # only used in limited API
Expand Down
2 changes: 2 additions & 0 deletions Cython/Compiler/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ def copy_inherited_directives(outer_directives, **new_directives):
'boundscheck' : True,
'nonecheck' : False,
'initializedcheck' : True,
'freethreading_compatible': False,
'embedsignature': False,
'embedsignature.format': 'c',
'auto_cpdef': False,
Expand Down Expand Up @@ -350,6 +351,7 @@ class DEFER_ANALYSIS_OF_ARGUMENTS:
'dataclasses.dataclass': DEFER_ANALYSIS_OF_ARGUMENTS,
'dataclasses.field': DEFER_ANALYSIS_OF_ARGUMENTS,
'embedsignature.format': one_of('c', 'clinic', 'python'),
'freethreading_compatible': bool,
}

for key, val in _directive_defaults.items():
Expand Down
40 changes: 40 additions & 0 deletions tests/run/freethreading_compatible.srctree
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
PYTHON setup.py build_ext --inplace
PYTHON -c "import default; default.test()"
PYTHON -c "import compatible; compatible.test()"
PYTHON -c "import incompatible; incompatible.test()"

######## setup.py ########

from Cython.Build.Dependencies import cythonize
from distutils.core import setup

ext_modules = []

# Test language_level specified in the cythonize() call
ext_modules += cythonize("default.py")
ext_modules += cythonize("compatible.py")
ext_modules += cythonize("incompatible.py")

setup(ext_modules=ext_modules)

######## default.py ########

def test():
import sys
assert sys._is_gil_enabled()

######## compatible.py ########

# cython: freethreading_compatible=True

def test():
import sys
assert not sys._is_gil_enabled()

######## incompatible.py ########

# cython: freethreading_compatible=False

def test():
import sys
assert sys._is_gil_enabled()

0 comments on commit 9272e60

Please sign in to comment.