Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 6dc2f0c7df6cefda5932ac8bcd9ca5ef45de36ee 153 lines 3.3 kB view raw
1#ifndef _ALPHA_SEMAPHORE_H 2#define _ALPHA_SEMAPHORE_H 3 4/* 5 * SMP- and interrupt-safe semaphores.. 6 * 7 * (C) Copyright 1996 Linus Torvalds 8 * (C) Copyright 1996, 2000 Richard Henderson 9 */ 10 11#include <asm/current.h> 12#include <asm/system.h> 13#include <asm/atomic.h> 14#include <linux/compiler.h> 15#include <linux/wait.h> 16#include <linux/rwsem.h> 17 18struct semaphore { 19 atomic_t count; 20 wait_queue_head_t wait; 21}; 22 23#define __SEMAPHORE_INITIALIZER(name, n) \ 24{ \ 25 .count = ATOMIC_INIT(n), \ 26 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ 27} 28 29#define __MUTEX_INITIALIZER(name) \ 30 __SEMAPHORE_INITIALIZER(name,1) 31 32#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ 33 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) 34 35#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) 36#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) 37 38static inline void sema_init(struct semaphore *sem, int val) 39{ 40 /* 41 * Logically, 42 * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); 43 * except that gcc produces better initializing by parts yet. 44 */ 45 46 atomic_set(&sem->count, val); 47 init_waitqueue_head(&sem->wait); 48} 49 50static inline void init_MUTEX (struct semaphore *sem) 51{ 52 sema_init(sem, 1); 53} 54 55static inline void init_MUTEX_LOCKED (struct semaphore *sem) 56{ 57 sema_init(sem, 0); 58} 59 60extern void down(struct semaphore *); 61extern void __down_failed(struct semaphore *); 62extern int down_interruptible(struct semaphore *); 63extern int __down_failed_interruptible(struct semaphore *); 64extern int down_trylock(struct semaphore *); 65extern void up(struct semaphore *); 66extern void __up_wakeup(struct semaphore *); 67 68/* 69 * Hidden out of line code is fun, but extremely messy. Rely on newer 70 * compilers to do a respectable job with this. The contention cases 71 * are handled out of line in arch/alpha/kernel/semaphore.c. 72 */ 73 74static inline void __down(struct semaphore *sem) 75{ 76 long count; 77 might_sleep(); 78 count = atomic_dec_return(&sem->count); 79 if (unlikely(count < 0)) 80 __down_failed(sem); 81} 82 83static inline int __down_interruptible(struct semaphore *sem) 84{ 85 long count; 86 might_sleep(); 87 count = atomic_dec_return(&sem->count); 88 if (unlikely(count < 0)) 89 return __down_failed_interruptible(sem); 90 return 0; 91} 92 93/* 94 * down_trylock returns 0 on success, 1 if we failed to get the lock. 95 */ 96 97static inline int __down_trylock(struct semaphore *sem) 98{ 99 long ret; 100 101 /* "Equivalent" C: 102 103 do { 104 ret = ldl_l; 105 --ret; 106 if (ret < 0) 107 break; 108 ret = stl_c = ret; 109 } while (ret == 0); 110 */ 111 __asm__ __volatile__( 112 "1: ldl_l %0,%1\n" 113 " subl %0,1,%0\n" 114 " blt %0,2f\n" 115 " stl_c %0,%1\n" 116 " beq %0,3f\n" 117 " mb\n" 118 "2:\n" 119 ".subsection 2\n" 120 "3: br 1b\n" 121 ".previous" 122 : "=&r" (ret), "=m" (sem->count) 123 : "m" (sem->count)); 124 125 return ret < 0; 126} 127 128static inline void __up(struct semaphore *sem) 129{ 130 if (unlikely(atomic_inc_return(&sem->count) <= 0)) 131 __up_wakeup(sem); 132} 133 134#if !defined(CONFIG_DEBUG_SEMAPHORE) 135extern inline void down(struct semaphore *sem) 136{ 137 __down(sem); 138} 139extern inline int down_interruptible(struct semaphore *sem) 140{ 141 return __down_interruptible(sem); 142} 143extern inline int down_trylock(struct semaphore *sem) 144{ 145 return __down_trylock(sem); 146} 147extern inline void up(struct semaphore *sem) 148{ 149 __up(sem); 150} 151#endif 152 153#endif