Add also test.support.Py_GIL_DISABLED constant.
return any(option in cflags_nodist for option in pgo_options)
-if sysconfig.get_config_var('Py_GIL_DISABLED'):
+Py_GIL_DISABLED = bool(sysconfig.get_config_var('Py_GIL_DISABLED'))
+if Py_GIL_DISABLED:
_header = 'PHBBInP'
else:
_header = 'nP'
self.assertIn("_FOR_ITER_TIER_TWO", uops)
+@unittest.skipUnless(support.Py_GIL_DISABLED, 'need Py_GIL_DISABLED')
+class TestPyThreadId(unittest.TestCase):
+ def test_py_thread_id(self):
+ # gh-112535: Test _Py_ThreadId(): make sure that thread identifiers
+ # in a few threads are unique
+ py_thread_id = _testinternalcapi.py_thread_id
+ short_sleep = 0.010
+
+ class GetThreadId(threading.Thread):
+ def __init__(self):
+ super().__init__()
+ self.get_lock = threading.Lock()
+ self.get_lock.acquire()
+ self.started_lock = threading.Event()
+ self.py_tid = None
+
+ def run(self):
+ self.started_lock.set()
+ self.get_lock.acquire()
+ self.py_tid = py_thread_id()
+ time.sleep(short_sleep)
+ self.py_tid2 = py_thread_id()
+
+ nthread = 5
+ threads = [GetThreadId() for _ in range(nthread)]
+
+ # first make run sure that all threads are running
+ for thread in threads:
+ thread.start()
+ for thread in threads:
+ thread.started_lock.wait()
+
+ # call _Py_ThreadId() in the main thread
+ py_thread_ids = [py_thread_id()]
+
+ # now call _Py_ThreadId() in each thread
+ for thread in threads:
+ thread.get_lock.release()
+
+ # call _Py_ThreadId() in each thread and wait until threads complete
+ for thread in threads:
+ thread.join()
+ py_thread_ids.append(thread.py_tid)
+ # _PyThread_Id() should not change for a given thread.
+ # For example, it should remain the same after a short sleep.
+ self.assertEqual(thread.py_tid2, thread.py_tid)
+
+ # make sure that all _Py_ThreadId() are unique
+ for tid in py_thread_ids:
+ self.assertIsInstance(tid, int)
+ self.assertGreater(tid, 0)
+ self.assertEqual(len(set(py_thread_ids)), len(py_thread_ids),
+ py_thread_ids)
+
+
if __name__ == "__main__":
unittest.main()
# compatible with C++ and does not emit C++ compiler warnings.
import os.path
import shutil
-import sys
import unittest
import subprocess
import sysconfig
# gh-110119: pip does not currently support 't' in the ABI flag use by
# --disable-gil builds. Once it does, we can remove this skip.
-@unittest.skipIf(sysconfig.get_config_var('Py_GIL_DISABLED') == 1,
+@unittest.skipIf(support.Py_GIL_DISABLED,
'test does not work with --disable-gil')
@support.requires_subprocess()
class TestCPPExt(unittest.TestCase):
import os
import re
import sys
-import sysconfig
import unittest
+from test import support
from test.support import import_helper
from contextlib import contextmanager
from test.test_importlib.util import temp_module
class WindowsExtensionSuffixTests:
def test_tagged_suffix(self):
suffixes = self.machinery.EXTENSION_SUFFIXES
- abi_flags = "t" if sysconfig.get_config_var("Py_GIL_DISABLED") else ""
+ abi_flags = "t" if support.Py_GIL_DISABLED else ""
ver = sys.version_info
platform = re.sub('[^a-zA-Z0-9]', '_', get_platform())
expected_tag = f".cp{ver.major}{ver.minor}{abi_flags}-{platform}.pyd"
@test.support.cpython_only
@unittest.skipUnless(hasattr(sys, 'abiflags'), 'need sys.abiflags')
def test_disable_gil_abi(self):
- abi_threaded = 't' in sys.abiflags
- py_gil_disabled = (sysconfig.get_config_var('Py_GIL_DISABLED') == 1)
- self.assertEqual(py_gil_disabled, abi_threaded)
+ self.assertEqual('t' in sys.abiflags, support.Py_GIL_DISABLED)
@test.support.cpython_only
}
+#ifdef Py_GIL_DISABLED
+static PyObject *
+get_py_thread_id(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ uintptr_t tid = _Py_ThreadId();
+ Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(tid));
+ return PyLong_FromUnsignedLongLong(tid);
+}
+#endif
+
+
static PyMethodDef module_functions[] = {
{"get_configs", get_configs, METH_NOARGS},
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
{"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS},
_TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF
{"get_type_module_name", get_type_module_name, METH_O},
+#ifdef Py_GIL_DISABLED
+ {"py_thread_id", get_py_thread_id, METH_NOARGS},
+#endif
{NULL, NULL} /* sentinel */
};