-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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
gh-111968: Use per-thread freelists for float in free-threading #113886
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,17 +26,13 @@ class float "PyObject *" "&PyFloat_Type" | |
|
||
#include "clinic/floatobject.c.h" | ||
|
||
#ifndef PyFloat_MAXFREELIST | ||
# define PyFloat_MAXFREELIST 100 | ||
#endif | ||
|
||
|
||
#if PyFloat_MAXFREELIST > 0 | ||
#ifdef WITH_FREELISTS | ||
static struct _Py_float_state * | ||
get_float_state(void) | ||
{ | ||
PyInterpreterState *interp = _PyInterpreterState_GET(); | ||
return &interp->float_state; | ||
_PyFreeListState *state = _PyFreeListState_GET(); | ||
assert(state != NULL); | ||
return &state->float_state; | ||
} | ||
#endif | ||
|
||
|
@@ -132,7 +128,7 @@ PyObject * | |
PyFloat_FromDouble(double fval) | ||
{ | ||
PyFloatObject *op; | ||
#if PyFloat_MAXFREELIST > 0 | ||
#ifdef WITH_FREELISTS | ||
struct _Py_float_state *state = get_float_state(); | ||
op = state->free_list; | ||
if (op != NULL) { | ||
|
@@ -252,13 +248,9 @@ _PyFloat_ExactDealloc(PyObject *obj) | |
{ | ||
assert(PyFloat_CheckExact(obj)); | ||
PyFloatObject *op = (PyFloatObject *)obj; | ||
#if PyFloat_MAXFREELIST > 0 | ||
#ifdef WITH_FREELISTS | ||
struct _Py_float_state *state = get_float_state(); | ||
#ifdef Py_DEBUG | ||
// float_dealloc() must not be called after _PyFloat_Fini() | ||
assert(state->numfree != -1); | ||
#endif | ||
if (state->numfree >= PyFloat_MAXFREELIST) { | ||
if (state->numfree >= PyFloat_MAXFREELIST || state->numfree < 0) { | ||
PyObject_Free(op); | ||
return; | ||
} | ||
|
@@ -275,7 +267,7 @@ static void | |
float_dealloc(PyObject *op) | ||
{ | ||
assert(PyFloat_Check(op)); | ||
#if PyFloat_MAXFREELIST > 0 | ||
#ifdef WITH_FREELISTS | ||
if (PyFloat_CheckExact(op)) { | ||
_PyFloat_ExactDealloc(op); | ||
} | ||
|
@@ -2002,29 +1994,30 @@ _PyFloat_InitTypes(PyInterpreterState *interp) | |
} | ||
|
||
void | ||
_PyFloat_ClearFreeList(PyInterpreterState *interp) | ||
_PyFloat_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) | ||
{ | ||
#if PyFloat_MAXFREELIST > 0 | ||
struct _Py_float_state *state = &interp->float_state; | ||
#ifdef WITH_FREELISTS | ||
struct _Py_float_state *state = &freelist_state->float_state; | ||
PyFloatObject *f = state->free_list; | ||
while (f != NULL) { | ||
PyFloatObject *next = (PyFloatObject*) Py_TYPE(f); | ||
PyObject_Free(f); | ||
f = next; | ||
} | ||
state->free_list = NULL; | ||
state->numfree = 0; | ||
if (is_finalization) { | ||
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. Previously, we only set I'd suggest adding changing the condition in 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. Updated! |
||
state->numfree = -1; | ||
} | ||
else { | ||
state->numfree = 0; | ||
} | ||
#endif | ||
} | ||
|
||
void | ||
_PyFloat_Fini(PyInterpreterState *interp) | ||
_PyFloat_Fini(_PyFreeListState *state) | ||
{ | ||
_PyFloat_ClearFreeList(interp); | ||
#if defined(Py_DEBUG) && PyFloat_MAXFREELIST > 0 | ||
struct _Py_float_state *state = &interp->float_state; | ||
state->numfree = -1; | ||
#endif | ||
_PyFloat_ClearFreeList(state, 1); | ||
} | ||
|
||
void | ||
|
@@ -2037,7 +2030,7 @@ _PyFloat_FiniType(PyInterpreterState *interp) | |
void | ||
_PyFloat_DebugMallocStats(FILE *out) | ||
{ | ||
#if PyFloat_MAXFREELIST > 0 | ||
#ifdef WITH_FREELISTS | ||
struct _Py_float_state *state = get_float_state(); | ||
_PyDebugAllocatorStats(out, | ||
"free PyFloatObject", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,6 @@ void | |
_PyGC_ClearAllFreeLists(PyInterpreterState *interp) | ||
{ | ||
_PyTuple_ClearFreeList(interp); | ||
_PyFloat_ClearFreeList(interp); | ||
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. Integrated with _Py_ClearFreeLists |
||
_PyDict_ClearFreeList(interp); | ||
_PyAsyncGen_ClearFreeLists(interp); | ||
_PyContext_ClearFreeList(interp); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,6 @@ void | |
_PyGC_ClearAllFreeLists(PyInterpreterState *interp) | ||
{ | ||
_PyTuple_ClearFreeList(interp); | ||
_PyFloat_ClearFreeList(interp); | ||
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. Integrated with _Py_ClearFreeLists |
||
_PyDict_ClearFreeList(interp); | ||
_PyAsyncGen_ClearFreeLists(interp); | ||
_PyContext_ClearFreeList(interp); | ||
|
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.
Why not use the same naming scheme? The list freelist state member is named
list
.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.
Because float is reserved name?
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.
If we decide to change the naming schme, list should be changed. WDYT?
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.
I think that the naming of a struct and its members is an important part of API design. Having a consistent scheme makes it easier to read and review code. I would suggest use a naming scheme for the freelist struct and its members. Up to you :)
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.
Totally agree, I will create a seperate PR :)