Skip to content

Commit 80c12d2

Browse files
committed
add tests and remove suppressions
1 parent a0dca26 commit 80c12d2

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

Modules/_testcapi/pyatomic.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include "parts.h"
8+
#include "pyconfig.h" // SIZEOF_VOID_P
89

910
// We define atomic bitwise operations on these types
1011
#define FOR_BITWISE_TYPES(V) \
@@ -156,6 +157,78 @@ test_atomic_load_store_int_release_acquire(PyObject *self, PyObject *obj) { \
156157
Py_RETURN_NONE;
157158
}
158159

160+
static PyObject *
161+
test_atomic_memcpy_ptr_store_relaxed(PyObject *self, PyObject *obj) {
162+
#if SIZEOF_VOID_P == 8
163+
#define p0 (void *)0x5555555555555555
164+
#define p1 (void *)0xaaaaaaaaaaaaaaaa
165+
#define p2 (void *)0xfedcba9876543210
166+
#define p3 (void *)0x0123456789abcdef
167+
#else
168+
#if SIZEOF_VOID_P == 4
169+
#define p0 (void *)0x55555555
170+
#define p1 (void *)0xaaaaaaaa
171+
#define p2 (void *)0x76543210
172+
#define p3 (void *)0x01234567
173+
#else
174+
#error "unexpected sizeof(void *), expecting 8 or 4"
175+
#endif
176+
#endif
177+
void *src[4] = { (void *)0, p2, p3, (void *)0 };
178+
void *dst[4] = { p0, (void *)0, (void *)0, p1 };
179+
assert(_Py_atomic_memcpy_ptr_store_relaxed(&dst[1], &src[1], SIZEOF_VOID_P * 2) == &dst[1]);
180+
assert(dst[0] == p0);
181+
assert(dst[1] == p2);
182+
assert(dst[2] == p3);
183+
assert(dst[3] == p1);
184+
Py_RETURN_NONE;
185+
#undef p3
186+
#undef p2
187+
#undef p1
188+
#undef p0
189+
}
190+
191+
static PyObject *
192+
test_atomic_memmove_ptr_store_relaxed(PyObject *self, PyObject *obj) {
193+
#if SIZEOF_VOID_P == 8
194+
#define p0 (void *)0x5555555555555555
195+
#define p1 (void *)0xaaaaaaaaaaaaaaaa
196+
#define p2 (void *)0xfedcba9876543210
197+
#define p3 (void *)0x0123456789abcdef
198+
#define p4 (void *)0x0f2d4b6987a5c3e1
199+
#else
200+
#if SIZEOF_VOID_P == 4
201+
#define p0 (void *)0x55555555
202+
#define p1 (void *)0xaaaaaaaa
203+
#define p2 (void *)0x76543210
204+
#define p3 (void *)0x01234567
205+
#define p4 (void *)0x07254361
206+
#else
207+
#error "unexpected sizeof(void *), expecting 8 or 4"
208+
#endif
209+
#endif
210+
void *back[5] = { p0, p2, p3, p4, p1 };
211+
assert(_Py_atomic_memmove_ptr_store_relaxed(&back[1], &back[2], SIZEOF_VOID_P * 2) == &back[1]);
212+
assert(back[0] == p0);
213+
assert(back[1] == p3);
214+
assert(back[2] == p4);
215+
assert(back[3] == p4);
216+
assert(back[4] == p1);
217+
void *fwd[5] = { p0, p2, p3, p4, p1 };
218+
assert(_Py_atomic_memmove_ptr_store_relaxed(&fwd[2], &fwd[1], SIZEOF_VOID_P * 2) == &fwd[2]);
219+
assert(fwd[0] == p0);
220+
assert(fwd[1] == p2);
221+
assert(fwd[2] == p2);
222+
assert(fwd[3] == p3);
223+
assert(fwd[4] == p1);
224+
Py_RETURN_NONE;
225+
#undef p4
226+
#undef p3
227+
#undef p2
228+
#undef p1
229+
#undef p0
230+
}
231+
159232
// NOTE: all tests should start with "test_atomic_" to be included
160233
// in test_pyatomic.py
161234

@@ -179,6 +252,8 @@ static PyMethodDef test_methods[] = {
179252
{"test_atomic_fences", test_atomic_fences, METH_NOARGS},
180253
{"test_atomic_release_acquire", test_atomic_release_acquire, METH_NOARGS},
181254
{"test_atomic_load_store_int_release_acquire", test_atomic_load_store_int_release_acquire, METH_NOARGS},
255+
{"test_atomic_memcpy_ptr_store_relaxed", test_atomic_memcpy_ptr_store_relaxed, METH_NOARGS},
256+
{"test_atomic_memmove_ptr_store_relaxed", test_atomic_memmove_ptr_store_relaxed, METH_NOARGS},
182257
{NULL, NULL} /* sentinel */
183258
};
184259

Tools/tsan/suppressions_free_threading.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,6 @@ thread:pthread_create
3232
# Range iteration is not thread-safe yet (issue #129068)
3333
race_top:rangeiter_next
3434

35-
# List resizing happens through different paths ending in memcpy or memmove
36-
# (for efficiency), which will probably need to rewritten as explicit loops
37-
# of ptr-sized copies to be thread-safe. (Issue #129069)
38-
race:list_ass_slice_lock_held
39-
race:list_inplace_repeat_lock_held
40-
4135
# PyObject_Realloc internally does memcpy which isn't atomic so can race
4236
# with non-locking reads. See #132070
4337
race:PyObject_Realloc

0 commit comments

Comments
 (0)