Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-111968: Introduce _PyFreeListState and _PyFreeListState_GET API#113584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
cd4863c333873d8b7e261dd0afa2f0d55de5e8e3b47aa956a908ef130096383bc8dd4a40bad6b1b0f3703d6042e09403dbc05491ed5f95593dd3c3f0d8ea53e9d813807e05366c8ba678a809706d2f2d4887bacfe65952f25a67143fd9baae175b61295a2925836c4b7cb261f01bbc7ab08f65f65cedee9a40708af86a204e841307ffa64cd6a2feb458aadbb105bda18e92165bb8d3f2811a12a5f494d837ae6008c8613b5eb4720d8dc3dfe859e1c284061a8e39b399ac3750c331c7File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,35 @@ | ||||||||||||||||||||||||||||||||||
| #ifndef Py_INTERNAL_FREELIST_H | ||||||||||||||||||||||||||||||||||
| #define Py_INTERNAL_FREELIST_H | ||||||||||||||||||||||||||||||||||
| #ifdef __cplusplus | ||||||||||||||||||||||||||||||||||
| extern "C" { | ||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||
| #ifndef Py_BUILD_CORE | ||||||||||||||||||||||||||||||||||
| # error "this header requires Py_BUILD_CORE define" | ||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||
| #ifndef WITH_FREELISTS | ||||||||||||||||||||||||||||||||||
| // without freelists | ||||||||||||||||||||||||||||||||||
| # define PyList_MAXFREELIST 0 | ||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||
| /* Empty list reuse scheme to save calls to malloc and free */ | ||||||||||||||||||||||||||||||||||
| #ifndef PyList_MAXFREELIST | ||||||||||||||||||||||||||||||||||
| # define PyList_MAXFREELIST 80 | ||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||
Comment on lines
+11
to
+19
| ||||||||||||||||||||||||||||||||||
| #ifndefWITH_FREELISTS | |
| // without freelists | |
| # definePyList_MAXFREELIST 0 | |
| #endif | |
| /* Empty list reuse scheme to save calls to malloc and free */ | |
| #ifndefPyList_MAXFREELIST | |
| # definePyList_MAXFREELIST 80 | |
| #endif | |
| struct_Py_list_state { | |
| #ifPyList_MAXFREELIST>0 | |
| PyListObject*free_list[PyList_MAXFREELIST]; | |
| intnumfree; | |
| #endif | |
| }; |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,32 @@ | ||||||
| #include "Python.h" | ||||||
| #include "pycore_pystate.h" // _PyFreeListState_GET() | ||||||
| #include "pycore_tstate.h" // _PyThreadStateImpl | ||||||
| #ifdef Py_GIL_DISABLED | ||||||
| /* Clear all free lists | ||||||
| * All free lists are cleared during the collection of the highest generation. | ||||||
| * Allocated items in the free list may keep a pymalloc arena occupied. | ||||||
| * Clearing the free lists may give back memory to the OS earlier. | ||||||
| * Free-threading version: Since freelists are managed per thread, | ||||||
| * GC should clear all freelists by traversing all threads. | ||||||
| */ | ||||||
| void | ||||||
| _PyGC_ClearAllFreeLists(PyInterpreterState *interp) | ||||||
| { | ||||||
| _PyTuple_ClearFreeList(interp); | ||||||
| _PyFloat_ClearFreeList(interp); | ||||||
| _PyDict_ClearFreeList(interp); | ||||||
| _PyAsyncGen_ClearFreeLists(interp); | ||||||
| _PyContext_ClearFreeList(interp); | ||||||
| HEAD_LOCK(&_PyRuntime); | ||||||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This locks interpreters creation, but not thread creation, no? Is it possible that this races with thread creation/destruction? I am missing something? Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part looks okay to me. The Lines 1370 to 1371 in ace4d7f
Modification of the free-lists themselves is protected by the "stop-the-world" pause (or the GIL), which is not yet implemented. | ||||||
| _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head; | ||||||
| while (tstate != NULL) { | ||||||
| _Py_ClearFreeLists(&tstate->freelist_state, 0); | ||||||
| tstate = (_PyThreadStateImpl *)tstate->base.next; | ||||||
| } | ||||||
| HEAD_UNLOCK(&_PyRuntime); | ||||||
| } | ||||||
| #endif | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #include "Python.h" | ||
| #include "pycore_pystate.h" // _Py_ClearFreeLists() | ||
| #ifndef Py_GIL_DISABLED | ||
| /* Clear all free lists | ||
| * All free lists are cleared during the collection of the highest generation. | ||
| * Allocated items in the free list may keep a pymalloc arena occupied. | ||
| * Clearing the free lists may give back memory to the OS earlier. | ||
| */ | ||
| void | ||
| _PyGC_ClearAllFreeLists(PyInterpreterState *interp) | ||
| { | ||
| _PyTuple_ClearFreeList(interp); | ||
| _PyFloat_ClearFreeList(interp); | ||
| _PyDict_ClearFreeList(interp); | ||
| _PyAsyncGen_ClearFreeLists(interp); | ||
| _PyContext_ClearFreeList(interp); | ||
| _Py_ClearFreeLists(&interp->freelist_state, 0); | ||
| } | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1752,13 +1752,16 @@ finalize_interp_types(PyInterpreterState *interp) | ||
| _PyUnicode_ClearInterned(interp); | ||
| _PyDict_Fini(interp); | ||
| _PyList_Fini(interp); | ||
| _PyTuple_Fini(interp); | ||
| _PySlice_Fini(interp); | ||
| _PyUnicode_Fini(interp); | ||
| _PyFloat_Fini(interp); | ||
| _PyFreeListState *state = _PyFreeListState_GET(); | ||
corona10 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| _PyList_Fini(state); | ||
| #ifdef Py_DEBUG | ||
| _PyStaticObjects_CheckRefcnt(interp); | ||
| #endif | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All freelist related domains will be moved here.