OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-alpha/] [atomic.h] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#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 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.