Skip to content

Commit 8390e48

Browse files
committed
Add a common interface for FT-only locks
1 parent 525784a commit 8390e48

9 files changed

Lines changed: 39 additions & 86 deletions

File tree

Include/internal/pycore_pyatomic_ft_wrappers.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ extern "C" {
111111
_Py_atomic_load_ullong_relaxed(&value)
112112
#define FT_ATOMIC_ADD_SSIZE(value, new_value) \
113113
(void)_Py_atomic_add_ssize(&value, new_value)
114+
#define FT_MUTEX_LOCK(lock) PyMutex_Lock(lock)
115+
#define FT_MUTEX_UNLOCK(lock) PyMutex_Unlock(lock)
114116

115117
#else
116118
#define FT_ATOMIC_LOAD_PTR(value) value
@@ -159,7 +161,8 @@ extern "C" {
159161
#define FT_ATOMIC_LOAD_ULLONG_RELAXED(value) value
160162
#define FT_ATOMIC_STORE_ULLONG_RELAXED(value, new_value) value = new_value
161163
#define FT_ATOMIC_ADD_SSIZE(value, new_value) (void)(value += new_value)
162-
164+
#define FT_MUTEX_LOCK(lock) do {} while (0)
165+
#define FT_MUTEX_UNLOCK(lock) do {} while (0)
163166
#endif
164167

165168
#ifdef __cplusplus

Modules/_ctypes/malloc_closure.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@
3030

3131
#ifdef Py_GIL_DISABLED
3232
static PyMutex malloc_closure_lock;
33-
# define MALLOC_CLOSURE_LOCK() PyMutex_Lock(&malloc_closure_lock)
34-
# define MALLOC_CLOSURE_UNLOCK() PyMutex_Unlock(&malloc_closure_lock)
35-
#else
36-
# define MALLOC_CLOSURE_LOCK() ((void)0)
37-
# define MALLOC_CLOSURE_UNLOCK() ((void)0)
3833
#endif
3934

4035
typedef union _tagITEM {
@@ -120,11 +115,11 @@ void Py_ffi_closure_free(void *p)
120115
}
121116
#endif
122117
#endif
123-
MALLOC_CLOSURE_LOCK();
118+
FT_MUTEX_LOCK(&malloc_closure_lock);
124119
ITEM *item = (ITEM *)p;
125120
item->next = free_list;
126121
free_list = item;
127-
MALLOC_CLOSURE_UNLOCK();
122+
FT_MUTEX_UNLOCK(&malloc_closure_lock);
128123
}
129124

130125
/* return one item from the free list, allocating more if needed */
@@ -143,13 +138,13 @@ void *Py_ffi_closure_alloc(size_t size, void** codeloc)
143138
}
144139
#endif
145140
#endif
146-
MALLOC_CLOSURE_LOCK();
141+
FT_MUTEX_LOCK(&malloc_closure_lock);
147142
ITEM *item;
148143
if (!free_list) {
149144
more_core();
150145
}
151146
if (!free_list) {
152-
MALLOC_CLOSURE_UNLOCK();
147+
FT_MUTEX_UNLOCK(&malloc_closure_lock);
153148
return NULL;
154149
}
155150
item = free_list;
@@ -160,6 +155,6 @@ void *Py_ffi_closure_alloc(size_t size, void** codeloc)
160155
#else
161156
*codeloc = (void *)item;
162157
#endif
163-
MALLOC_CLOSURE_UNLOCK();
158+
FT_MUTEX_UNLOCK(&malloc_closure_lock);
164159
return (void *)item;
165160
}

Objects/codeobject.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -550,16 +550,12 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
550550
co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
551551
co->co_ncellvars = ncellvars;
552552
co->co_nfreevars = nfreevars;
553-
#ifdef Py_GIL_DISABLED
554-
PyMutex_Lock(&interp->func_state.mutex);
555-
#endif
553+
FT_MUTEX_LOCK(&interp->func_state.mutex);
556554
co->co_version = interp->func_state.next_version;
557555
if (interp->func_state.next_version != 0) {
558556
interp->func_state.next_version++;
559557
}
560-
#ifdef Py_GIL_DISABLED
561-
PyMutex_Unlock(&interp->func_state.mutex);
562-
#endif
558+
FT_MUTEX_UNLOCK(&interp->func_state.mutex);
563559
co->_co_monitoring = NULL;
564560
co->_co_instrumentation_version = 0;
565561
/* not set */
@@ -689,7 +685,7 @@ intern_code_constants(struct _PyCodeConstructor *con)
689685
#ifdef Py_GIL_DISABLED
690686
PyInterpreterState *interp = _PyInterpreterState_GET();
691687
struct _py_code_state *state = &interp->code_state;
692-
PyMutex_Lock(&state->mutex);
688+
FT_MUTEX_LOCK(&state->mutex);
693689
#endif
694690
if (intern_strings(con->names) < 0) {
695691
goto error;
@@ -700,15 +696,11 @@ intern_code_constants(struct _PyCodeConstructor *con)
700696
if (intern_strings(con->localsplusnames) < 0) {
701697
goto error;
702698
}
703-
#ifdef Py_GIL_DISABLED
704-
PyMutex_Unlock(&state->mutex);
705-
#endif
699+
FT_MUTEX_UNLOCK(&state->mutex);
706700
return 0;
707701

708702
error:
709-
#ifdef Py_GIL_DISABLED
710-
PyMutex_Unlock(&state->mutex);
711-
#endif
703+
FT_MUTEX_UNLOCK(&state->mutex);
712704
return -1;
713705
}
714706

Objects/unicodeobject.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,6 @@ NOTE: In the interpreter's initialization phase, some globals are currently
114114
# define _PyUnicode_CHECK(op) PyUnicode_Check(op)
115115
#endif
116116

117-
#ifdef Py_GIL_DISABLED
118-
# define LOCK_INTERNED(interp) PyMutex_Lock(&_Py_INTERP_CACHED_OBJECT(interp, interned_mutex))
119-
# define UNLOCK_INTERNED(interp) PyMutex_Unlock(&_Py_INTERP_CACHED_OBJECT(interp, interned_mutex))
120-
#else
121-
# define LOCK_INTERNED(interp)
122-
# define UNLOCK_INTERNED(interp)
123-
#endif
124-
125117
static inline char* _PyUnicode_UTF8(PyObject *op)
126118
{
127119
return FT_ATOMIC_LOAD_PTR_ACQUIRE(_PyCompactUnicodeObject_CAST(op)->utf8);
@@ -15993,13 +15985,13 @@ intern_common(PyInterpreterState *interp, PyObject *s /* stolen */,
1599315985
PyObject *interned = get_interned_dict(interp);
1599415986
assert(interned != NULL);
1599515987

15996-
LOCK_INTERNED(interp);
15988+
FT_MUTEX_LOCK(&_Py_INTERP_CACHED_OBJECT(interp, interned_mutex));
1599715989
PyObject *t;
1599815990
{
1599915991
int res = PyDict_SetDefaultRef(interned, s, s, &t);
1600015992
if (res < 0) {
1600115993
PyErr_Clear();
16002-
UNLOCK_INTERNED(interp);
15994+
FT_MUTEX_UNLOCK(&_Py_INTERP_CACHED_OBJECT(interp, interned_mutex));
1600315995
return s;
1600415996
}
1600515997
else if (res == 1) {
@@ -16009,7 +16001,7 @@ intern_common(PyInterpreterState *interp, PyObject *s /* stolen */,
1600916001
PyUnicode_CHECK_INTERNED(t) == SSTATE_INTERNED_MORTAL) {
1601016002
immortalize_interned(t);
1601116003
}
16012-
UNLOCK_INTERNED(interp);
16004+
FT_MUTEX_UNLOCK(&_Py_INTERP_CACHED_OBJECT(interp, interned_mutex));
1601316005
return t;
1601416006
}
1601516007
else {
@@ -16042,7 +16034,7 @@ intern_common(PyInterpreterState *interp, PyObject *s /* stolen */,
1604216034
immortalize_interned(s);
1604316035
}
1604416036

16045-
UNLOCK_INTERNED(interp);
16037+
FT_MUTEX_UNLOCK(&_Py_INTERP_CACHED_OBJECT(interp, interned_mutex));
1604616038
return s;
1604716039
}
1604816040

Parser/pegen.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -299,22 +299,14 @@ _PyPegen_fill_token(Parser *p)
299299
#define NSTATISTICS _PYPEGEN_NSTATISTICS
300300
#define memo_statistics _PyRuntime.parser.memo_statistics
301301

302-
#ifdef Py_GIL_DISABLED
303-
#define MUTEX_LOCK() PyMutex_Lock(&_PyRuntime.parser.mutex)
304-
#define MUTEX_UNLOCK() PyMutex_Unlock(&_PyRuntime.parser.mutex)
305-
#else
306-
#define MUTEX_LOCK()
307-
#define MUTEX_UNLOCK()
308-
#endif
309-
310302
void
311303
_PyPegen_clear_memo_statistics(void)
312304
{
313-
MUTEX_LOCK();
305+
FT_MUTEX_LOCK(&_PyRuntime.parser.mutex);
314306
for (int i = 0; i < NSTATISTICS; i++) {
315307
memo_statistics[i] = 0;
316308
}
317-
MUTEX_UNLOCK();
309+
FT_MUTEX_UNLOCK(&_PyRuntime.parser.mutex);
318310
}
319311

320312
PyObject *
@@ -325,22 +317,22 @@ _PyPegen_get_memo_statistics(void)
325317
return NULL;
326318
}
327319

328-
MUTEX_LOCK();
320+
FT_MUTEX_LOCK(&_PyRuntime.parser.mutex);
329321
for (int i = 0; i < NSTATISTICS; i++) {
330322
PyObject *value = PyLong_FromLong(memo_statistics[i]);
331323
if (value == NULL) {
332-
MUTEX_UNLOCK();
324+
FT_MUTEX_UNLOCK(&_PyRuntime.parser.mutex);
333325
Py_DECREF(ret);
334326
return NULL;
335327
}
336328
// PyList_SetItem borrows a reference to value.
337329
if (PyList_SetItem(ret, i, value) < 0) {
338-
MUTEX_UNLOCK();
330+
FT_MUTEX_UNLOCK(&_PyRuntime.parser.mutex);
339331
Py_DECREF(ret);
340332
return NULL;
341333
}
342334
}
343-
MUTEX_UNLOCK();
335+
FT_MUTEX_UNLOCK(&_PyRuntime.parser.mutex);
344336
return ret;
345337
}
346338
#endif
@@ -366,9 +358,9 @@ _PyPegen_is_memoized(Parser *p, int type, void *pres)
366358
if (count <= 0) {
367359
count = 1;
368360
}
369-
MUTEX_LOCK();
361+
FT_MUTEX_LOCK(&_PyRuntime.parser.mutex);
370362
memo_statistics[type] += count;
371-
MUTEX_UNLOCK();
363+
FT_MUTEX_UNLOCK(&_PyRuntime.parser.mutex);
372364
}
373365
#endif
374366
p->mark = m->mark;

Python/ceval_gil.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -907,13 +907,10 @@ unsignal_pending_calls(PyThreadState *tstate, PyInterpreterState *interp)
907907
static void
908908
clear_pending_handling_thread(struct _pending_calls *pending)
909909
{
910-
#ifdef Py_GIL_DISABLED
911-
PyMutex_Lock(&pending->mutex);
910+
FT_MUTEX_LOCK(&pending->mutex);
912911
pending->handling_thread = NULL;
913-
PyMutex_Unlock(&pending->mutex);
914-
#else
912+
FT_MUTEX_UNLOCK(&pending->mutex);
915913
pending->handling_thread = NULL;
916-
#endif
917914
}
918915

919916
static int

Python/codecs.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,10 @@ int PyCodec_Register(PyObject *search_function)
4040
PyErr_SetString(PyExc_TypeError, "argument must be callable");
4141
goto onError;
4242
}
43-
#ifdef Py_GIL_DISABLED
44-
PyMutex_Lock(&interp->codecs.search_path_mutex);
45-
#endif
43+
FT_MUTEX_LOCK(&interp->codecs.search_path_mutex);
4644
int ret = PyList_Append(interp->codecs.search_path, search_function);
47-
#ifdef Py_GIL_DISABLED
48-
PyMutex_Unlock(&interp->codecs.search_path_mutex);
49-
#endif
45+
FT_MUTEX_UNLOCK(&interp->codecs.search_path_mutex);
46+
5047
return ret;
5148

5249
onError:
@@ -66,19 +63,15 @@ PyCodec_Unregister(PyObject *search_function)
6663
PyObject *codec_search_path = interp->codecs.search_path;
6764
assert(PyList_CheckExact(codec_search_path));
6865
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(codec_search_path); i++) {
69-
#ifdef Py_GIL_DISABLED
70-
PyMutex_Lock(&interp->codecs.search_path_mutex);
71-
#endif
66+
FT_MUTEX_LOCK(&interp->codecs.search_path_mutex);
7267
PyObject *item = PyList_GetItemRef(codec_search_path, i);
7368
int ret = 1;
7469
if (item == search_function) {
7570
// We hold a reference to the item, so its destructor can't run
7671
// while we hold search_path_mutex.
7772
ret = PyList_SetSlice(codec_search_path, i, i+1, NULL);
7873
}
79-
#ifdef Py_GIL_DISABLED
80-
PyMutex_Unlock(&interp->codecs.search_path_mutex);
81-
#endif
74+
FT_MUTEX_UNLOCK(&interp->codecs.search_path_mutex);
8275
Py_DECREF(item);
8376
if (ret != 1) {
8477
assert(interp->codecs.search_cache != NULL);

Python/legacy_tracing.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,6 @@ typedef struct _PyLegacyEventHandler {
2020

2121
#define _PyLegacyEventHandler_CAST(op) ((_PyLegacyEventHandler *)(op))
2222

23-
#ifdef Py_GIL_DISABLED
24-
#define LOCK_SETUP() PyMutex_Lock(&_PyRuntime.ceval.sys_trace_profile_mutex);
25-
#define UNLOCK_SETUP() PyMutex_Unlock(&_PyRuntime.ceval.sys_trace_profile_mutex);
26-
#else
27-
#define LOCK_SETUP()
28-
#define UNLOCK_SETUP()
29-
#endif
3023
/* The Py_tracefunc function expects the following arguments:
3124
* obj: the trace object (PyObject *)
3225
* frame: the current frame (PyFrameObject *)
@@ -509,9 +502,9 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
509502

510503
// needs to be decref'd outside of the lock
511504
PyObject *old_profileobj;
512-
LOCK_SETUP();
505+
FT_MUTEX_LOCK(&_PyRuntime.ceval.sys_trace_profile_mutex);
513506
Py_ssize_t profiling_threads = setup_profile(tstate, func, arg, &old_profileobj);
514-
UNLOCK_SETUP();
507+
FT_MUTEX_UNLOCK(&_PyRuntime.ceval.sys_trace_profile_mutex);
515508
Py_XDECREF(old_profileobj);
516509

517510
uint32_t events = 0;
@@ -605,10 +598,10 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
605598
}
606599
// needs to be decref'd outside of the lock
607600
PyObject *old_traceobj;
608-
LOCK_SETUP();
601+
FT_MUTEX_LOCK(&_PyRuntime.ceval.sys_trace_profile_mutex);
609602
assert(tstate->interp->sys_tracing_threads >= 0);
610603
Py_ssize_t tracing_threads = setup_tracing(tstate, func, arg, &old_traceobj);
611-
UNLOCK_SETUP();
604+
FT_MUTEX_UNLOCK(&_PyRuntime.ceval.sys_trace_profile_mutex);
612605
Py_XDECREF(old_traceobj);
613606
if (tracing_threads < 0) {
614607
return -1;

Python/pystate.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,9 +1689,7 @@ PyThreadState_Clear(PyThreadState *tstate)
16891689
"PyThreadState_Clear: warning: thread still has a generator\n");
16901690
}
16911691

1692-
#ifdef Py_GIL_DISABLED
1693-
PyMutex_Lock(&_PyRuntime.ceval.sys_trace_profile_mutex);
1694-
#endif
1692+
FT_MUTEX_LOCK(&_PyRuntime.ceval.sys_trace_profile_mutex);
16951693

16961694
if (tstate->c_profilefunc != NULL) {
16971695
tstate->interp->sys_profiling_threads--;
@@ -1702,9 +1700,7 @@ PyThreadState_Clear(PyThreadState *tstate)
17021700
tstate->c_tracefunc = NULL;
17031701
}
17041702

1705-
#ifdef Py_GIL_DISABLED
1706-
PyMutex_Unlock(&_PyRuntime.ceval.sys_trace_profile_mutex);
1707-
#endif
1703+
FT_MUTEX_UNLOCK(&_PyRuntime.ceval.sys_trace_profile_mutex);
17081704

17091705
Py_CLEAR(tstate->c_profileobj);
17101706
Py_CLEAR(tstate->c_traceobj);

0 commit comments

Comments
 (0)