summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2020-03-31 21:07:08 +0100
committerGitHub <noreply@github.com>2020-03-31 22:07:08 +0200
commited94b465c5ceabd42e74052e3d164ec9b5d4a946 (patch)
treefa164444a8d4f63c806858e7f73c0e12ba6786e4
parent9b4a68fc7a7f7df77bd229ca38e5454fd9d828d4 (diff)
downloadcython-ed94b465c5ceabd42e74052e3d164ec9b5d4a946.tar.gz
Cython header file for C++ `std::atomic` type (GH-3469)
-rw-r--r--Cython/Includes/libcpp/atomic.pxd60
-rw-r--r--tests/run/cpp_stl_atomic.pyx85
-rw-r--r--tests/run/libcpp_all.pyx3
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]()