The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/include/asm-alpha/atomic.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #ifndef _ALPHA_ATOMIC_H
    2 #define _ALPHA_ATOMIC_H
    3 
    4 /*
    5  * Atomic operations that C can't guarantee us.  Useful for
    6  * resource counting etc...
    7  *
    8  * But use these as seldom as possible since they are much slower
    9  * than regular operations.
   10  */
   11 
   12 
   13 /*
   14  * Counter is volatile to make sure gcc doesn't try to be clever
   15  * and move things around on us. We need to use _exactly_ the address
   16  * the user gave us, not some alias that contains the same information.
   17  */
   18 typedef struct { volatile int counter; } atomic_t;
   19 
   20 #define ATOMIC_INIT(i)  ( (atomic_t) { (i) } )
   21 
   22 #define atomic_read(v)          ((v)->counter)
   23 #define atomic_set(v,i)         ((v)->counter = (i))
   24 
   25 /*
   26  * To get proper branch prediction for the main line, we must branch
   27  * forward to code at the end of this object's .text section, then
   28  * branch back to restart the operation.
   29  */
   30 
   31 static __inline__ void atomic_add(int i, atomic_t * v)
   32 {
   33         unsigned long temp;
   34         __asm__ __volatile__(
   35         "1:     ldl_l %0,%1\n"
   36         "       addl %0,%2,%0\n"
   37         "       stl_c %0,%1\n"
   38         "       beq %0,2f\n"
   39         ".subsection 2\n"
   40         "2:     br 1b\n"
   41         ".previous"
   42         :"=&r" (temp), "=m" (v->counter)
   43         :"Ir" (i), "m" (v->counter));
   44 }
   45 
   46 static __inline__ void atomic_sub(int i, atomic_t * v)
   47 {
   48         unsigned long temp;
   49         __asm__ __volatile__(
   50         "1:     ldl_l %0,%1\n"
   51         "       subl %0,%2,%0\n"
   52         "       stl_c %0,%1\n"
   53         "       beq %0,2f\n"
   54         ".subsection 2\n"
   55         "2:     br 1b\n"
   56         ".previous"
   57         :"=&r" (temp), "=m" (v->counter)
   58         :"Ir" (i), "m" (v->counter));
   59 }
   60 
   61 /*
   62  * Same as above, but return the result value
   63  */
   64 static __inline__ long atomic_add_return(int i, atomic_t * v)
   65 {
   66         long temp, result;
   67         __asm__ __volatile__(
   68         "1:     ldl_l %0,%1\n"
   69         "       addl %0,%3,%2\n"
   70         "       addl %0,%3,%0\n"
   71         "       stl_c %0,%1\n"
   72         "       beq %0,2f\n"
   73         "       mb\n"
   74         ".subsection 2\n"
   75         "2:     br 1b\n"
   76         ".previous"
   77         :"=&r" (temp), "=m" (v->counter), "=&r" (result)
   78         :"Ir" (i), "m" (v->counter) : "memory");
   79         return result;
   80 }
   81 
   82 static __inline__ long atomic_sub_return(int i, atomic_t * v)
   83 {
   84         long temp, result;
   85         __asm__ __volatile__(
   86         "1:     ldl_l %0,%1\n"
   87         "       subl %0,%3,%2\n"
   88         "       subl %0,%3,%0\n"
   89         "       stl_c %0,%1\n"
   90         "       beq %0,2f\n"
   91         "       mb\n"
   92         ".subsection 2\n"
   93         "2:     br 1b\n"
   94         ".previous"
   95         :"=&r" (temp), "=m" (v->counter), "=&r" (result)
   96         :"Ir" (i), "m" (v->counter) : "memory");
   97         return result;
   98 }
   99 
  100 #define atomic_dec_return(v) atomic_sub_return(1,(v))
  101 #define atomic_inc_return(v) atomic_add_return(1,(v))
  102 
  103 #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
  104 #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
  105 
  106 #define atomic_inc(v) atomic_add(1,(v))
  107 #define atomic_dec(v) atomic_sub(1,(v))
  108 
  109 #define smp_mb__before_atomic_dec()     smp_mb()
  110 #define smp_mb__after_atomic_dec()      smp_mb()
  111 #define smp_mb__before_atomic_inc()     smp_mb()
  112 #define smp_mb__after_atomic_inc()      smp_mb()
  113 
  114 #endif /* _ALPHA_ATOMIC_H */

Cache object: f942b7c2667f21a86a3f58db723891b3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.