summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-06-05 00:34:14 (GMT)
committerGitHub <noreply@github.com>2020-06-05 00:34:14 (GMT)
commit78a02c2568714562e23e885b6dc5730601f35226 (patch)
tree167982aa5857ae92f0dd301aaa3e22e908a9d9a1 /Include
parent88ec9190105c9b03f49aaef601ce02b242a75273 (diff)
downloadcpython-78a02c2568714562e23e885b6dc5730601f35226.zip
cpython-78a02c2568714562e23e885b6dc5730601f35226.tar.gz
cpython-78a02c2568714562e23e885b6dc5730601f35226.tar.bz2
bpo-40521: Make async gen free lists per-interpreter (GH-20643)
Each interpreter now has its own asynchronous generator free lists: * Move async gen free lists into PyInterpreterState. * Move _PyAsyncGen_MAXFREELIST define to pycore_interp.h * Add _Py_async_gen_state structure. * Add tstate parameter to _PyAsyncGen_ClearFreeLists and _PyAsyncGen_Fini().
Diffstat (limited to 'Include')
-rw-r--r--Include/internal/pycore_gc.h2
-rw-r--r--Include/internal/pycore_interp.h18
-rw-r--r--Include/internal/pycore_pylifecycle.h2
3 files changed, 20 insertions, 2 deletions
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 3388b4d..ad2e552 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -170,7 +170,7 @@ extern void _PyTuple_ClearFreeList(PyThreadState *tstate);
extern void _PyFloat_ClearFreeList(PyThreadState *tstate);
extern void _PyList_ClearFreeList(PyThreadState *tstate);
extern void _PyDict_ClearFreeList(void);
-extern void _PyAsyncGen_ClearFreeLists(void);
+extern void _PyAsyncGen_ClearFreeLists(PyThreadState *tstate);
extern void _PyContext_ClearFreeList(void);
#ifdef __cplusplus
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 0eab246..d624218 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -108,6 +108,23 @@ struct _Py_frame_state {
int numfree;
};
+#ifndef _PyAsyncGen_MAXFREELIST
+# define _PyAsyncGen_MAXFREELIST 80
+#endif
+
+struct _Py_async_gen_state {
+ /* 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;
+};
+
+
/* interpreter state */
@@ -205,6 +222,7 @@ struct _is {
struct _Py_list_state list;
struct _Py_float_state float_state;
struct _Py_frame_state frame;
+ struct _Py_async_gen_state async_gen;
/* Using a cache is very effective since typically only a single slice is
created and then deleted again. */
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 3c35ca2..3e36573 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -66,7 +66,7 @@ extern void _PySet_Fini(void);
extern void _PyBytes_Fini(void);
extern void _PyFloat_Fini(PyThreadState *tstate);
extern void _PySlice_Fini(PyThreadState *tstate);
-extern void _PyAsyncGen_Fini(void);
+extern void _PyAsyncGen_Fini(PyThreadState *tstate);
extern void PyOS_FiniInterrupts(void);