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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 1276 phoenix
/*
2
 * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff
3
 * in lib/rwsem.c.  Adapted largely from include/asm-i386/rwsem.h
4
 * by Paul Mackerras <paulus@samba.org>.
5
 */
6
 
7
#ifndef _PPC_RWSEM_H
8
#define _PPC_RWSEM_H
9
 
10
#ifdef __KERNEL__
11
#include <linux/list.h>
12
#include <linux/spinlock.h>
13
#include <asm/atomic.h>
14
#include <asm/system.h>
15
 
16
/*
17
 * the semaphore definition
18
 */
19
struct rw_semaphore {
20
        /* XXX this should be able to be an atomic_t  -- paulus */
21
        signed long             count;
22
#define RWSEM_UNLOCKED_VALUE            0x00000000
23
#define RWSEM_ACTIVE_BIAS               0x00000001
24
#define RWSEM_ACTIVE_MASK               0x0000ffff
25
#define RWSEM_WAITING_BIAS              (-0x00010000)
26
#define RWSEM_ACTIVE_READ_BIAS          RWSEM_ACTIVE_BIAS
27
#define RWSEM_ACTIVE_WRITE_BIAS         (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
28
        spinlock_t              wait_lock;
29
        struct list_head        wait_list;
30
#if RWSEM_DEBUG
31
        int                     debug;
32
#endif
33
};
34
 
35
/*
36
 * initialisation
37
 */
38
#if RWSEM_DEBUG
39
#define __RWSEM_DEBUG_INIT      , 0
40
#else
41
#define __RWSEM_DEBUG_INIT      /* */
42
#endif
43
 
44
#define __RWSEM_INITIALIZER(name) \
45
        { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
46
          LIST_HEAD_INIT((name).wait_list) \
47
          __RWSEM_DEBUG_INIT }
48
 
49
#define DECLARE_RWSEM(name)             \
50
        struct rw_semaphore name = __RWSEM_INITIALIZER(name)
51
 
52
extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
53
extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
54
extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
55
 
56
static inline void init_rwsem(struct rw_semaphore *sem)
57
{
58
        sem->count = RWSEM_UNLOCKED_VALUE;
59
        spin_lock_init(&sem->wait_lock);
60
        INIT_LIST_HEAD(&sem->wait_list);
61
#if RWSEM_DEBUG
62
        sem->debug = 0;
63
#endif
64
}
65
 
66
/*
67
 * lock for reading
68
 */
69
static inline void __down_read(struct rw_semaphore *sem)
70
{
71
        if (atomic_inc_return((atomic_t *)(&sem->count)) >= 0)
72
                smp_wmb();
73
        else
74
                rwsem_down_read_failed(sem);
75
}
76
 
77
static inline int __down_read_trylock(struct rw_semaphore *sem)
78
{
79
        int tmp;
80
 
81
        while ((tmp = sem->count) >= 0) {
82
                if (tmp == cmpxchg(&sem->count, tmp,
83
                                   tmp + RWSEM_ACTIVE_READ_BIAS)) {
84
                        smp_wmb();
85
                        return 1;
86
                }
87
        }
88
        return 0;
89
}
90
 
91
/*
92
 * lock for writing
93
 */
94
static inline void __down_write(struct rw_semaphore *sem)
95
{
96
        int tmp;
97
 
98
        tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
99
                                (atomic_t *)(&sem->count));
100
        if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
101
                smp_wmb();
102
        else
103
                rwsem_down_write_failed(sem);
104
}
105
 
106
static inline int __down_write_trylock(struct rw_semaphore *sem)
107
{
108
        int tmp;
109
 
110
        tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
111
                      RWSEM_ACTIVE_WRITE_BIAS);
112
        smp_wmb();
113
        return tmp == RWSEM_UNLOCKED_VALUE;
114
}
115
 
116
/*
117
 * unlock after reading
118
 */
119
static inline void __up_read(struct rw_semaphore *sem)
120
{
121
        int tmp;
122
 
123
        smp_wmb();
124
        tmp = atomic_dec_return((atomic_t *)(&sem->count));
125
        if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
126
                rwsem_wake(sem);
127
}
128
 
129
/*
130
 * unlock after writing
131
 */
132
static inline void __up_write(struct rw_semaphore *sem)
133
{
134
        smp_wmb();
135
        if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
136
                              (atomic_t *)(&sem->count)) < 0)
137
                rwsem_wake(sem);
138
}
139
 
140
/*
141
 * implement atomic add functionality
142
 */
143
static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
144
{
145
        atomic_add(delta, (atomic_t *)(&sem->count));
146
}
147
 
148
/*
149
 * implement exchange and add functionality
150
 */
151
static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
152
{
153
        smp_mb();
154
        return atomic_add_return(delta, (atomic_t *)(&sem->count));
155
}
156
 
157
#endif /* __KERNEL__ */
158
#endif /* _PPC_RWSEM_XADD_H */

powered by: WebSVN 2.1.0

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