Blame view

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