~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-sparc/atomic.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* atomic.h: These still suck, but the I-cache hit rate is higher.
  2  *
  3  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  4  */
  5 
  6 #ifndef __ARCH_SPARC_ATOMIC__
  7 #define __ARCH_SPARC_ATOMIC__
  8 
  9 #include <linux/config.h>
 10 
 11 typedef struct { volatile int counter; } atomic_t;
 12 
 13 #ifdef __KERNEL__
 14 #ifndef CONFIG_SMP
 15 
 16 #define ATOMIC_INIT(i)  { (i) }
 17 #define atomic_read(v)          ((v)->counter)
 18 #define atomic_set(v, i)        (((v)->counter) = i)
 19 
 20 #else
 21 /* We do the bulk of the actual work out of line in two common
 22  * routines in assembler, see arch/sparc/lib/atomic.S for the
 23  * "fun" details.
 24  *
 25  * For SMP the trick is you embed the spin lock byte within
 26  * the word, use the low byte so signedness is easily retained
 27  * via a quick arithmetic shift.  It looks like this:
 28  *
 29  *      ----------------------------------------
 30  *      | signed 24-bit counter value |  lock  |  atomic_t
 31  *      ----------------------------------------
 32  *       31                          8 7      0
 33  */
 34 
 35 #define ATOMIC_INIT(i)  { (i << 8) }
 36 
 37 static __inline__ int atomic_read(atomic_t *v)
 38 {
 39         int ret = v->counter;
 40 
 41         while(ret & 0xff)
 42                 ret = v->counter;
 43 
 44         return ret >> 8;
 45 }
 46 
 47 #define atomic_set(v, i)        (((v)->counter) = ((i) << 8))
 48 #endif
 49 
 50 /* Make sure gcc doesn't try to be clever and move things around
 51  * on us. We need to use _exactly_ the address the user gave us,
 52  * not some alias that contains the same information.
 53  */
 54 #define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x)
 55 
 56 static __inline__ void atomic_add(int i, atomic_t *v)
 57 {
 58         register atomic_t *ptr asm("g1");
 59         register int increment asm("g2");
 60         ptr = (atomic_t *) __atomic_fool_gcc(v);
 61         increment = i;
 62 
 63         __asm__ __volatile__("
 64         mov     %%o7, %%g4
 65         call    ___atomic_add
 66          add    %%o7, 8, %%o7
 67 "       : "=&r" (increment)
 68         : "" (increment), "r" (ptr)
 69         : "g3", "g4", "g7", "memory", "cc");
 70 }
 71 
 72 static __inline__ void atomic_sub(int i, atomic_t *v)
 73 {
 74         register atomic_t *ptr asm("g1");
 75         register int increment asm("g2");
 76 
 77         ptr = (atomic_t *) __atomic_fool_gcc(v);
 78         increment = i;
 79 
 80         __asm__ __volatile__("
 81         mov     %%o7, %%g4
 82         call    ___atomic_sub
 83          add    %%o7, 8, %%o7
 84 "       : "=&r" (increment)
 85         : "" (increment), "r" (ptr)
 86         : "g3", "g4", "g7", "memory", "cc");
 87 }
 88 
 89 static __inline__ int atomic_add_return(int i, atomic_t *v)
 90 {
 91         register atomic_t *ptr asm("g1");
 92         register int increment asm("g2");
 93 
 94         ptr = (atomic_t *) __atomic_fool_gcc(v);
 95         increment = i;
 96 
 97         __asm__ __volatile__("
 98         mov     %%o7, %%g4
 99         call    ___atomic_add
100          add    %%o7, 8, %%o7
101 "       : "=&r" (increment)
102         : "" (increment), "r" (ptr)
103         : "g3", "g4", "g7", "memory", "cc");
104 
105         return increment;
106 }
107 
108 static __inline__ int atomic_sub_return(int i, atomic_t *v)
109 {
110         register atomic_t *ptr asm("g1");
111         register int increment asm("g2");
112 
113         ptr = (atomic_t *) __atomic_fool_gcc(v);
114         increment = i;
115 
116         __asm__ __volatile__("
117         mov     %%o7, %%g4
118         call    ___atomic_sub
119          add    %%o7, 8, %%o7
120 "       : "=&r" (increment)
121         : "" (increment), "r" (ptr)
122         : "g3", "g4", "g7", "memory", "cc");
123 
124         return increment;
125 }
126 
127 #define atomic_dec_return(v) atomic_sub_return(1,(v))
128 #define atomic_inc_return(v) atomic_add_return(1,(v))
129 
130 #define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
131 #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
132 
133 #define atomic_inc(v) atomic_add(1,(v))
134 #define atomic_dec(v) atomic_sub(1,(v))
135 
136 #define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0)
137 
138 #endif /* !(__KERNEL__) */
139 
140 #endif /* !(__ARCH_SPARC_ATOMIC__) */
141 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.