This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: perl 5.0061 unable to build on sparc 5 Sol2.5.1 threads.
[perl5.git] / atomic.h
CommitLineData
dce16143
MB
1#ifdef __GNUC__
2
3/*
4 * These atomic operations copied from the linux kernel and altered
5 * only slightly. I need to get official permission to distribute
6 * under the Artistic License.
7 */
8/* We really need to integrate the atomic typedef with the typedef
9 * used by sv_refcnt of an SV. It's possible that for CPUs like alpha
10 * where we'd need to up sv_refcnt from 32 to 64 bits, we may be better
11 * off sticking with EMULATE_ATOMIC_REFCOUNTS instead.
12 */
13typedef U32 atomic_t; /* kludge */
14
15#ifdef i386
16
17# ifdef NO_SMP
18# define LOCK ""
19# else
20# define LOCK "lock ; "
21# endif
22
23# define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x)
24static __inline__ void atomic_inc(atomic_t *v)
25{
26 __asm__ __volatile__(
27 LOCK "incl %0"
28 :"=m" (__atomic_fool_gcc(v))
29 :"m" (__atomic_fool_gcc(v)));
30}
31
32static __inline__ int atomic_dec_and_test(atomic_t *v)
33{
34 unsigned char c;
35
36 __asm__ __volatile__(
37 LOCK "decl %0; sete %1"
38 :"=m" (__atomic_fool_gcc(v)), "=qm" (c)
39 :"m" (__atomic_fool_gcc(v)));
40 return c != 0;
41}
42# else
43/* XXX What symbol does gcc define for sparc64? */
44# ifdef sparc64
45# define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x)
46typedef U32 atomic_t;
47extern __inline__ void atomic_add(int i, atomic_t *v)
48{
49 __asm__ __volatile__("
501: lduw [%1], %%g5
51 add %%g5, %0, %%g7
52 cas [%1], %%g5, %%g7
53 sub %%g5, %%g7, %%g5
54 brnz,pn %%g5, 1b
55 nop"
56 : /* No outputs */
57 : "HIr" (i), "r" (__atomic_fool_gcc(v))
58 : "g5", "g7", "memory");
59}
60
61extern __inline__ int atomic_sub_return(int i, atomic_t *v)
62{
63 unsigned long oldval;
64 __asm__ __volatile__("
651: lduw [%2], %%g5
66 sub %%g5, %1, %%g7
67 cas [%2], %%g5, %%g7
68 sub %%g5, %%g7, %%g5
69 brnz,pn %%g5, 1b
70 sub %%g7, %1, %0"
71 : "=&r" (oldval)
72 : "HIr" (i), "r" (__atomic_fool_gcc(v))
73 : "g5", "g7", "memory");
74 return (int)oldval;
75}
76
77#define atomic_inc(v) atomic_add(1,(v))
78#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
79/* Add further gcc architectures here */
4dab3d39
NIS
80# else
81# define EMULATE_ATOMIC_REFCOUNTS
dce16143
MB
82# endif /* sparc64 */
83#endif /* i386 */
84#else
85/* Add non-gcc native atomic operations here */
86# define EMULATE_ATOMIC_REFCOUNTS
87#endif