summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-17 23:18:50 +0000
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-17 23:18:50 +0000
commit307c2567daf2a4918cbe6f5a52463dd0b69e5556 (patch)
treeaeb2c0104eb090d64ecc8cbb04774512793af98c /libgcc
parentcfe49258593616fbd592cc6fc0490019d6dee20a (diff)
downloadgcc-307c2567daf2a4918cbe6f5a52463dd0b69e5556.tar.gz
* config/pa/linux-atomic.c (__sync_lock_release_4): New.
(SYNC_LOCK_RELEASE): Update to use __kernel_cmpxchg for release. Don't use SYNC_LOCK_RELEASE for int type. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212767 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog6
-rw-r--r--libgcc/config/pa/linux-atomic.c25
2 files changed, 29 insertions, 2 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 2efd3312cf3..b659f803a8e 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-17 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/linux-atomic.c (__sync_lock_release_4): New.
+ (SYNC_LOCK_RELEASE): Update to use __kernel_cmpxchg for release.
+ Don't use SYNC_LOCK_RELEASE for int type.
+
2014-07-14 Richard Biener <rguenther@suse.de>
* libgcov.h (struct gcov_fn_info): Make ctrs size 1.
diff --git a/libgcc/config/pa/linux-atomic.c b/libgcc/config/pa/linux-atomic.c
index d92d6ef79b3..e70d7d7a1f7 100644
--- a/libgcc/config/pa/linux-atomic.c
+++ b/libgcc/config/pa/linux-atomic.c
@@ -293,13 +293,34 @@ __sync_lock_test_and_set_4 (int *ptr, int val)
SUBWORD_TEST_AND_SET (unsigned short, 2)
SUBWORD_TEST_AND_SET (unsigned char, 1)
+void HIDDEN
+__sync_lock_release_4 (int *ptr)
+{
+ int failure, oldval;
+
+ do {
+ oldval = *ptr;
+ failure = __kernel_cmpxchg (oldval, 0, ptr);
+ } while (failure != 0);
+}
+
#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \
void HIDDEN \
__sync_lock_release_##WIDTH (TYPE *ptr) \
{ \
- *ptr = 0; \
+ int failure; \
+ unsigned int oldval, newval, shift, mask; \
+ int *wordptr = (int *) ((unsigned long) ptr & ~3); \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ \
+ do { \
+ oldval = *wordptr; \
+ newval = oldval & ~mask; \
+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \
+ } while (failure != 0); \
}
-SYNC_LOCK_RELEASE (int, 4)
SYNC_LOCK_RELEASE (short, 2)
SYNC_LOCK_RELEASE (char, 1)