Skip to content

Commit 232f97a

Browse files
committed
Add conditional compilation for critical sections
1 parent e16ea10 commit 232f97a

File tree

4 files changed

+67
-25
lines changed

4 files changed

+67
-25
lines changed

meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,12 @@ else
4545
endif
4646

4747
cy = meson.get_compiler('cython')
48+
cdata = configuration_data()
4849
if cy.version().version_compare('>=3.1.0')
4950
add_project_arguments('-Xfreethreading_compatible=true', language: 'cython')
51+
cdata.set('freethreading_compatible', '1')
52+
else
53+
cdata.set('freethreading_compatible', '0')
5054
endif
5155

5256
# Needed by pandas.test() when it looks for the pytest ini options
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Autogenerated file containing Cython compile-time defines
2+
3+
DEF CYTHON_COMPATIBLE_WITH_FREE_THREADING = @freethreading_compatible@

pandas/_libs/internals.pyx

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@ from collections import defaultdict
33
cimport cython
44
from cpython.object cimport PyObject
55
from cpython.pyport cimport PY_SSIZE_T_MAX
6-
from cpython.ref cimport Py_DECREF
76
from cpython.slice cimport PySlice_GetIndicesEx
8-
from cpython.weakref cimport (
9-
PyWeakref_GetRef,
10-
PyWeakref_NewRef,
11-
)
7+
from cpython.weakref cimport PyWeakref_NewRef
128
from cython cimport Py_ssize_t
139

1410
import numpy as np
@@ -30,6 +26,14 @@ from pandas._libs.util cimport (
3026
is_integer_object,
3127
)
3228

29+
include "free_threading_config.pxi"
30+
31+
IF CYTHON_COMPATIBLE_WITH_FREE_THREADING:
32+
from cpython.weakref cimport PyWeakref_GetRef
33+
from cpython.ref cimport Py_DECREF
34+
ELSE:
35+
from cpython.weakref cimport PyWeakref_GetObject
36+
3337

3438
cdef extern from "Python.h":
3539
PyObject* Py_None
@@ -909,24 +913,35 @@ cdef class BlockValuesRefs:
909913
# if force=False. Clearing for every insertion causes slowdowns if
910914
# all these objects stay alive, e.g. df.items() for wide DataFrames
911915
# see GH#55245 and GH#55008
912-
cdef PyObject* pobj
913-
cdef bint status
916+
IF CYTHON_COMPATIBLE_WITH_FREE_THREADING:
917+
cdef PyObject* pobj
918+
cdef bint status
914919

915920
if force or len(self.referenced_blocks) > self.clear_counter:
916-
new_referenced_blocks = []
917-
for ref in self.referenced_blocks:
918-
status = PyWeakref_GetRef(ref, &pobj)
919-
if status == 1:
920-
new_referenced_blocks.append(ref)
921-
Py_DECREF(<object>pobj)
922-
self.referenced_blocks = new_referenced_blocks
921+
IF CYTHON_COMPATIBLE_WITH_FREE_THREADING:
922+
new_referenced_blocks = []
923+
for ref in self.referenced_blocks:
924+
status = PyWeakref_GetRef(ref, &pobj)
925+
if status == 1:
926+
new_referenced_blocks.append(ref)
927+
Py_DECREF(<object>pobj)
928+
self.referenced_blocks = new_referenced_blocks
929+
ELSE:
930+
self.referenced_blocks = [
931+
ref for ref in self.referenced_blocks
932+
if PyWeakref_GetObject(ref) != Py_None
933+
]
923934

924935
nr_of_refs = len(self.referenced_blocks)
925936
if nr_of_refs < self.clear_counter // 2:
926937
self.clear_counter = max(self.clear_counter // 2, 500)
927938
elif nr_of_refs > self.clear_counter:
928939
self.clear_counter = max(self.clear_counter * 2, nr_of_refs)
929940

941+
cpdef _add_reference_maybe_locked(self, Block blk):
942+
self._clear_dead_references()
943+
self.referenced_blocks.append(PyWeakref_NewRef(blk, None))
944+
930945
cpdef add_reference(self, Block blk):
931946
"""Adds a new reference to our reference collection.
932947
@@ -935,9 +950,15 @@ cdef class BlockValuesRefs:
935950
blk : Block
936951
The block that the new references should point to.
937952
"""
938-
with cython.critical_section(self):
939-
self._clear_dead_references()
940-
self.referenced_blocks.append(PyWeakref_NewRef(blk, None))
953+
IF CYTHON_COMPATIBLE_WITH_FREE_THREADING:
954+
with cython.critical_section(self):
955+
self._add_reference_maybe_locked(blk)
956+
ELSE:
957+
self._add_reference_maybe_locked(blk)
958+
959+
def _add_index_reference_maybe_locked(self, index: object) -> None:
960+
self._clear_dead_references()
961+
self.referenced_blocks.append(PyWeakref_NewRef(index, None))
941962

942963
def add_index_reference(self, index: object) -> None:
943964
"""Adds a new reference to our reference collection when creating an index.
@@ -947,9 +968,16 @@ cdef class BlockValuesRefs:
947968
index : Index
948969
The index that the new reference should point to.
949970
"""
950-
with cython.critical_section(self):
951-
self._clear_dead_references()
952-
self.referenced_blocks.append(PyWeakref_NewRef(index, None))
971+
IF CYTHON_COMPATIBLE_WITH_FREE_THREADING:
972+
with cython.critical_section(self):
973+
self._add_index_reference_maybe_locked(index)
974+
ELSE:
975+
self._add_index_reference_maybe_locked(index)
976+
977+
def _has_reference_maybe_locked(self) -> bool:
978+
self._clear_dead_references(force=True)
979+
# Checking for more references than block pointing to itself
980+
return len(self.referenced_blocks) > 1
953981

954982
def has_reference(self) -> bool:
955983
"""Checks if block has foreign references.
@@ -961,8 +989,8 @@ cdef class BlockValuesRefs:
961989
-------
962990
bool
963991
"""
964-
with cython.critical_section(self):
965-
self._clear_dead_references(force=True)
966-
# Checking for more references than block pointing to itself
967-
has_reference = len(self.referenced_blocks) > 1
968-
return has_reference
992+
IF CYTHON_COMPATIBLE_WITH_FREE_THREADING:
993+
with cython.critical_section(self):
994+
return self._has_reference_maybe_locked()
995+
ELSE:
996+
return self._has_reference_maybe_locked()

pandas/_libs/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ _khash_primitive_helper_dep = declare_dependency(
5050
sources: _khash_primitive_helper,
5151
)
5252

53+
_free_threading_config = configure_file(
54+
input: 'free_threading_config.pxi.in',
55+
output: 'free_threading_config.pxi',
56+
configuration: cdata,
57+
install: false
58+
)
59+
5360
subdir('tslibs')
5461

5562
libs_sources = {

0 commit comments

Comments
 (0)