Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * rwsem.h: R/W semaphores implemented using CAS
  3 *
  4 * Written by David S. Miller (davem@redhat.com), 2001.
  5 * Derived from asm-i386/rwsem.h
  6 */
  7#ifndef _SPARC64_RWSEM_H
  8#define _SPARC64_RWSEM_H
  9
 10#ifndef _LINUX_RWSEM_H
 11#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
 12#endif
 13
 14#ifdef __KERNEL__
 15
 16#define RWSEM_UNLOCKED_VALUE		0x00000000L
 17#define RWSEM_ACTIVE_BIAS		0x00000001L
 18#define RWSEM_ACTIVE_MASK		0xffffffffL
 19#define RWSEM_WAITING_BIAS		(-RWSEM_ACTIVE_MASK-1)
 20#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
 21#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
 22
 23/*
 24 * lock for reading
 25 */
 26static inline void __down_read(struct rw_semaphore *sem)
 27{
 28	if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L))
 29		rwsem_down_read_failed(sem);
 30}
 31
 32static inline int __down_read_trylock(struct rw_semaphore *sem)
 33{
 34	long tmp;
 35
 36	while ((tmp = sem->count) >= 0L) {
 37		if (tmp == cmpxchg(&sem->count, tmp,
 38				   tmp + RWSEM_ACTIVE_READ_BIAS)) {
 39			return 1;
 40		}
 41	}
 42	return 0;
 43}
 44
 45/*
 46 * lock for writing
 47 */
 48static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
 49{
 50	long tmp;
 51
 52	tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS,
 53				  (atomic64_t *)(&sem->count));
 54	if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
 55		rwsem_down_write_failed(sem);
 56}
 57
 58static inline void __down_write(struct rw_semaphore *sem)
 59{
 60	__down_write_nested(sem, 0);
 61}
 62
 63static inline int __down_write_trylock(struct rw_semaphore *sem)
 64{
 65	long tmp;
 66
 67	tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
 68		      RWSEM_ACTIVE_WRITE_BIAS);
 69	return tmp == RWSEM_UNLOCKED_VALUE;
 70}
 71
 72/*
 73 * unlock after reading
 74 */
 75static inline void __up_read(struct rw_semaphore *sem)
 76{
 77	long tmp;
 78
 79	tmp = atomic64_dec_return((atomic64_t *)(&sem->count));
 80	if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L))
 81		rwsem_wake(sem);
 82}
 83
 84/*
 85 * unlock after writing
 86 */
 87static inline void __up_write(struct rw_semaphore *sem)
 88{
 89	if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
 90					 (atomic64_t *)(&sem->count)) < 0L))
 91		rwsem_wake(sem);
 92}
 93
 94/*
 95 * implement atomic add functionality
 96 */
 97static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
 98{
 99	atomic64_add(delta, (atomic64_t *)(&sem->count));
100}
101
102/*
103 * downgrade write lock to read lock
104 */
105static inline void __downgrade_write(struct rw_semaphore *sem)
106{
107	long tmp;
108
109	tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count));
110	if (tmp < 0L)
111		rwsem_downgrade_wake(sem);
112}
113
114/*
115 * implement exchange and add functionality
116 */
117static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
118{
119	return atomic64_add_return(delta, (atomic64_t *)(&sem->count));
120}
121
122#endif /* __KERNEL__ */
123
124#endif /* _SPARC64_RWSEM_H */
v3.15
  1/*
  2 * rwsem.h: R/W semaphores implemented using CAS
  3 *
  4 * Written by David S. Miller (davem@redhat.com), 2001.
  5 * Derived from asm-i386/rwsem.h
  6 */
  7#ifndef _SPARC64_RWSEM_H
  8#define _SPARC64_RWSEM_H
  9
 10#ifndef _LINUX_RWSEM_H
 11#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
 12#endif
 13
 14#ifdef __KERNEL__
 15
 16#define RWSEM_UNLOCKED_VALUE		0x00000000L
 17#define RWSEM_ACTIVE_BIAS		0x00000001L
 18#define RWSEM_ACTIVE_MASK		0xffffffffL
 19#define RWSEM_WAITING_BIAS		(-RWSEM_ACTIVE_MASK-1)
 20#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
 21#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
 22
 23/*
 24 * lock for reading
 25 */
 26static inline void __down_read(struct rw_semaphore *sem)
 27{
 28	if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L))
 29		rwsem_down_read_failed(sem);
 30}
 31
 32static inline int __down_read_trylock(struct rw_semaphore *sem)
 33{
 34	long tmp;
 35
 36	while ((tmp = sem->count) >= 0L) {
 37		if (tmp == cmpxchg(&sem->count, tmp,
 38				   tmp + RWSEM_ACTIVE_READ_BIAS)) {
 39			return 1;
 40		}
 41	}
 42	return 0;
 43}
 44
 45/*
 46 * lock for writing
 47 */
 48static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
 49{
 50	long tmp;
 51
 52	tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS,
 53				  (atomic64_t *)(&sem->count));
 54	if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
 55		rwsem_down_write_failed(sem);
 56}
 57
 58static inline void __down_write(struct rw_semaphore *sem)
 59{
 60	__down_write_nested(sem, 0);
 61}
 62
 63static inline int __down_write_trylock(struct rw_semaphore *sem)
 64{
 65	long tmp;
 66
 67	tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
 68		      RWSEM_ACTIVE_WRITE_BIAS);
 69	return tmp == RWSEM_UNLOCKED_VALUE;
 70}
 71
 72/*
 73 * unlock after reading
 74 */
 75static inline void __up_read(struct rw_semaphore *sem)
 76{
 77	long tmp;
 78
 79	tmp = atomic64_dec_return((atomic64_t *)(&sem->count));
 80	if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L))
 81		rwsem_wake(sem);
 82}
 83
 84/*
 85 * unlock after writing
 86 */
 87static inline void __up_write(struct rw_semaphore *sem)
 88{
 89	if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
 90					 (atomic64_t *)(&sem->count)) < 0L))
 91		rwsem_wake(sem);
 92}
 93
 94/*
 95 * implement atomic add functionality
 96 */
 97static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
 98{
 99	atomic64_add(delta, (atomic64_t *)(&sem->count));
100}
101
102/*
103 * downgrade write lock to read lock
104 */
105static inline void __downgrade_write(struct rw_semaphore *sem)
106{
107	long tmp;
108
109	tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count));
110	if (tmp < 0L)
111		rwsem_downgrade_wake(sem);
112}
113
114/*
115 * implement exchange and add functionality
116 */
117static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
118{
119	return atomic64_add_return(delta, (atomic64_t *)(&sem->count));
120}
121
122#endif /* __KERNEL__ */
123
124#endif /* _SPARC64_RWSEM_H */