diff options
author | Brett Simmers <swtaarrs@users.noreply.github.com> | 2024-03-11 15:02:58 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-11 15:02:58 (GMT) |
commit | 2731913dd5234ff5ab630a3b7f1c98ad79d4d9df (patch) | |
tree | c666bae1112581bf0fe4c23ced8d188082cbcefd /Lib | |
parent | 546eb7a3be241c5abd8a83cebbbab8c71107edcf (diff) | |
download | cpython-2731913dd5234ff5ab630a3b7f1c98ad79d4d9df.zip cpython-2731913dd5234ff5ab630a3b7f1c98ad79d4d9df.tar.gz cpython-2731913dd5234ff5ab630a3b7f1c98ad79d4d9df.tar.bz2 |
gh-116167: Allow disabling the GIL with `PYTHON_GIL=0` or `-X gil=0` (#116338)
In free-threaded builds, running with `PYTHON_GIL=0` will now disable the
GIL. Follow-up issues track work to re-enable the GIL when loading an
incompatible extension, and to disable the GIL by default.
In order to support re-enabling the GIL at runtime, all GIL-related data
structures are initialized as usual, and disabling the GIL simply sets a flag
that causes `take_gil()` and `drop_gil()` to return early.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/subprocess.py | 2 | ||||
-rw-r--r-- | Lib/test/_test_embed_set_config.py | 14 | ||||
-rw-r--r-- | Lib/test/test_cmd_line.py | 33 | ||||
-rw-r--r-- | Lib/test/test_embed.py | 2 |
4 files changed, 50 insertions, 1 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 20db774..1437bf8 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -350,7 +350,7 @@ def _args_from_interpreter_flags(): if dev_mode: args.extend(('-X', 'dev')) for opt in ('faulthandler', 'tracemalloc', 'importtime', - 'frozen_modules', 'showrefcount', 'utf8'): + 'frozen_modules', 'showrefcount', 'utf8', 'gil'): if opt in xoptions: value = xoptions[opt] if value is True: diff --git a/Lib/test/_test_embed_set_config.py b/Lib/test/_test_embed_set_config.py index 75b6b7d..5ff5218 100644 --- a/Lib/test/_test_embed_set_config.py +++ b/Lib/test/_test_embed_set_config.py @@ -9,6 +9,7 @@ import _testinternalcapi import os import sys import unittest +from test import support from test.support import MS_WINDOWS @@ -211,6 +212,19 @@ class SetConfigTests(unittest.TestCase): self.set_config(use_hash_seed=1, hash_seed=123) self.assertEqual(sys.flags.hash_randomization, 1) + if support.Py_GIL_DISABLED: + self.set_config(enable_gil=-1) + self.assertEqual(sys.flags.gil, None) + self.set_config(enable_gil=0) + self.assertEqual(sys.flags.gil, 0) + self.set_config(enable_gil=1) + self.assertEqual(sys.flags.gil, 1) + else: + # Builds without Py_GIL_DISABLED don't have + # PyConfig.enable_gil. sys.flags.gil is always defined to 1, for + # consistency. + self.assertEqual(sys.flags.gil, 1) + def test_options(self): self.check(warnoptions=[]) self.check(warnoptions=["default", "ignore"]) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 6796dc6..c633f64 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -869,6 +869,39 @@ class CmdLineTest(unittest.TestCase): self.assertEqual(proc.stdout.rstrip(), 'True') self.assertEqual(proc.returncode, 0, proc) + @unittest.skipUnless(support.Py_GIL_DISABLED, + "PYTHON_GIL and -X gil only supported in Py_GIL_DISABLED builds") + def test_python_gil(self): + cases = [ + # (env, opt, expected, msg) + (None, None, 'None', "no options set"), + ('0', None, '0', "PYTHON_GIL=0"), + ('1', None, '1', "PYTHON_GIL=1"), + ('1', '0', '0', "-X gil=0 overrides PYTHON_GIL=1"), + (None, '0', '0', "-X gil=0"), + (None, '1', '1', "-X gil=1"), + ] + + code = "import sys; print(sys.flags.gil)" + environ = dict(os.environ) + + for env, opt, expected, msg in cases: + with self.subTest(msg, env=env, opt=opt): + environ.pop('PYTHON_GIL', None) + if env is not None: + environ['PYTHON_GIL'] = env + extra_args = [] + if opt is not None: + extra_args = ['-X', f'gil={opt}'] + + proc = subprocess.run([sys.executable, *extra_args, '-c', code], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, env=environ) + self.assertEqual(proc.returncode, 0, proc) + self.assertEqual(proc.stdout.rstrip(), expected) + self.assertEqual(proc.stderr, '') + @unittest.skipUnless(sys.platform == 'win32', 'bpo-32457 only applies on Windows') def test_argv0_normalization(self): diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 55d3acf..ab1d579 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -523,6 +523,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): CONFIG_COMPAT['_pystats'] = 0 if support.Py_DEBUG: CONFIG_COMPAT['run_presite'] = None + if support.Py_GIL_DISABLED: + CONFIG_COMPAT['enable_gil'] = -1 if MS_WINDOWS: CONFIG_COMPAT.update({ 'legacy_windows_stdio': 0, |