pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/f728f7242c6008a16daaa5dde8e1db786857c50e

97560d244c08.css" /> gh-111968: Use per-thread freelists for float in free-threading (gh-1… · python/cpython@f728f72 · GitHub
Skip to content

Commit f728f72

Browse files
authored
gh-111968: Use per-thread freelists for float in free-threading (gh-113886)
1 parent a0c9cf9 commit f728f72

File tree

9 files changed

+43
-59
lines changed

9 files changed

+43
-59
lines changed

Include/internal/pycore_floatobject.h

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11-
11+
#include "pycore_freelist.h" // _PyFreeListState
1212
#include "pycore_unicodeobject.h" // _PyUnicodeWriter
1313

1414
/* runtime lifecycle */
1515

1616
extern void _PyFloat_InitState(PyInterpreterState *);
1717
extern PyStatus _PyFloat_InitTypes(PyInterpreterState *);
18-
extern void _PyFloat_Fini(PyInterpreterState *);
18+
extern void _PyFloat_Fini(_PyFreeListState *);
1919
extern void _PyFloat_FiniType(PyInterpreterState *);
2020

2121

@@ -33,24 +33,7 @@ struct _Py_float_runtime_state {
3333
};
3434

3535

36-
#ifndef WITH_FREELISTS
37-
// without freelists
38-
# define PyFloat_MAXFREELIST 0
39-
#endif
40-
41-
#ifndef PyFloat_MAXFREELIST
42-
# define PyFloat_MAXFREELIST 100
43-
#endif
4436

45-
struct _Py_float_state {
46-
#if PyFloat_MAXFREELIST > 0
47-
/* Special free list
48-
free_list is a singly-linked list of available PyFloatObjects,
49-
linked via abuse of their ob_type members. */
50-
int numfree;
51-
PyFloatObject *free_list;
52-
#endif
53-
};
5437

5538
void _PyFloat_ExactDealloc(PyObject *op);
5639

Include/internal/pycore_freelist.h

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,34 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11-
#ifndef WITH_FREELISTS
12-
// without freelists
13-
# define PyList_MAXFREELIST 0
14-
#endif
15-
16-
/* Empty list reuse scheme to save calls to malloc and free */
17-
#ifndef PyList_MAXFREELIST
11+
#ifdef WITH_FREELISTS
12+
// with freelists
1813
# define PyList_MAXFREELIST 80
14+
# define PyFloat_MAXFREELIST 100
15+
#else
16+
# define PyList_MAXFREELIST 0
17+
# define PyFloat_MAXFREELIST 0
1918
#endif
2019

2120
struct _Py_list_state {
22-
#if PyList_MAXFREELIST > 0
21+
#ifdef WITH_FREELISTS
2322
PyListObject *free_list[PyList_MAXFREELIST];
2423
int numfree;
2524
#endif
2625
};
2726

27+
struct _Py_float_state {
28+
#ifdef WITH_FREELISTS
29+
/* Special free list
30+
free_list is a singly-linked list of available PyFloatObjects,
31+
linked via abuse of their ob_type members. */
32+
int numfree;
33+
PyFloatObject *free_list;
34+
#endif
35+
};
36+
2837
typedef struct _Py_freelist_state {
38+
struct _Py_float_state float_state;
2939
struct _Py_list_state list;
3040
} _PyFreeListState;
3141

Include/internal/pycore_gc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ extern PyObject *_PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs);
243243
extern void _PyGC_ClearAllFreeLists(PyInterpreterState *interp);
244244
extern void _Py_ClearFreeLists(_PyFreeListState *state, int is_finalization);
245245
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
246-
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
246+
extern void _PyFloat_ClearFreeList(_PyFreeListState *state, int is_finalization);
247247
extern void _PyList_ClearFreeList(_PyFreeListState *state, int is_finalization);
248248
extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
249249
extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);

Include/internal/pycore_interp.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ struct _is {
184184
#endif
185185
struct _py_object_state object_state;
186186
struct _Py_unicode_state unicode;
187-
struct _Py_float_state float_state;
188187
struct _Py_long_state long_state;
189188
struct _dtoa_state dtoa;
190189
struct _py_func_state func_state;

Objects/floatobject.c

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,13 @@ class float "PyObject *" "&PyFloat_Type"
2626

2727
#include "clinic/floatobject.c.h"
2828

29-
#ifndef PyFloat_MAXFREELIST
30-
# define PyFloat_MAXFREELIST 100
31-
#endif
32-
33-
34-
#if PyFloat_MAXFREELIST > 0
29+
#ifdef WITH_FREELISTS
3530
static struct _Py_float_state *
3631
get_float_state(void)
3732
{
38-
PyInterpreterState *interp = _PyInterpreterState_GET();
39-
return &interp->float_state;
33+
_PyFreeListState *state = _PyFreeListState_GET();
34+
assert(state != NULL);
35+
return &state->float_state;
4036
}
4137
#endif
4238

@@ -132,7 +128,7 @@ PyObject *
132128
PyFloat_FromDouble(double fval)
133129
{
134130
PyFloatObject *op;
135-
#if PyFloat_MAXFREELIST > 0
131+
#ifdef WITH_FREELISTS
136132
struct _Py_float_state *state = get_float_state();
137133
op = state->free_list;
138134
if (op != NULL) {
@@ -252,13 +248,9 @@ _PyFloat_ExactDealloc(PyObject *obj)
252248
{
253249
assert(PyFloat_CheckExact(obj));
254250
PyFloatObject *op = (PyFloatObject *)obj;
255-
#if PyFloat_MAXFREELIST > 0
251+
#ifdef WITH_FREELISTS
256252
struct _Py_float_state *state = get_float_state();
257-
#ifdef Py_DEBUG
258-
// float_dealloc() must not be called after _PyFloat_Fini()
259-
assert(state->numfree != -1);
260-
#endif
261-
if (state->numfree >= PyFloat_MAXFREELIST) {
253+
if (state->numfree >= PyFloat_MAXFREELIST || state->numfree < 0) {
262254
PyObject_Free(op);
263255
return;
264256
}
@@ -275,7 +267,7 @@ static void
275267
float_dealloc(PyObject *op)
276268
{
277269
assert(PyFloat_Check(op));
278-
#if PyFloat_MAXFREELIST > 0
270+
#ifdef WITH_FREELISTS
279271
if (PyFloat_CheckExact(op)) {
280272
_PyFloat_ExactDealloc(op);
281273
}
@@ -2002,29 +1994,30 @@ _PyFloat_InitTypes(PyInterpreterState *interp)
20021994
}
20031995

20041996
void
2005-
_PyFloat_ClearFreeList(PyInterpreterState *interp)
1997+
_PyFloat_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization)
20061998
{
2007-
#if PyFloat_MAXFREELIST > 0
2008-
struct _Py_float_state *state = &interp->float_state;
1999+
#ifdef WITH_FREELISTS
2000+
struct _Py_float_state *state = &freelist_state->float_state;
20092001
PyFloatObject *f = state->free_list;
20102002
while (f != NULL) {
20112003
PyFloatObject *next = (PyFloatObject*) Py_TYPE(f);
20122004
PyObject_Free(f);
20132005
f = next;
20142006
}
20152007
state->free_list = NULL;
2016-
state->numfree = 0;
2008+
if (is_finalization) {
2009+
state->numfree = -1;
2010+
}
2011+
else {
2012+
state->numfree = 0;
2013+
}
20172014
#endif
20182015
}
20192016

20202017
void
2021-
_PyFloat_Fini(PyInterpreterState *interp)
2018+
_PyFloat_Fini(_PyFreeListState *state)
20222019
{
2023-
_PyFloat_ClearFreeList(interp);
2024-
#if defined(Py_DEBUG) && PyFloat_MAXFREELIST > 0
2025-
struct _Py_float_state *state = &interp->float_state;
2026-
state->numfree = -1;
2027-
#endif
2020+
_PyFloat_ClearFreeList(state, 1);
20282021
}
20292022

20302023
void
@@ -2037,7 +2030,7 @@ _PyFloat_FiniType(PyInterpreterState *interp)
20372030
void
20382031
_PyFloat_DebugMallocStats(FILE *out)
20392032
{
2040-
#if PyFloat_MAXFREELIST > 0
2033+
#ifdef WITH_FREELISTS
20412034
struct _Py_float_state *state = get_float_state();
20422035
_PyDebugAllocatorStats(out,
20432036
"free PyFloatObject",

Python/gc_free_threading.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ void
1515
_PyGC_ClearAllFreeLists(PyInterpreterState *interp)
1616
{
1717
_PyTuple_ClearFreeList(interp);
18-
_PyFloat_ClearFreeList(interp);
1918
_PyDict_ClearFreeList(interp);
2019
_PyAsyncGen_ClearFreeLists(interp);
2120
_PyContext_ClearFreeList(interp);

Python/gc_gil.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ void
1212
_PyGC_ClearAllFreeLists(PyInterpreterState *interp)
1313
{
1414
_PyTuple_ClearFreeList(interp);
15-
_PyFloat_ClearFreeList(interp);
1615
_PyDict_ClearFreeList(interp);
1716
_PyAsyncGen_ClearFreeLists(interp);
1817
_PyContext_ClearFreeList(interp);

Python/pylifecycle.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,10 +1757,10 @@ finalize_interp_types(PyInterpreterState *interp)
17571757
_PySlice_Fini(interp);
17581758

17591759
_PyUnicode_Fini(interp);
1760-
_PyFloat_Fini(interp);
17611760

17621761
_PyFreeListState *state = _PyFreeListState_GET();
17631762
_PyList_Fini(state);
1763+
_PyFloat_Fini(state);
17641764

17651765
#ifdef Py_DEBUG
17661766
_PyStaticObjects_CheckRefcnt(interp);

Python/pystate.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,7 @@ clear_datastack(PyThreadState *tstate)
14581458
void
14591459
_Py_ClearFreeLists(_PyFreeListState *state, int is_finalization)
14601460
{
1461+
_PyFloat_ClearFreeList(state, is_finalization);
14611462
_PyList_ClearFreeList(state, is_finalization);
14621463
}
14631464

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy