Skip to content

Commit 78d3595

Browse files
committed
avoid Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST
1 parent 8b12e0f commit 78d3595

3 files changed

Lines changed: 89 additions & 62 deletions

File tree

Include/cpython/critical_section.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ PyCriticalSection2_End(PyCriticalSection2 *c);
8585
#ifndef Py_GIL_DISABLED
8686
# define Py_BEGIN_CRITICAL_SECTION(op) \
8787
{
88-
# define Py_EXIT_CRITICAL_SECTION()
8988
# define Py_END_CRITICAL_SECTION() \
9089
}
9190
# define Py_BEGIN_CRITICAL_SECTION2(a, b) \
@@ -119,10 +118,6 @@ struct PyCriticalSection2 {
119118
PyCriticalSection _py_cs; \
120119
PyCriticalSection_Begin(&_py_cs, _PyObject_CAST(op))
121120

122-
# define Py_EXIT_CRITICAL_SECTION() \
123-
_PyCriticalSection_End(&_py_cs);
124-
125-
126121
# define Py_END_CRITICAL_SECTION() \
127122
PyCriticalSection_End(&_py_cs); \
128123
}

Include/internal/pycore_critical_section.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ extern "C" {
5151
} \
5252
}
5353

54-
# define Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST() \
55-
if (_should_lock_cs) { \
56-
_PyCriticalSection_End(&_cs); \
57-
}
58-
5954
// Asserts that the mutex is locked. The mutex must be held by the
6055
// top-most critical section otherwise there's the possibility
6156
// that the mutex would be swalled out in some code paths.
@@ -83,7 +78,6 @@ extern "C" {
8378
# define Py_BEGIN_CRITICAL_SECTION_MUT(mut) {
8479
# define Py_BEGIN_CRITICAL_SECTION2_MUT(m1, m2) {
8580
# define Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(original) {
86-
# define Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST()
8781
# define Py_END_CRITICAL_SECTION_SEQUENCE_FAST() }
8882
# define _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(mutex)
8983
# define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op)

Modules/_json.c

Lines changed: 89 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,52 @@ encoder_encode_key_value(PyEncoderObject *s, PyUnicodeWriter *writer, bool *firs
16341634
return 0;
16351635
}
16361636

1637+
static inline int
1638+
_encoder_iterate_mapping_lock_held(PyEncoderObject *s, PyUnicodeWriter *writer,
1639+
PyObject *dct, PyObject *items,
1640+
Py_ssize_t indent_level, PyObject *indent_cache,
1641+
PyObject *separator)
1642+
{
1643+
PyObject *key, *value;
1644+
bool first = true;
1645+
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(items); i++) {
1646+
PyObject *item = PyList_GET_ITEM(items, i);
1647+
1648+
if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) {
1649+
PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
1650+
return -1;
1651+
}
1652+
1653+
key = PyTuple_GET_ITEM(item, 0);
1654+
value = PyTuple_GET_ITEM(item, 1);
1655+
if (encoder_encode_key_value(s, writer, &first, dct, key, value,
1656+
indent_level, indent_cache,
1657+
separator) < 0) {
1658+
return -1;
1659+
}
1660+
}
1661+
1662+
return 0;
1663+
}
1664+
1665+
static inline int
1666+
_encoder_iterate_dict_lock_held(PyEncoderObject *s, PyUnicodeWriter *writer,
1667+
PyObject *dct, Py_ssize_t indent_level,
1668+
PyObject *indent_cache, PyObject *separator)
1669+
{
1670+
PyObject *key, *value;
1671+
Py_ssize_t pos = 0;
1672+
bool first = true;
1673+
while (PyDict_Next(dct, &pos, &key, &value)) {
1674+
if (encoder_encode_key_value(s, writer, &first, dct, key, value,
1675+
indent_level, indent_cache,
1676+
separator) < 0) {
1677+
return -1;
1678+
}
1679+
}
1680+
return 0;
1681+
}
1682+
16371683
static int
16381684
encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer,
16391685
PyObject *dct,
@@ -1642,8 +1688,6 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer,
16421688
/* Encode Python dict dct a JSON term */
16431689
PyObject *ident = NULL;
16441690
PyObject *items = NULL;
1645-
PyObject *key, *value;
1646-
bool first = true;
16471691

16481692
if (PyDict_GET_SIZE(dct) == 0) {
16491693
/* Fast path */
@@ -1683,46 +1727,30 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer,
16831727

16841728
if (s->sort_keys || !PyDict_CheckExact(dct)) {
16851729
items = PyMapping_Items(dct);
1686-
if (items == NULL || (s->sort_keys && PyList_Sort(items) < 0))
1730+
if (items == NULL || (s->sort_keys && PyList_Sort(items) < 0)) {
16871731
goto bail;
1732+
}
16881733

1734+
int result;
16891735
Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(items);
1690-
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(items); i++) {
1691-
PyObject *item = PyList_GET_ITEM(items, i);
1692-
1693-
if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) {
1694-
PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
1695-
Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST();
1696-
goto bail;
1697-
}
1698-
1699-
key = PyTuple_GET_ITEM(item, 0);
1700-
value = PyTuple_GET_ITEM(item, 1);
1701-
if (encoder_encode_key_value(s, writer, &first, dct, key, value,
1702-
new_newline_indent,
1703-
current_item_separator) < 0) {
1704-
indent_level, indent_cache,
1705-
separator) < 0)
1706-
//Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST();
1707-
goto bail;
1708-
}
1709-
}
1736+
result = _encoder_iterate_mapping_lock_held(s, writer, dct,
1737+
items, indent_level, indent_cache, separator);
17101738
Py_END_CRITICAL_SECTION_SEQUENCE_FAST();
17111739
Py_CLEAR(items);
1740+
if (result < 0) {
1741+
Py_XDECREF(items);
1742+
goto bail;
1743+
}
17121744

17131745
} else {
1714-
Py_ssize_t pos = 0;
1746+
int result;
17151747
Py_BEGIN_CRITICAL_SECTION(dct);
1716-
while (PyDict_Next(dct, &pos, &key, &value)) {
1717-
if (encoder_encode_key_value(s, writer, &first, dct, key, value,
1718-
indent_level, indent_cache,
1719-
separator) < 0)
1720-
//Py_EXIT_CRITICAL_SECTION();
1721-
1722-
goto bail;
1723-
}
1724-
}
1748+
result = _encoder_iterate_dict_lock_held(s, writer, dct,
1749+
indent_level, indent_cache, separator);
17251750
Py_END_CRITICAL_SECTION();
1751+
if (result < 0) {
1752+
goto bail;
1753+
}
17261754
}
17271755

17281756
if (ident != NULL) {
@@ -1748,25 +1776,40 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer,
17481776
return -1;
17491777
}
17501778

1779+
static inline int
1780+
_encoder_iterate_fast_seq_lock_held(PyEncoderObject *s, PyUnicodeWriter *writer,
1781+
PyObject *seq, PyObject *s_fast,
1782+
Py_ssize_t indent_level, PyObject *indent_cache, PyObject *separator)
1783+
{
1784+
for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) {
1785+
PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i);
1786+
if (i) {
1787+
if (PyUnicodeWriter_WriteStr(writer, separator) < 0) {
1788+
return -1;
1789+
}
1790+
}
1791+
if (encoder_listencode_obj(s, writer, obj, indent_level, indent_cache)) {
1792+
_PyErr_FormatNote("when serializing %T item %zd", seq, i);
1793+
return -1;
1794+
}
1795+
}
1796+
return 0;
1797+
}
1798+
17511799
static int
17521800
encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer,
17531801
PyObject *seq,
17541802
Py_ssize_t indent_level, PyObject *indent_cache)
17551803
{
17561804
PyObject *ident = NULL;
17571805
PyObject *s_fast = NULL;
1758-
Py_ssize_t i;
17591806

1760-
ident = NULL;
1761-
s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence");
1807+
s_fast = PySequence_Fast(seq, "encoder_listencode_list needs a sequence");
17621808
if (s_fast == NULL)
17631809
return -1;
17641810

1765-
Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(seq);
1766-
17671811
if (PySequence_Fast_GET_SIZE(s_fast) == 0) {
17681812
Py_DECREF(s_fast);
1769-
Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST();
17701813
return PyUnicodeWriter_WriteUTF8(writer, "[]", 2);
17711814
}
17721815

@@ -1800,16 +1843,13 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer,
18001843
goto bail;
18011844
}
18021845
}
1803-
for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) {
1804-
PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i);
1805-
if (i) {
1806-
if (PyUnicodeWriter_WriteStr(writer, separator) < 0)
1807-
goto bail;
1808-
}
1809-
if (encoder_listencode_obj(s, writer, obj, indent_level, indent_cache)) {
1810-
_PyErr_FormatNote("when serializing %T item %zd", seq, i);
1811-
goto bail;
1812-
}
1846+
int result;
1847+
Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(seq);
1848+
result = _encoder_iterate_fast_seq_lock_held(s, writer, seq, s_fast,
1849+
indent_level, indent_cache, separator);
1850+
Py_END_CRITICAL_SECTION_SEQUENCE_FAST();
1851+
if (result < -1) {
1852+
goto bail;
18131853
}
18141854
if (ident != NULL) {
18151855
if (PyDict_DelItem(s->markers, ident))
@@ -1828,12 +1868,10 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer,
18281868
goto bail;
18291869
}
18301870
Py_DECREF(s_fast);
1831-
Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST();
18321871
return 0;
18331872

18341873
bail:
18351874
Py_XDECREF(ident);
1836-
Py_END_CRITICAL_SECTION_SEQUENCE_FAST();
18371875
Py_DECREF(s_fast);
18381876
return -1;
18391877
}

0 commit comments

Comments
 (0)