]>
Commit | Line | Data |
---|---|---|
17dc08ed | 1 | /* NVPTX atomic operations |
99dee823 | 2 | Copyright (C) 2020-2021 Free Software Foundation, Inc. |
17dc08ed KCY |
3 | Contributed by Mentor Graphics. |
4 | ||
5 | This file is free software; you can redistribute it and/or modify it | |
6 | under the terms of the GNU General Public License as published by the | |
7 | Free Software Foundation; either version 3, or (at your option) any | |
8 | later version. | |
9 | ||
10 | This file is distributed in the hope that it will be useful, but | |
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | General Public License for more details. | |
14 | ||
15 | Under Section 7 of GPL version 3, you are granted additional | |
16 | permissions described in the GCC Runtime Library Exception, version | |
17 | 3.1, as published by the Free Software Foundation. | |
18 | ||
19 | You should have received a copy of the GNU General Public License and | |
20 | a copy of the GCC Runtime Library Exception along with this program; | |
21 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
22 | <http://www.gnu.org/licenses/>. */ | |
23 | ||
24 | #include <stdbool.h> | |
25 | ||
26 | /* Implement __sync_val_compare_and_swap and __sync_bool_compare_and_swap | |
27 | for 1 and 2-byte values (which are not natively supported) in terms of | |
28 | __sync_val_compare_and_swap for 4-byte values (which is supported). | |
29 | This assumes that the contents of the word surrounding the subword | |
30 | value that we are interested in are accessible as well (which should | |
31 | normally be the case). Note that if the contents of the word surrounding | |
32 | the subword changes between the __sync_val_compare_and_swap_4 and the | |
33 | preceeding load of oldword, while the subword does not, the implementation | |
34 | loops, which may manifest worst-case as a hang. */ | |
35 | ||
36 | #define __SYNC_SUBWORD_COMPARE_AND_SWAP(TYPE, SIZE) \ | |
37 | \ | |
38 | TYPE \ | |
7b9c2651 TV |
39 | __sync_val_compare_and_swap_##SIZE (volatile void *vptr, TYPE oldval, \ |
40 | TYPE newval) \ | |
17dc08ed | 41 | { \ |
7b9c2651 TV |
42 | volatile TYPE *ptr = vptr; \ |
43 | volatile unsigned int *wordptr \ | |
44 | = (volatile unsigned int *)((__UINTPTR_TYPE__) ptr & ~3UL); \ | |
45 | int shift = ((__UINTPTR_TYPE__) ptr & 3UL) * 8; \ | |
17dc08ed KCY |
46 | unsigned int valmask = (1 << (SIZE * 8)) - 1; \ |
47 | unsigned int wordmask = ~(valmask << shift); \ | |
48 | unsigned int oldword = *wordptr; \ | |
49 | for (;;) \ | |
50 | { \ | |
51 | TYPE prevval = (oldword >> shift) & valmask; \ | |
52 | /* Exit if the subword value previously read from memory is not */ \ | |
53 | /* equal to the expected value OLDVAL. */ \ | |
54 | if (__builtin_expect (prevval != oldval, 0)) \ | |
55 | return prevval; \ | |
56 | unsigned int newword = oldword & wordmask; \ | |
57 | newword |= ((unsigned int) newval) << shift; \ | |
58 | unsigned int prevword \ | |
59 | = __sync_val_compare_and_swap_4 (wordptr, oldword, newword); \ | |
60 | /* Exit only if the compare-and-swap succeeds on the whole word */ \ | |
61 | /* (i.e. the contents of *WORDPTR have not changed since the last */ \ | |
62 | /* memory read). */ \ | |
63 | if (__builtin_expect (prevword == oldword, 1)) \ | |
64 | return oldval; \ | |
65 | oldword = prevword; \ | |
66 | } \ | |
67 | } \ | |
68 | \ | |
69 | bool \ | |
7b9c2651 TV |
70 | __sync_bool_compare_and_swap_##SIZE (volatile void *ptr, TYPE oldval, \ |
71 | TYPE newval) \ | |
17dc08ed KCY |
72 | { \ |
73 | return __sync_val_compare_and_swap_##SIZE (ptr, oldval, newval) == oldval; \ | |
74 | } | |
75 | ||
76 | __SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned char, 1) | |
77 | __SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned short, 2) |