Skip to content

Commit d968323

Browse files
fix: use atomics for started and activity flags (#2019)
* use c11 atomics * add qualifier to activity --------- Co-authored-by: Sam Gross <[email protected]>
1 parent b4edc26 commit d968323

File tree

4 files changed

+19
-14
lines changed

4 files changed

+19
-14
lines changed

coverage/ctracer/tracer.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse
818818
return RET_OK;
819819
#endif
820820

821-
if (!self->started) {
821+
if (!atomic_load(&self->started)) {
822822
/* If CTracer.stop() has been called from another thread, the tracer
823823
is still active in the current thread. Let's deactivate ourselves
824824
now. */
@@ -848,7 +848,7 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse
848848
Py_DECREF(ascii);
849849
#endif
850850

851-
self->activity = TRUE;
851+
atomic_store(&self->activity, TRUE);
852852

853853
switch (what) {
854854
case PyTrace_CALL:
@@ -981,9 +981,10 @@ CTracer_call(CTracer *self, PyObject *args, PyObject *kwds)
981981
static PyObject *
982982
CTracer_start(CTracer *self, PyObject *args_unused)
983983
{
984+
assert(atomic_load(&self->started) == FALSE);
984985
PyEval_SetTrace((Py_tracefunc)CTracer_trace, (PyObject*)self);
985-
self->started = TRUE;
986986
self->tracing_arcs = self->trace_arcs && PyObject_IsTrue(self->trace_arcs);
987+
atomic_store(&self->started, TRUE);
987988

988989
/* start() returns a trace function usable with sys.settrace() */
989990
Py_INCREF(self);
@@ -993,21 +994,19 @@ CTracer_start(CTracer *self, PyObject *args_unused)
993994
static PyObject *
994995
CTracer_stop(CTracer *self, PyObject *args_unused)
995996
{
996-
if (self->started) {
997-
/* Set the started flag only. The actual call to
998-
PyEval_SetTrace(NULL, NULL) is delegated to the callback
999-
itself to ensure that it called from the right thread.
1000-
*/
1001-
self->started = FALSE;
1002-
}
997+
/* Set the started flag only. The actual call to
998+
PyEval_SetTrace(NULL, NULL) is delegated to the callback
999+
itself to ensure that it called from the right thread.
1000+
*/
1001+
atomic_store(&self->started, FALSE);
10031002

10041003
Py_RETURN_NONE;
10051004
}
10061005

10071006
static PyObject *
10081007
CTracer_activity(CTracer *self, PyObject *args_unused)
10091008
{
1010-
if (self->activity) {
1009+
if (atomic_load(&self->activity)) {
10111010
Py_RETURN_TRUE;
10121011
}
10131012
else {
@@ -1018,7 +1017,7 @@ CTracer_activity(CTracer *self, PyObject *args_unused)
10181017
static PyObject *
10191018
CTracer_reset_activity(CTracer *self, PyObject *args_unused)
10201019
{
1021-
self->activity = FALSE;
1020+
atomic_store(&self->activity, FALSE);
10221021
Py_RETURN_NONE;
10231022
}
10241023

coverage/ctracer/tracer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ typedef struct CTracer {
3232
PyObject * disable_plugin;
3333

3434
/* Has the tracer been started? */
35-
BOOL started;
35+
_Atomic BOOL started;
3636
/* Are we tracing arcs, or just lines? */
3737
BOOL tracing_arcs;
3838
/* Have we had any activity? */
39-
BOOL activity;
39+
_Atomic BOOL activity;
4040
/* The current dynamic context. */
4141
PyObject * context;
4242

coverage/ctracer/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define _COVERAGE_UTIL_H
66

77
#include <Python.h>
8+
#include <stdatomic.h>
89

910
/* Compile-time debugging helpers */
1011
#undef WHAT_LOG /* Define to log the WHAT params in the trace function. */

setup.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ def run(self):
155155

156156
def build_extension(self, ext):
157157
"""Wrap `build_extension` with `BuildFailed`."""
158+
if self.compiler.compiler_type == "msvc":
159+
ext.extra_compile_args = (ext.extra_compile_args or []) + [
160+
"/std:c11",
161+
"/experimental:c11atomics",
162+
]
158163
try:
159164
# Uncomment to test compile failure handling:
160165
# raise errors.CCompilerError("OOPS")

0 commit comments

Comments
 (0)