Subversion Repositories HelenOS

Rev

Rev 3191 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3191 Rev 4343
Line 33... Line 33...
33
 */
33
 */
34
 
34
 
35
#ifndef KERN_mips32_ATOMIC_H_
35
#ifndef KERN_mips32_ATOMIC_H_
36
#define KERN_mips32_ATOMIC_H_
36
#define KERN_mips32_ATOMIC_H_
37
 
37
 
38
#define atomic_inc(x)   ((void) atomic_add(x, 1))
38
#define atomic_inc(x)  ((void) atomic_add(x, 1))
39
#define atomic_dec(x)   ((void) atomic_add(x, -1))
39
#define atomic_dec(x)  ((void) atomic_add(x, -1))
40
 
40
 
41
#define atomic_postinc(x) (atomic_add(x, 1) - 1)
41
#define atomic_postinc(x)  (atomic_add(x, 1) - 1)
42
#define atomic_postdec(x) (atomic_add(x, -1) + 1)
42
#define atomic_postdec(x)  (atomic_add(x, -1) + 1)
43
 
43
 
44
#define atomic_preinc(x) atomic_add(x, 1)
44
#define atomic_preinc(x)  atomic_add(x, 1)
45
#define atomic_predec(x) atomic_add(x, -1)
45
#define atomic_predec(x)  atomic_add(x, -1)
46
 
46
 
47
/* Atomic addition of immediate value.
47
/* Atomic addition of immediate value.
48
 *
48
 *
49
 * @param val Memory location to which will be the immediate value added.
49
 * @param val Memory location to which will be the immediate value added.
50
 * @param i Signed immediate that will be added to *val.
50
 * @param i Signed immediate that will be added to *val.
Line 52... Line 52...
52
 * @return Value after addition.
52
 * @return Value after addition.
53
 */
53
 */
54
static inline long atomic_add(atomic_t *val, int i)
54
static inline long atomic_add(atomic_t *val, int i)
55
{
55
{
56
    long tmp, v;
56
    long tmp, v;
57
 
57
   
58
    asm volatile (
58
    asm volatile (
59
        "1:\n"
59
        "1:\n"
60
        "   ll %0, %1\n"
60
        "   ll %0, %1\n"
61
        "   addu %0, %0, %3\n"  /* same as addi, but never traps on overflow */
61
        "   addu %0, %0, %3\n"  /* same as addi, but never traps on overflow */
62
        "       move %2, %0\n"
62
        "   move %2, %0\n"
63
        "   sc %0, %1\n"
63
        "   sc %0, %1\n"
64
        "   beq %0, %4, 1b\n"   /* if the atomic operation failed, try again */
64
        "   beq %0, %4, 1b\n"   /* if the atomic operation failed, try again */
65
        "   nop\n"
65
        "   nop\n"
66
        : "=&r" (tmp), "+m" (val->count), "=&r" (v)
66
        : "=&r" (tmp), "+m" (val->count), "=&r" (v)
67
        : "r" (i), "i" (0)
67
        : "r" (i), "i" (0)
68
        );
68
    );
-
 
69
   
-
 
70
    return v;
-
 
71
}
69
 
72
 
-
 
73
static inline uint32_t test_and_set(atomic_t *val) {
-
 
74
    uint32_t tmp, v;
-
 
75
   
-
 
76
    asm volatile (
-
 
77
        "1:\n"
-
 
78
        "   ll %2, %1\n"
-
 
79
        "   bnez %2, 2f\n"
-
 
80
        "   li %0, %3\n"
-
 
81
        "   sc %0, %1\n"
-
 
82
        "   beqz %0, 1b\n"
-
 
83
        "2:\n"
-
 
84
        : "=&r" (tmp), "+m" (val->count), "=&r" (v)
-
 
85
        : "i" (1)
-
 
86
    );
-
 
87
   
70
    return v;
88
    return v;
71
}
89
}
72
 
90
 
73
#endif
91
#endif
74
 
92