summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-02-18 09:12:02 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-02-18 09:12:02 +0300
commit1e82bcffac6378e34c40bea98aecadc57aa8fa4e (patch)
treef25771e93fe7279f29f996738574d9af928624e2
parentc3d6688d2e0308f224096fd5bc75ffc689a22fda (diff)
downloadlibatomic_ops-1e82bcffac6378e34c40bea98aecadc57aa8fa4e.tar.gz
New AO_stack_is_lock_free API function
* README_stack.txt: Document AO_stack_is_lock_free; update documentation about AO_STACK_IS_LOCK_FREE. * src/atomic_ops_stack.c (AO_stack_is_lock_free): Implement. * src/atomic_ops_stack.h (AO_stack_is_lock_free): New API function declaration. * tests/test_stack.c (main): Use !AO_stack_is_lock_free() instead of AO_USE_ALMOST_LOCK_FREE.
-rw-r--r--README_stack.txt5
-rw-r--r--src/atomic_ops_stack.c9
-rw-r--r--src/atomic_ops_stack.h1
-rw-r--r--tests/test_stack.c3
4 files changed, 14 insertions, 4 deletions
diff --git a/README_stack.txt b/README_stack.txt
index 66c167c..a3c8e00 100644
--- a/README_stack.txt
+++ b/README_stack.txt
@@ -28,8 +28,9 @@ makes that less expensive, i.e. when we have a double-wide compare-and-swap
operation available. (The fully lock-free implementation uses an AO_t-
sized version count, and assumes it does not wrap during the time any
given operation is active. This seems reasonably safe on 32-bit hardware,
-and very safe on 64-bit hardware.) If a fully lock-free implementation
-is used, the macro AO_STACK_IS_LOCK_FREE will be defined.
+and very safe on 64-bit hardware.) If a fully lock-free implementation,
+AO_stack_is_lock_free() returns 1 (also, the macro AO_STACK_IS_LOCK_FREE is
+defined in this case but its usage by client is deprecated).
The implementation is interesting only because it allows reuse of
existing nodes. This is necessary, for example, to implement a memory
diff --git a/src/atomic_ops_stack.c b/src/atomic_ops_stack.c
index cefc1ed..e4a4fdc 100644
--- a/src/atomic_ops_stack.c
+++ b/src/atomic_ops_stack.c
@@ -35,6 +35,15 @@ AO_API void AO_stack_init(AO_stack_t *list)
memset(list, 0, sizeof(AO_stack_t));
}
+AO_API int AO_stack_is_lock_free(void)
+{
+# ifdef AO_USE_ALMOST_LOCK_FREE
+ return 0;
+# else
+ return 1;
+# endif
+}
+
AO_API AO_t *AO_real_head_ptr(const AO_stack_t *list)
{
return AO_REAL_HEAD_PTR(*list);
diff --git a/src/atomic_ops_stack.h b/src/atomic_ops_stack.h
index a1dc60d..c92752c 100644
--- a/src/atomic_ops_stack.h
+++ b/src/atomic_ops_stack.h
@@ -168,6 +168,7 @@ AO_API AO_t *AO_stack_pop_acquire(AO_stack_t *list);
#define AO_HAVE_stack_pop
AO_API void AO_stack_init(AO_stack_t *list);
+AO_API int AO_stack_is_lock_free(void);
AO_API AO_t *AO_real_head_ptr(const AO_stack_t *list);
AO_API AO_t *AO_real_next_ptr(AO_t /* next */);
diff --git a/tests/test_stack.c b/tests/test_stack.c
index 4025c7e..abaf0b8 100644
--- a/tests/test_stack.c
+++ b/tests/test_stack.c
@@ -271,9 +271,8 @@ int main(int argc, char **argv)
fprintf(stderr, "Usage: %s [max # of threads]\n", argv[0]);
exit(1);
}
-# ifdef AO_USE_ALMOST_LOCK_FREE
+ if (!AO_stack_is_lock_free())
printf("Use almost-lock-free implementation\n");
-# endif
# if defined(CPPCHECK)
AO_stack_init(&the_list);
# endif