Skip to content

Commit 44876fb

Browse files
committed
gh-112535: Add test on _Py_ThreadId()
Add also test.support.Py_GIL_DISABLED constant.
1 parent 9560e0d commit 44876fb

File tree

6 files changed

+67
-6
lines changed

6 files changed

+67
-6
lines changed

Lib/test/support/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,8 @@ def check_cflags_pgo():
796796
return any(option in cflags_nodist for option in pgo_options)
797797

798798

799-
if sysconfig.get_config_var('Py_GIL_DISABLED'):
799+
Py_GIL_DISABLED = bool(sysconfig.get_config_var('Py_GIL_DISABLED'))
800+
if Py_GIL_DISABLED:
800801
_header = 'PHBBInP'
801802
else:
802803
_header = 'nP'

Lib/test/test_capi/test_misc.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2854,5 +2854,53 @@ def testfunc(n, m):
28542854
self.assertIn("_FOR_ITER_TIER_TWO", uops)
28552855

28562856

2857+
@unittest.skipUnless(support.Py_GIL_DISABLED, 'need Py_GIL_DISABLED')
2858+
class TestPyThreadId(unittest.TestCase):
2859+
def test_py_thread_id(self):
2860+
# gh-112535: Test _Py_ThreadId(): make sure that thread identifiers
2861+
# in a few threads are unique
2862+
py_thread_id = _testinternalcapi.py_thread_id
2863+
2864+
class GetThreadId(threading.Thread):
2865+
def __init__(self):
2866+
super().__init__()
2867+
self.get_lock = threading.Lock()
2868+
self.get_lock.acquire()
2869+
self.started_lock = threading.Event()
2870+
self.py_tid = None
2871+
2872+
def run(self):
2873+
self.started_lock.set()
2874+
self.get_lock.acquire()
2875+
self.py_tid = py_thread_id()
2876+
2877+
nthread = 5
2878+
threads = [GetThreadId() for _ in range(nthread)]
2879+
2880+
# first make run sure that all threads are running
2881+
for thread in threads:
2882+
thread.start()
2883+
for thread in threads:
2884+
thread.started_lock.wait()
2885+
2886+
# call _Py_ThreadId() in the main thread
2887+
py_thread_ids = [py_thread_id()]
2888+
2889+
# now call _Py_ThreadId() in each thread
2890+
for thread in threads:
2891+
thread.get_lock.release()
2892+
2893+
# call _Py_ThreadId() in each thread and wait until threads complete
2894+
for thread in threads:
2895+
thread.join()
2896+
py_thread_ids.append(thread.py_tid)
2897+
for tid in py_thread_ids:
2898+
self.assertIsInstance(tid, int)
2899+
2900+
# make sure that all _Py_ThreadId() are unique
2901+
self.assertEqual(len(set(py_thread_ids)), len(py_thread_ids),
2902+
py_thread_ids)
2903+
2904+
28572905
if __name__ == "__main__":
28582906
unittest.main()

Lib/test/test_cppext/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
# gh-110119: pip does not currently support 't' in the ABI flag use by
1717
# --disable-gil builds. Once it does, we can remove this skip.
18-
@unittest.skipIf(sysconfig.get_config_var('Py_GIL_DISABLED') == 1,
18+
@unittest.skipIf(support.Py_GIL_DISABLED,
1919
'test does not work with --disable-gil')
2020
@support.requires_subprocess()
2121
class TestCPPExt(unittest.TestCase):

Lib/test/test_importlib/test_windows.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def test_module_not_found(self):
112112
class WindowsExtensionSuffixTests:
113113
def test_tagged_suffix(self):
114114
suffixes = self.machinery.EXTENSION_SUFFIXES
115-
abi_flags = "t" if sysconfig.get_config_var("Py_GIL_DISABLED") else ""
115+
abi_flags = "t" if support.Py_GIL_DISABLED else ""
116116
ver = sys.version_info
117117
platform = re.sub('[^a-zA-Z0-9]', '_', get_platform())
118118
expected_tag = f".cp{ver.major}{ver.minor}{abi_flags}-{platform}.pyd"

Lib/test/test_sys.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,9 +1224,7 @@ def test_pystats(self):
12241224
@test.support.cpython_only
12251225
@unittest.skipUnless(hasattr(sys, 'abiflags'), 'need sys.abiflags')
12261226
def test_disable_gil_abi(self):
1227-
abi_threaded = 't' in sys.abiflags
1228-
py_gil_disabled = (sysconfig.get_config_var('Py_GIL_DISABLED') == 1)
1229-
self.assertEqual(py_gil_disabled, abi_threaded)
1227+
self.assertEqual('t' in sys.abiflags, support.Py_GIL_DISABLED)
12301228

12311229

12321230
@test.support.cpython_only

Modules/_testinternalcapi.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,17 @@ get_type_module_name(PyObject *self, PyObject *type)
16251625
}
16261626

16271627

1628+
#ifdef Py_GIL_DISABLED
1629+
static PyObject *
1630+
get_py_thread_id(PyObject *self, PyObject *type)
1631+
{
1632+
uintptr_t tid = _Py_ThreadId();
1633+
Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(tid));
1634+
return PyLong_FromUnsignedLongLong(tid);
1635+
}
1636+
#endif
1637+
1638+
16281639
static PyMethodDef module_functions[] = {
16291640
{"get_configs", get_configs, METH_NOARGS},
16301641
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
@@ -1688,6 +1699,9 @@ static PyMethodDef module_functions[] = {
16881699
{"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS},
16891700
_TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF
16901701
{"get_type_module_name", get_type_module_name, METH_O},
1702+
#ifdef Py_GIL_DISABLED
1703+
{"py_thread_id", get_py_thread_id, METH_NOARGS},
1704+
#endif
16911705
{NULL, NULL} /* sentinel */
16921706
};
16931707

0 commit comments

Comments
 (0)