diff options
author | da-woods <dw-git@d-woods.co.uk> | 2020-03-31 21:07:08 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-31 22:07:08 +0200 |
commit | ed94b465c5ceabd42e74052e3d164ec9b5d4a946 (patch) | |
tree | fa164444a8d4f63c806858e7f73c0e12ba6786e4 | |
parent | 9b4a68fc7a7f7df77bd229ca38e5454fd9d828d4 (diff) | |
download | cython-ed94b465c5ceabd42e74052e3d164ec9b5d4a946.tar.gz |
Cython header file for C++ `std::atomic` type (GH-3469)
-rw-r--r-- | Cython/Includes/libcpp/atomic.pxd | 60 | ||||
-rw-r--r-- | tests/run/cpp_stl_atomic.pyx | 85 | ||||
-rw-r--r-- | tests/run/libcpp_all.pyx | 3 |
3 files changed, 148 insertions, 0 deletions
diff --git a/Cython/Includes/libcpp/atomic.pxd b/Cython/Includes/libcpp/atomic.pxd new file mode 100644 index 000000000..3efd35aef --- /dev/null +++ b/Cython/Includes/libcpp/atomic.pxd @@ -0,0 +1,60 @@ + +cdef extern from "<atomic>" namespace "std" nogil: + + cdef enum memory_order: + memory_order_relaxed + memory_order_consume + memory_order_acquire + memory_order_release + memory_order_acq_rel + memory_order_seq_cst + + cdef cppclass atomic[T]: + atomic() + atomic(T) + + bint is_lock_free() + void store(T) + void store(T, memory_order) + T load() + T load(memory_order) + T exchange(T) + T exchange(T, memory_order) + + bint compare_exchange_weak(T&, T, memory_order, memory_order) + bint compare_exchange_weak(T&, T, memory_order) + bint compare_exchange_weak(T&, T) + bint compare_exchange_strong(T&, T, memory_order, memory_order) + bint compare_exchange_strong(T&, T, memory_order) + bint compare_exchange_strong(T&, T) + + T fetch_add(T, memory_order) + T fetch_add(T) + T fetch_sub(T, memory_order) + T fetch_sub(T) + T fetch_and(T, memory_order) + T fetch_and(T) + T fetch_or(T, memory_order) + T fetch_or(T) + T fetch_xor(T, memory_order) + T fetch_xor(T) + + T operator++() + T operator++(int) + T operator--() + T operator--(int) + + # modify-in-place operators not yet supported by Cython: + # T operator+=(T) + # T operator-=(T) + # T operator&=(T) + # T operator|=(T) + # T operator^=(T) + + bint operator==(atomic[T]&, atomic[T]&) + bint operator==(atomic[T]&, T&) + bint operator==(T&, atomic[T]&) + bint operator!=(atomic[T]&, atomic[T]&) + bint operator!=(atomic[T]&, T&) + bint operator!=(T&, atomic[T]&) + diff --git a/tests/run/cpp_stl_atomic.pyx b/tests/run/cpp_stl_atomic.pyx new file mode 100644 index 000000000..e504c70eb --- /dev/null +++ b/tests/run/cpp_stl_atomic.pyx @@ -0,0 +1,85 @@ +# mode: run +# tag: cpp, cpp11, werror + +from cython.operator cimport preincrement as incr, dereference as deref +from libc.stdint cimport * + +from libcpp.atomic cimport atomic + +def int_test(int x): + """ + >>> int_test(55) + 3 + >>> int_test(42) + 3 + >>> int_test(100000) + 3 + """ + atom = new atomic[int](x) + try: + atom.store(0) + incr(deref(atom)) + incr(deref(atom)) + incr(deref(atom)) + return atom.load() + finally: + del atom + +ctypedef atomic[int32_t] atomint32_t + +def typedef_test(int x): + """ + >>> typedef_test(55) + 3 + >>> typedef_test(42) + 3 + >>> typedef_test(100000) + 3 + """ + atom = new atomint32_t(x) + try: + atom.store(0) + incr(deref(atom)) + incr(deref(atom)) + incr(deref(atom)) + return atom.load() + finally: + del atom + +def stack_allocation_test(int x): + """ + >>> stack_allocation_test(55) + 3 + >>> stack_allocation_test(42) + 3 + >>> stack_allocation_test(100000) + 3 + """ + cdef atomint32_t atom + atom.store(x) + try: + atom.store(0) + incr(atom) + incr(atom) + incr(atom) + return atom.load() + finally: + pass + +def nogil_int_test(int x): + """ + >>> nogil_int_test(55) + 55 + >>> nogil_int_test(42) + 42 + >>> nogil_int_test(100000) + 100000 + """ + with nogil: + atom = new atomic[int](0) + try: + with nogil: + atom.store(x) + return atom.load() + finally: + del atom diff --git a/tests/run/libcpp_all.pyx b/tests/run/libcpp_all.pyx index 2930807d9..a45de63f6 100644 --- a/tests/run/libcpp_all.pyx +++ b/tests/run/libcpp_all.pyx @@ -4,6 +4,7 @@ import cython cimport libcpp +# cimport libcpp.atomic cimport libcpp.deque cimport libcpp.list cimport libcpp.map @@ -15,6 +16,7 @@ cimport libcpp.vector cimport libcpp.complex cimport libcpp.limits +# from libcpp.atomic cimport * from libcpp.deque cimport * from libcpp.list cimport * from libcpp.map cimport * @@ -26,6 +28,7 @@ from libcpp.vector cimport * from libcpp.complex cimport * from libcpp.limits cimport * +# cdef libcpp.atomic.atomc[int] a1 = atomic[int]() cdef libcpp.deque.deque[int] d1 = deque[int]() cdef libcpp.list.list[int] l1 = list[int]() cdef libcpp.map.map[int,int] m1 = map[int,int]() |