Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.16-rc2 120 lines 3.0 kB view raw
1#ifndef __ASM_SH64_SEMAPHORE_H 2#define __ASM_SH64_SEMAPHORE_H 3 4/* 5 * This file is subject to the terms and conditions of the GNU General Public 6 * License. See the file "COPYING" in the main directory of this archive 7 * for more details. 8 * 9 * include/asm-sh64/semaphore.h 10 * 11 * Copyright (C) 2000, 2001 Paolo Alberelli 12 * 13 * SMP- and interrupt-safe semaphores. 14 * 15 * (C) Copyright 1996 Linus Torvalds 16 * 17 * SuperH verison by Niibe Yutaka 18 * (Currently no asm implementation but generic C code...) 19 * 20 */ 21 22#include <linux/linkage.h> 23#include <linux/spinlock.h> 24#include <linux/wait.h> 25#include <linux/rwsem.h> 26 27#include <asm/system.h> 28#include <asm/atomic.h> 29 30struct semaphore { 31 atomic_t count; 32 int sleepers; 33 wait_queue_head_t wait; 34}; 35 36#define __SEMAPHORE_INITIALIZER(name, n) \ 37{ \ 38 .count = ATOMIC_INIT(n), \ 39 .sleepers = 0, \ 40 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ 41} 42 43#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ 44 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) 45 46#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) 47#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) 48 49static inline void sema_init (struct semaphore *sem, int val) 50{ 51/* 52 * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); 53 * 54 * i'd rather use the more flexible initialization above, but sadly 55 * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. 56 */ 57 atomic_set(&sem->count, val); 58 sem->sleepers = 0; 59 init_waitqueue_head(&sem->wait); 60} 61 62static inline void init_MUTEX (struct semaphore *sem) 63{ 64 sema_init(sem, 1); 65} 66 67static inline void init_MUTEX_LOCKED (struct semaphore *sem) 68{ 69 sema_init(sem, 0); 70} 71 72#if 0 73asmlinkage void __down_failed(void /* special register calling convention */); 74asmlinkage int __down_failed_interruptible(void /* params in registers */); 75asmlinkage int __down_failed_trylock(void /* params in registers */); 76asmlinkage void __up_wakeup(void /* special register calling convention */); 77#endif 78 79asmlinkage void __down(struct semaphore * sem); 80asmlinkage int __down_interruptible(struct semaphore * sem); 81asmlinkage int __down_trylock(struct semaphore * sem); 82asmlinkage void __up(struct semaphore * sem); 83 84extern spinlock_t semaphore_wake_lock; 85 86static inline void down(struct semaphore * sem) 87{ 88 if (atomic_dec_return(&sem->count) < 0) 89 __down(sem); 90} 91 92static inline int down_interruptible(struct semaphore * sem) 93{ 94 int ret = 0; 95 96 if (atomic_dec_return(&sem->count) < 0) 97 ret = __down_interruptible(sem); 98 return ret; 99} 100 101static inline int down_trylock(struct semaphore * sem) 102{ 103 int ret = 0; 104 105 if (atomic_dec_return(&sem->count) < 0) 106 ret = __down_trylock(sem); 107 return ret; 108} 109 110/* 111 * Note! This is subtle. We jump to wake people up only if 112 * the semaphore was negative (== somebody was waiting on it). 113 */ 114static inline void up(struct semaphore * sem) 115{ 116 if (atomic_inc_return(&sem->count) <= 0) 117 __up(sem); 118} 119 120#endif /* __ASM_SH64_SEMAPHORE_H */