summaryrefslogtreecommitdiffstats
path: root/Include/internal
diff options
context:
space:
mode:
authorDonghee Na <donghee.na@python.org>2024-01-18 18:15:00 (GMT)
committerGitHub <noreply@github.com>2024-01-18 18:15:00 (GMT)
commit7fa511ba576b9a760f3971ad16dbbbbf91c3f39c (patch)
treed3e5fa9dd914d10f6f018bc728664635419ecb32 /Include/internal
parent2d3f6b56c5846df60b0b305e51a1d293ba0b2aae (diff)
downloadcpython-7fa511ba576b9a760f3971ad16dbbbbf91c3f39c.zip
cpython-7fa511ba576b9a760f3971ad16dbbbbf91c3f39c.tar.gz
cpython-7fa511ba576b9a760f3971ad16dbbbbf91c3f39c.tar.bz2
gh-111968: Use per-thread freelists for generator in free-threading (gh-114189)
Diffstat (limited to 'Include/internal')
-rw-r--r--Include/internal/pycore_freelist.h17
-rw-r--r--Include/internal/pycore_gc.h2
-rw-r--r--Include/internal/pycore_genobject.h31
-rw-r--r--Include/internal/pycore_interp.h1
4 files changed, 21 insertions, 30 deletions
diff --git a/Include/internal/pycore_freelist.h b/Include/internal/pycore_freelist.h
index 566d47d..4ab93ee 100644
--- a/Include/internal/pycore_freelist.h
+++ b/Include/internal/pycore_freelist.h
@@ -19,12 +19,14 @@ extern "C" {
# define PyList_MAXFREELIST 80
# define PyFloat_MAXFREELIST 100
# define PyContext_MAXFREELIST 255
+# define _PyAsyncGen_MAXFREELIST 80
#else
# define PyTuple_NFREELISTS 0
# define PyTuple_MAXFREELIST 0
# define PyList_MAXFREELIST 0
# define PyFloat_MAXFREELIST 0
# define PyContext_MAXFREELIST 0
+# define _PyAsyncGen_MAXFREELIST 0
#endif
struct _Py_list_state {
@@ -77,12 +79,27 @@ struct _Py_context_state {
#endif
};
+struct _Py_async_gen_state {
+#ifdef WITH_FREELISTS
+ /* Freelists boost performance 6-10%; they also reduce memory
+ fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
+ are short-living objects that are instantiated for every
+ __anext__() call. */
+ struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
+ int value_numfree;
+
+ struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
+ int asend_numfree;
+#endif
+};
+
typedef struct _Py_freelist_state {
struct _Py_float_state float_state;
struct _Py_tuple_state tuple_state;
struct _Py_list_state list_state;
struct _Py_slice_state slice_state;
struct _Py_context_state context_state;
+ struct _Py_async_gen_state async_gen_state;
} _PyFreeListState;
#ifdef __cplusplus
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 52e8b39..d53de97 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -251,7 +251,7 @@ extern void _PyFloat_ClearFreeList(_PyFreeListState *state, int is_finalization)
extern void _PyList_ClearFreeList(_PyFreeListState *state, int is_finalization);
extern void _PySlice_ClearCache(_PyFreeListState *state);
extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
-extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
+extern void _PyAsyncGen_ClearFreeLists(_PyFreeListState *state, int is_finalization);
extern void _PyContext_ClearFreeList(_PyFreeListState *state, int is_finalization);
extern void _Py_ScheduleGC(PyInterpreterState *interp);
extern void _Py_RunGC(PyThreadState *tstate);
diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h
index cf58a27..5ad6365 100644
--- a/Include/internal/pycore_genobject.h
+++ b/Include/internal/pycore_genobject.h
@@ -8,6 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_freelist.h"
+
extern PyObject *_PyGen_yf(PyGenObject *);
extern void _PyGen_Finalize(PyObject *self);
@@ -26,34 +28,7 @@ extern PyTypeObject _PyAsyncGenAThrow_Type;
/* runtime lifecycle */
-extern void _PyAsyncGen_Fini(PyInterpreterState *);
-
-
-/* other API */
-
-#ifndef WITH_FREELISTS
-// without freelists
-# define _PyAsyncGen_MAXFREELIST 0
-#endif
-
-#ifndef _PyAsyncGen_MAXFREELIST
-# define _PyAsyncGen_MAXFREELIST 80
-#endif
-
-struct _Py_async_gen_state {
-#if _PyAsyncGen_MAXFREELIST > 0
- /* Freelists boost performance 6-10%; they also reduce memory
- fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
- are short-living objects that are instantiated for every
- __anext__() call. */
- struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
- int value_numfree;
-
- struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
- int asend_numfree;
-#endif
-};
-
+extern void _PyAsyncGen_Fini(_PyFreeListState *);
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 7ec9630..922c845 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -190,7 +190,6 @@ struct _is {
struct _Py_tuple_state tuple;
struct _Py_dict_state dict_state;
- struct _Py_async_gen_state async_gen;
struct _Py_exc_state exc_state;
struct ast_state ast;