Skip to content

Commit 4a1cf66

Browse files
authored
gh-117657: Fix small issues with instrumentation and TSAN (#118064)
Small TSAN fixups for instrumentation
1 parent 1f16b4c commit 4a1cf66

File tree

7 files changed

+25
-13
lines changed

7 files changed

+25
-13
lines changed

Include/internal/pycore_pyatomic_ft_wrappers.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ extern "C" {
3939
_Py_atomic_load_uint8(&value)
4040
#define FT_ATOMIC_STORE_UINT8(value, new_value) \
4141
_Py_atomic_store_uint8(&value, new_value)
42+
#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) \
43+
_Py_atomic_load_uint8_relaxed(&value)
44+
#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) \
45+
_Py_atomic_load_uint16_relaxed(&value)
4246
#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) \
4347
_Py_atomic_store_ptr_relaxed(&value, new_value)
4448
#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) \
@@ -49,7 +53,8 @@ extern "C" {
4953
_Py_atomic_store_ssize_relaxed(&value, new_value)
5054
#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) \
5155
_Py_atomic_store_uint8_relaxed(&value, new_value)
52-
56+
#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) \
57+
_Py_atomic_store_uint16_relaxed(&value, new_value)
5358
#else
5459
#define FT_ATOMIC_LOAD_PTR(value) value
5560
#define FT_ATOMIC_STORE_PTR(value, new_value) value = new_value
@@ -62,12 +67,14 @@ extern "C" {
6267
#define FT_ATOMIC_LOAD_PTR_RELAXED(value) value
6368
#define FT_ATOMIC_LOAD_UINT8(value) value
6469
#define FT_ATOMIC_STORE_UINT8(value, new_value) value = new_value
70+
#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) value
71+
#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) value
6572
#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value
6673
#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) value = new_value
6774
#define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) value = new_value
6875
#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value
6976
#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) value = new_value
70-
77+
#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) value = new_value
7178
#endif
7279

7380
#ifdef __cplusplus

Objects/genobject.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
1212
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
1313
#include "pycore_opcode_utils.h" // RESUME_AFTER_YIELD_FROM
14+
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_*
1415
#include "pycore_pyerrors.h" // _PyErr_ClearExcState()
1516
#include "pycore_pystate.h" // _PyThreadState_GET()
1617

@@ -329,10 +330,11 @@ gen_close_iter(PyObject *yf)
329330
static inline bool
330331
is_resume(_Py_CODEUNIT *instr)
331332
{
333+
uint8_t code = FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.code);
332334
return (
333-
instr->op.code == RESUME ||
334-
instr->op.code == RESUME_CHECK ||
335-
instr->op.code == INSTRUMENTED_RESUME
335+
code == RESUME ||
336+
code == RESUME_CHECK ||
337+
code == INSTRUMENTED_RESUME
336338
);
337339
}
338340

Python/bytecodes.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "pycore_object.h" // _PyObject_GC_TRACK()
2121
#include "pycore_opcode_metadata.h" // uop names
2222
#include "pycore_opcode_utils.h" // MAKE_FUNCTION_*
23-
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_ACQUIRE
23+
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_*
2424
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
2525
#include "pycore_pystate.h" // _PyInterpreterState_GET()
2626
#include "pycore_range.h" // _PyRangeIterObject
@@ -163,7 +163,7 @@ dummy_func(
163163
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
164164
CHECK_EVAL_BREAKER();
165165
}
166-
this_instr->op.code = RESUME_CHECK;
166+
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK);
167167
}
168168
}
169169

Python/ceval.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "pycore_opcode_metadata.h" // EXTRA_CASES
2121
#include "pycore_optimizer.h" // _PyUOpExecutor_Type
2222
#include "pycore_opcode_utils.h" // MAKE_FUNCTION_*
23-
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_ACQUIRE
23+
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_*
2424
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
2525
#include "pycore_pystate.h" // _PyInterpreterState_GET()
2626
#include "pycore_range.h" // _PyRangeIterObject

Python/ceval_macros.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ GETITEM(PyObject *v, Py_ssize_t i) {
162162
/* The integer overflow is checked by an assertion below. */
163163
#define INSTR_OFFSET() ((int)(next_instr - _PyCode_CODE(_PyFrame_GetCode(frame))))
164164
#define NEXTOPARG() do { \
165-
_Py_CODEUNIT word = *next_instr; \
165+
_Py_CODEUNIT word = {.cache = FT_ATOMIC_LOAD_UINT16_RELAXED(*(uint16_t*)next_instr)}; \
166166
opcode = word.op.code; \
167167
oparg = word.op.arg; \
168168
} while (0)

Python/generated_cases.c.h

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/instrumentation.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,10 @@ de_instrument(PyCodeObject *code, int i, int event)
626626
return;
627627
}
628628
CHECK(_PyOpcode_Deopt[deinstrumented] == deinstrumented);
629-
*opcode_ptr = deinstrumented;
629+
FT_ATOMIC_STORE_UINT8_RELAXED(*opcode_ptr, deinstrumented);
630630
if (_PyOpcode_Caches[deinstrumented]) {
631-
instr[1].counter = adaptive_counter_warmup();
631+
FT_ATOMIC_STORE_UINT16_RELAXED(instr[1].counter.as_counter,
632+
adaptive_counter_warmup().as_counter);
632633
}
633634
}
634635

@@ -703,8 +704,10 @@ instrument(PyCodeObject *code, int i)
703704
int deopt = _PyOpcode_Deopt[opcode];
704705
int instrumented = INSTRUMENTED_OPCODES[deopt];
705706
assert(instrumented);
706-
*opcode_ptr = instrumented;
707+
FT_ATOMIC_STORE_UINT8_RELAXED(*opcode_ptr, instrumented);
707708
if (_PyOpcode_Caches[deopt]) {
709+
FT_ATOMIC_STORE_UINT16_RELAXED(instr[1].counter.as_counter,
710+
adaptive_counter_warmup().as_counter);
708711
instr[1].counter = adaptive_counter_warmup();
709712
}
710713
}

0 commit comments

Comments
 (0)