]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-112532: Require mimalloc in `--disable-gil` builds (gh-112883)
authorSam Gross <colesbury@gmail.com>
Tue, 12 Dec 2023 00:04:48 +0000 (19:04 -0500)
committerGitHub <noreply@github.com>
Tue, 12 Dec 2023 00:04:48 +0000 (09:04 +0900)
Include/internal/pycore_pymem_init.h
Lib/test/support/__init__.py
Lib/test/test_capi/test_mem.py
Lib/test/test_cmd_line.py
Lib/test/test_embed.py
Lib/test/test_os.py
Objects/obmalloc.c
Programs/_testembed.c
configure
configure.ac

index 11fbe16fa6f1d5f2fc7f0bdd694bf42cdf8323dd..360fb9218a9cdac0efcc770a64eb9870dff29cc5 100644 (file)
@@ -18,7 +18,19 @@ extern void * _PyMem_RawRealloc(void *, void *, size_t);
 extern void _PyMem_RawFree(void *, void *);
 #define PYRAW_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree}
 
-#if defined(WITH_PYMALLOC)
+#ifdef Py_GIL_DISABLED
+// Py_GIL_DISABLED requires mimalloc
+extern void* _PyObject_MiMalloc(void *, size_t);
+extern void* _PyObject_MiCalloc(void *, size_t, size_t);
+extern void _PyObject_MiFree(void *, void *);
+extern void* _PyObject_MiRealloc(void *, void *, size_t);
+#  define PYOBJ_ALLOC {NULL, _PyObject_MiMalloc, _PyObject_MiCalloc, _PyObject_MiRealloc, _PyObject_MiFree}
+extern void* _PyMem_MiMalloc(void *, size_t);
+extern void* _PyMem_MiCalloc(void *, size_t, size_t);
+extern void _PyMem_MiFree(void *, void *);
+extern void* _PyMem_MiRealloc(void *, void *, size_t);
+#  define PYMEM_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree}
+#elif defined(WITH_PYMALLOC)
 extern void* _PyObject_Malloc(void *, size_t);
 extern void* _PyObject_Calloc(void *, size_t, size_t);
 extern void _PyObject_Free(void *, void *);
index c22d73c231b46e45dc5be16b45ae8c607c2ed609..b605951320dc8b6bd06543b90f27f56e3bda711d 100644 (file)
@@ -1844,7 +1844,7 @@ class SaveSignals:
 
 def with_pymalloc():
     import _testcapi
-    return _testcapi.WITH_PYMALLOC
+    return _testcapi.WITH_PYMALLOC and not Py_GIL_DISABLED
 
 
 def with_mimalloc():
index 72f23b1a34080e741b289295a48d89aa0efd4692..04f17a9ec9e72a8824881a55ba65276f14541424 100644 (file)
@@ -152,6 +152,8 @@ class PyMemDebugTests(unittest.TestCase):
             self.assertGreaterEqual(count, i*5-2)
 
 
+# Py_GIL_DISABLED requires mimalloc (not malloc)
+@unittest.skipIf(support.Py_GIL_DISABLED, 'need malloc')
 class PyMemMallocDebugTests(PyMemDebugTests):
     PYTHONMALLOC = 'malloc_debug'
 
@@ -161,6 +163,11 @@ class PyMemPymallocDebugTests(PyMemDebugTests):
     PYTHONMALLOC = 'pymalloc_debug'
 
 
+@unittest.skipUnless(support.with_mimalloc(), 'need mimaloc')
+class PyMemMimallocDebugTests(PyMemDebugTests):
+    PYTHONMALLOC = 'mimalloc_debug'
+
+
 @unittest.skipUnless(support.Py_DEBUG, 'need Py_DEBUG')
 class PyMemDefaultTests(PyMemDebugTests):
     # test default allocator of Python compiled in debug mode
index 7a27952c345b9c3830d95585bef65f26d6413550..1fe3b2fe53c0b63216ee7d0790daffe7647aa2e6 100644 (file)
@@ -738,6 +738,8 @@ class CmdLineTest(unittest.TestCase):
                 out = self.run_xdev("-c", code, check_exitcode=False)
             if support.with_pymalloc():
                 alloc_name = "pymalloc_debug"
+            elif support.Py_GIL_DISABLED:
+                alloc_name = "mimalloc_debug"
             else:
                 alloc_name = "malloc_debug"
             self.assertEqual(out, alloc_name)
@@ -814,9 +816,13 @@ class CmdLineTest(unittest.TestCase):
     @support.cpython_only
     def test_pythonmalloc(self):
         # Test the PYTHONMALLOC environment variable
+        malloc = not support.Py_GIL_DISABLED
         pymalloc = support.with_pymalloc()
         mimalloc = support.with_mimalloc()
-        if pymalloc:
+        if support.Py_GIL_DISABLED:
+            default_name = 'mimalloc_debug' if support.Py_DEBUG else 'mimalloc'
+            default_name_debug = 'mimalloc_debug'
+        elif pymalloc:
             default_name = 'pymalloc_debug' if support.Py_DEBUG else 'pymalloc'
             default_name_debug = 'pymalloc_debug'
         else:
@@ -826,9 +832,12 @@ class CmdLineTest(unittest.TestCase):
         tests = [
             (None, default_name),
             ('debug', default_name_debug),
-            ('malloc', 'malloc'),
-            ('malloc_debug', 'malloc_debug'),
         ]
+        if malloc:
+            tests.extend([
+                ('malloc', 'malloc'),
+                ('malloc_debug', 'malloc_debug'),
+            ])
         if pymalloc:
             tests.extend((
                 ('pymalloc', 'pymalloc'),
index d2d6c1b61e46f069cf2d8c21f7798b0d89a1e84e..6c60854bbd76cc0a923ed57841414a3f3b657926 100644 (file)
@@ -23,6 +23,12 @@ MACOS = (sys.platform == 'darwin')
 PYMEM_ALLOCATOR_NOT_SET = 0
 PYMEM_ALLOCATOR_DEBUG = 2
 PYMEM_ALLOCATOR_MALLOC = 3
+PYMEM_ALLOCATOR_MIMALLOC = 7
+if support.Py_GIL_DISABLED:
+    ALLOCATOR_FOR_CONFIG = PYMEM_ALLOCATOR_MIMALLOC
+else:
+    ALLOCATOR_FOR_CONFIG = PYMEM_ALLOCATOR_MALLOC
+
 Py_STATS = hasattr(sys, '_stats_on')
 
 # _PyCoreConfig_InitCompatConfig()
@@ -841,7 +847,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
 
     def test_init_from_config(self):
         preconfig = {
-            'allocator': PYMEM_ALLOCATOR_MALLOC,
+            'allocator': ALLOCATOR_FOR_CONFIG,
             'utf8_mode': 1,
         }
         config = {
@@ -908,7 +914,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
 
     def test_init_compat_env(self):
         preconfig = {
-            'allocator': PYMEM_ALLOCATOR_MALLOC,
+            'allocator': ALLOCATOR_FOR_CONFIG,
         }
         config = {
             'use_hash_seed': 1,
@@ -942,7 +948,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
 
     def test_init_python_env(self):
         preconfig = {
-            'allocator': PYMEM_ALLOCATOR_MALLOC,
+            'allocator': ALLOCATOR_FOR_CONFIG,
             'utf8_mode': 1,
         }
         config = {
@@ -984,7 +990,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
                                api=API_COMPAT)
 
     def test_init_env_dev_mode_alloc(self):
-        preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC)
+        preconfig = dict(allocator=ALLOCATOR_FOR_CONFIG)
         config = dict(dev_mode=1,
                       faulthandler=1,
                       warnoptions=['default'])
index c31c96840511968f8afbd6fb2b2a70c7ff69ceed..d4680ef0f0e03f77e8923402bb7583dda04d56d1 100644 (file)
@@ -5080,7 +5080,10 @@ class ForkTests(unittest.TestCase):
                 support.wait_process(pid, exitcode=0)
         """
         assert_python_ok("-c", code)
-        assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")
+        if support.Py_GIL_DISABLED:
+            assert_python_ok("-c", code, PYTHONMALLOC="mimalloc_debug")
+        else:
+            assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")
 
     @unittest.skipUnless(sys.platform in ("linux", "darwin"),
                          "Only Linux and macOS detect this today.")
index b737c03095756417b98f6cb585624e04da4cf6bf..99c95d90658b08efab0ca1281c91a8639d812601 100644 (file)
 #  include "mimalloc/internal.h"  // for stats
 #endif
 
+#if defined(Py_GIL_DISABLED) && !defined(WITH_MIMALLOC)
+#  error "Py_GIL_DISABLED requires WITH_MIMALLOC"
+#endif
+
 #undef  uint
 #define uint pymem_uint
 
@@ -153,7 +157,12 @@ void* _PyObject_Realloc(void *ctx, void *ptr, size_t size);
 #  define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free}
 #endif  // WITH_PYMALLOC
 
-#if defined(WITH_PYMALLOC)
+#if defined(Py_GIL_DISABLED)
+// Py_GIL_DISABLED requires using mimalloc for "mem" and "obj" domains.
+#  define PYRAW_ALLOC MALLOC_ALLOC
+#  define PYMEM_ALLOC MIMALLOC_ALLOC
+#  define PYOBJ_ALLOC MIMALLOC_OBJALLOC
+#elif defined(WITH_PYMALLOC)
 #  define PYRAW_ALLOC MALLOC_ALLOC
 #  define PYMEM_ALLOC PYMALLOC_ALLOC
 #  define PYOBJ_ALLOC PYMALLOC_ALLOC
@@ -350,7 +359,7 @@ _PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator)
     else if (strcmp(name, "debug") == 0) {
         *allocator = PYMEM_ALLOCATOR_DEBUG;
     }
-#ifdef WITH_PYMALLOC
+#if defined(WITH_PYMALLOC) && !defined(Py_GIL_DISABLED)
     else if (strcmp(name, "pymalloc") == 0) {
         *allocator = PYMEM_ALLOCATOR_PYMALLOC;
     }
@@ -366,12 +375,14 @@ _PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator)
         *allocator = PYMEM_ALLOCATOR_MIMALLOC_DEBUG;
     }
 #endif
+#ifndef Py_GIL_DISABLED
     else if (strcmp(name, "malloc") == 0) {
         *allocator = PYMEM_ALLOCATOR_MALLOC;
     }
     else if (strcmp(name, "malloc_debug") == 0) {
         *allocator = PYMEM_ALLOCATOR_MALLOC_DEBUG;
     }
+#endif
     else {
         /* unknown allocator */
         return -1;
index 1f9aa4b3d449a109d601366738f682db49b63471..30998bf80f9ce442000d7066cb7f3b483d7e8c1c 100644 (file)
@@ -576,7 +576,11 @@ static int test_init_from_config(void)
     _PyPreConfig_InitCompatConfig(&preconfig);
 
     putenv("PYTHONMALLOC=malloc_debug");
+#ifndef Py_GIL_DISABLED
     preconfig.allocator = PYMEM_ALLOCATOR_MALLOC;
+#else
+    preconfig.allocator = PYMEM_ALLOCATOR_MIMALLOC;
+#endif
 
     putenv("PYTHONUTF8=0");
     Py_UTF8Mode = 0;
@@ -765,7 +769,11 @@ static int test_init_dont_parse_argv(void)
 static void set_most_env_vars(void)
 {
     putenv("PYTHONHASHSEED=42");
+#ifndef Py_GIL_DISABLED
     putenv("PYTHONMALLOC=malloc");
+#else
+    putenv("PYTHONMALLOC=mimalloc");
+#endif
     putenv("PYTHONTRACEMALLOC=2");
     putenv("PYTHONPROFILEIMPORTTIME=1");
     putenv("PYTHONNODEBUGRANGES=1");
@@ -851,7 +859,11 @@ static int test_init_env_dev_mode_alloc(void)
     /* Test initialization from environment variables */
     Py_IgnoreEnvironmentFlag = 0;
     set_all_env_vars_dev_mode();
+#ifndef Py_GIL_DISABLED
     putenv("PYTHONMALLOC=malloc");
+#else
+    putenv("PYTHONMALLOC=mimalloc");
+#endif
     _testembed_Py_InitializeFromConfig();
     dump_config();
     Py_Finalize();
index 5f880d6d8edd96d9bf0f3e15feb2c8d20c89c7aa..c4486441041a70948d865647eaf93199d2c3693f 100755 (executable)
--- a/configure
+++ b/configure
@@ -16891,6 +16891,8 @@ printf "%s\n" "#define WITH_MIMALLOC 1" >>confdefs.h
 
   MIMALLOC_HEADERS='$(MIMALLOC_HEADERS)'
 
+elif test "$disable_gil" = "yes"; then
+  as_fn_error $? "--disable-gil requires mimalloc memory allocator (--with-mimalloc)." "$LINENO" 5
 fi
 
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_mimalloc" >&5
index c07d7ce6bdc9189496cfcc9d497adf19de5f8447..a725309424a49ef0492461c820586ee2393d5f51 100644 (file)
@@ -4558,6 +4558,8 @@ if test "$with_mimalloc" != no; then
   with_mimalloc=yes
   AC_DEFINE([WITH_MIMALLOC], [1], [Define if you want to compile in mimalloc memory allocator.])
   AC_SUBST([MIMALLOC_HEADERS], ['$(MIMALLOC_HEADERS)'])
+elif test "$disable_gil" = "yes"; then
+  AC_MSG_ERROR([--disable-gil requires mimalloc memory allocator (--with-mimalloc).])
 fi
 
 AC_MSG_RESULT([$with_mimalloc])