Skip to content

Commit d715d18

Browse files
committed
Small TSAN fixups for instrumentation
1 parent 2aa11cc commit d715d18

File tree

7 files changed

+29
-8
lines changed

7 files changed

+29
-8
lines changed

Include/internal/pycore_pyatomic_ft_wrappers.h

+12
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,32 @@ extern "C" {
2626
_Py_atomic_load_ssize_relaxed(&value)
2727
#define FT_ATOMIC_STORE_PTR(value, new_value) \
2828
_Py_atomic_store_ptr(&value, new_value)
29+
#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) \
30+
_Py_atomic_load_uint8_relaxed(&value)
31+
#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) \
32+
_Py_atomic_load_uint16_relaxed(&value)
2933
#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) \
3034
_Py_atomic_store_ptr_relaxed(&value, new_value)
3135
#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) \
3236
_Py_atomic_store_ptr_release(&value, new_value)
3337
#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) \
3438
_Py_atomic_store_ssize_relaxed(&value, new_value)
39+
#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) \
40+
_Py_atomic_store_uint8_relaxed(&value, new_value)
41+
#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) \
42+
_Py_atomic_store_uint16_relaxed(&value, new_value)
3543
#else
3644
#define FT_ATOMIC_LOAD_PTR(value) value
3745
#define FT_ATOMIC_LOAD_SSIZE(value) value
3846
#define FT_ATOMIC_LOAD_SSIZE_RELAXED(value) value
3947
#define FT_ATOMIC_STORE_PTR(value, new_value) value = new_value
48+
#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) value
49+
#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) value
4050
#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value
4151
#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) value = new_value
4252
#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value
53+
#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) value = new_value
54+
#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) value = new_value
4355
#endif
4456

4557
#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-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +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_*
2324
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
2425
#include "pycore_pystate.h" // _PyInterpreterState_GET()
2526
#include "pycore_range.h" // _PyRangeIterObject
@@ -161,7 +162,7 @@ dummy_func(
161162
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
162163
CHECK_EVAL_BREAKER();
163164
}
164-
this_instr->op.code = RESUME_CHECK;
165+
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK);
165166
}
166167
}
167168

Python/ceval.c

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +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_*
2324
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
2425
#include "pycore_pystate.h" // _PyInterpreterState_GET()
2526
#include "pycore_range.h" // _PyRangeIterObject

Python/ceval_macros.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ GETITEM(PyObject *v, Py_ssize_t i) {
150150
/* The integer overflow is checked by an assertion below. */
151151
#define INSTR_OFFSET() ((int)(next_instr - _PyCode_CODE(_PyFrame_GetCode(frame))))
152152
#define NEXTOPARG() do { \
153-
_Py_CODEUNIT word = *next_instr; \
153+
_Py_CODEUNIT word = {.cache = FT_ATOMIC_LOAD_UINT16_RELAXED(*(uint16_t*)next_instr)}; \
154154
opcode = word.op.code; \
155155
oparg = word.op.arg; \
156156
} 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

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "pycore_namespace.h"
1414
#include "pycore_object.h"
1515
#include "pycore_opcode_metadata.h" // IS_VALID_OPCODE, _PyOpcode_Caches
16+
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_UINTPTR_RELEASE
1617
#include "pycore_pyerrors.h"
1718
#include "pycore_pystate.h" // _PyInterpreterState_GET()
1819

@@ -588,9 +589,10 @@ de_instrument(PyCodeObject *code, int i, int event)
588589
return;
589590
}
590591
CHECK(_PyOpcode_Deopt[deinstrumented] == deinstrumented);
591-
*opcode_ptr = deinstrumented;
592+
FT_ATOMIC_STORE_UINT8_RELAXED(*opcode_ptr, deinstrumented);
592593
if (_PyOpcode_Caches[deinstrumented]) {
593-
instr[1].counter = adaptive_counter_warmup();
594+
FT_ATOMIC_STORE_UINT16_RELAXED(instr[1].counter.as_counter,
595+
adaptive_counter_warmup().as_counter);
594596
}
595597
}
596598

@@ -665,8 +667,11 @@ instrument(PyCodeObject *code, int i)
665667
int deopt = _PyOpcode_Deopt[opcode];
666668
int instrumented = INSTRUMENTED_OPCODES[deopt];
667669
assert(instrumented);
670+
FT_ATOMIC_STORE_UINT8_RELAXED(*opcode_ptr, instrumented);
668671
*opcode_ptr = instrumented;
669672
if (_PyOpcode_Caches[deopt]) {
673+
FT_ATOMIC_STORE_UINT16_RELAXED(instr[1].counter.as_counter,
674+
adaptive_counter_warmup().as_counter);
670675
instr[1].counter = adaptive_counter_warmup();
671676
}
672677
}

0 commit comments

Comments
 (0)