diff options
author | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-07-17 23:18:50 +0000 |
---|---|---|
committer | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-07-17 23:18:50 +0000 |
commit | 307c2567daf2a4918cbe6f5a52463dd0b69e5556 (patch) | |
tree | aeb2c0104eb090d64ecc8cbb04774512793af98c /libgcc | |
parent | cfe49258593616fbd592cc6fc0490019d6dee20a (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | libgcc/config/pa/linux-atomic.c | 25 |
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) |