diff options
author | Donghee Na <donghee.na@python.org> | 2024-01-18 18:15:00 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-18 18:15:00 (GMT) |
commit | 7fa511ba576b9a760f3971ad16dbbbbf91c3f39c (patch) | |
tree | d3e5fa9dd914d10f6f018bc728664635419ecb32 /Include/internal | |
parent | 2d3f6b56c5846df60b0b305e51a1d293ba0b2aae (diff) | |
download | cpython-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.h | 17 | ||||
-rw-r--r-- | Include/internal/pycore_gc.h | 2 | ||||
-rw-r--r-- | Include/internal/pycore_genobject.h | 31 | ||||
-rw-r--r-- | Include/internal/pycore_interp.h | 1 |
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; |