[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 05/55: Fix 'atomic-box-compare-and-swap!'.
From: |
Andy Wingo |
Subject: |
[Guile-commits] 05/55: Fix 'atomic-box-compare-and-swap!'. |
Date: |
Thu, 23 May 2019 11:52:37 -0400 (EDT) |
wingo pushed a commit to branch master
in repository guile.
commit f65ccc6afeda2d4e14878928123d8d3660712dca
Author: Mark H Weaver <address@hidden>
Date: Thu Sep 27 01:00:11 2018 -0400
Fix 'atomic-box-compare-and-swap!'.
Fixes <https://bugs.gnu.org/32786>.
'scm_atomic_compare_and_swap_scm' is a thin wrapper around
'atomic_compare_exchange_weak' (where available), and therefore it may
spuriously fail on some platforms, leaving the atomic object unchanged
even when the observed value is equal to the expected value. Since
'scm_atomic_compare_and_swap_scm' returns both a boolean result and the
observed value, the caller is able to detect spurious failures when
using that API.
'atomic-box-compare-and-swap!' presents a simpler API, returning only
the observed value. The documentation advises callers to assume that
the exchange succeeded if the observed value is 'eq?' to the expected
value. It's therefore not possible to report spurious failures with
this API.
'atomic-box-compare-and-swap!' uses 'scm_atomic_compare_and_swap_scm',
and prior to this commit would simply ignore the boolean result and
return the observed value. In case of spurious failures, the caller
would legitimately conclude that the exchange had succeeded.
With this commit, 'atomic-box-compare-and-swap!' now retries in case of
spurious failures.
* libguile/atomic.c (scm_atomic_box_compare_and_swap_x): If
'scm_atomic_compare_and_swap_scm' returns false and the observed value
is equal to 'expected', then try again.
* libguile/intrinsics.c (atomic_compare_and_swap_scm): Ditto.
---
libguile/atomic.c | 19 +++++++++++++++----
libguile/intrinsics.c | 18 +++++++++++++++---
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/libguile/atomic.c b/libguile/atomic.c
index 604a21e..174d26b 100644
--- a/libguile/atomic.c
+++ b/libguile/atomic.c
@@ -1,4 +1,4 @@
-/* Copyright 2016,2018
+/* Copyright 2016,2018-2019
Free Software Foundation, Inc.
This file is part of Guile.
@@ -102,10 +102,21 @@ SCM_DEFINE (scm_atomic_box_compare_and_swap_x,
"if the return value is @code{eq?} to @var{expected}.")
#define FUNC_NAME s_scm_atomic_box_compare_and_swap_x
{
+ SCM result = expected;
+
SCM_VALIDATE_ATOMIC_BOX (1, box);
- scm_atomic_compare_and_swap_scm (scm_atomic_box_loc (box),
- &expected, desired);
- return expected;
+ while (!scm_atomic_compare_and_swap_scm (scm_atomic_box_loc (box),
+ &result, desired)
+ && scm_is_eq (result, expected))
+ {
+ /* 'scm_atomic_compare_and_swap_scm' has spuriously failed,
+ i.e. it has returned 0 to indicate failure, although the
+ observed value is 'eq?' to EXPECTED. In this case, we *must*
+ try again, because the API of 'atomic-box-compare-and-swap!'
+ provides no way to indicate to the caller that the exchange
+ failed when the observed value is 'eq?' to EXPECTED. */
+ }
+ return result;
}
#undef FUNC_NAME
diff --git a/libguile/intrinsics.c b/libguile/intrinsics.c
index a619fda..4374410 100644
--- a/libguile/intrinsics.c
+++ b/libguile/intrinsics.c
@@ -1,4 +1,4 @@
-/* Copyright 2018
+/* Copyright 2018-2019
Free Software Foundation, Inc.
This file is part of Guile.
@@ -459,8 +459,20 @@ atomic_swap_scm (SCM *loc, SCM val)
static SCM
atomic_compare_and_swap_scm (SCM *loc, SCM expected, SCM desired)
{
- scm_atomic_compare_and_swap_scm (loc, &expected, desired);
- return expected;
+ SCM result = expected;
+
+ while (!scm_atomic_compare_and_swap_scm (loc, &result, desired)
+ && scm_is_eq (result, expected))
+ {
+ /* 'scm_atomic_compare_and_swap_scm' has spuriously failed,
+ i.e. it has returned 0 to indicate failure, although the
+ observed value is 'eq?' to EXPECTED. In this case, we *must*
+ try again, because the API of 'atomic-box-compare-and-swap!'
+ provides no way to indicate to the caller that the exchange
+ failed when the observed value is 'eq?' to EXPECTED. */
+ }
+
+ return result;
}
void
- [Guile-commits] 11/55: In 'ash' and 'round-ash', handle right shift count of LONG_MIN., (continued)
- [Guile-commits] 11/55: In 'ash' and 'round-ash', handle right shift count of LONG_MIN., Andy Wingo, 2019/05/23
- [Guile-commits] 16/55: Add tests for type inferencing for 'nil?' and 'null?' predicates., Andy Wingo, 2019/05/23
- [Guile-commits] 22/55: SRFI-19: Fix normalization of seconds and nanoseconds in time records., Andy Wingo, 2019/05/23
- [Guile-commits] 20/55: SRFI-19: Fix handling of negative years and negative julian days., Andy Wingo, 2019/05/23
- [Guile-commits] 37/55: Avoid leaking a file descriptor in test-unwind, Andy Wingo, 2019/05/23
- [Guile-commits] 38/55: Fix binary output on files created by mkstemp!, Andy Wingo, 2019/05/23
- [Guile-commits] 43/55: Fix typo in comment., Andy Wingo, 2019/05/23
- [Guile-commits] 04/55: Define AT_SYMLINK_NOFOLLOW et al., Andy Wingo, 2019/05/23
- [Guile-commits] 08/55: Fix list validation of *list->bytevector procedures., Andy Wingo, 2019/05/23
- [Guile-commits] 13/55: Update SRFI-19 leap second table., Andy Wingo, 2019/05/23
- [Guile-commits] 05/55: Fix 'atomic-box-compare-and-swap!'.,
Andy Wingo <=
- [Guile-commits] 26/55: Add texinfo dependency to README, Andy Wingo, 2019/05/23
- [Guile-commits] 27/55: Bootstrap optimization, Andy Wingo, 2019/05/23
- [Guile-commits] 32/55: Fix tests for SRFI-19 date->string ~N, Andy Wingo, 2019/05/23
- [Guile-commits] 33/55: Do not warn the user when 'madvise' returns ENOSYS., Andy Wingo, 2019/05/23
- [Guile-commits] 30/55: Update (ice-9 match) to include selected bug fixes from upstream., Andy Wingo, 2019/05/23
- [Guile-commits] 31/55: Support ~N in SRFI-19 string->date, Andy Wingo, 2019/05/23
- [Guile-commits] 28/55: Documentation fixes, Andy Wingo, 2019/05/23
- [Guile-commits] 42/55: Disable test for current value of setitimer on Cygwin, Andy Wingo, 2019/05/23
- [Guile-commits] 29/55: Fix spelling of ellipsis in (ice-9 match)., Andy Wingo, 2019/05/23
- [Guile-commits] 53/55: put-u8: Always write a single byte, regardless of the port encoding., Andy Wingo, 2019/05/23