semaphore.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.semaphore.h 1.15 05/17/01 18:14:25 cort
  3.  */
  4. #ifndef _PPC_SEMAPHORE_H
  5. #define _PPC_SEMAPHORE_H
  6. /*
  7.  * Swiped from asm-sparc/semaphore.h and modified
  8.  * -- Cort (cort@cs.nmt.edu)
  9.  *
  10.  * Stole some rw spinlock-based semaphore stuff from asm-alpha/semaphore.h
  11.  * -- Ani Joshi (ajoshi@unixbox.com)
  12.  *
  13.  * Remove spinlock-based RW semaphores; RW semaphore definitions are
  14.  * now in rwsem.h and we use the the generic lib/rwsem.c implementation.
  15.  * Rework semaphores to use atomic_dec_if_positive.
  16.  * -- Paul Mackerras (paulus@samba.org)
  17.  */
  18. #ifdef __KERNEL__
  19. #include <asm/atomic.h>
  20. #include <asm/system.h>
  21. #include <linux/wait.h>
  22. #include <linux/rwsem.h>
  23. struct semaphore {
  24. /*
  25.  * Note that any negative value of count is equivalent to 0,
  26.  * but additionally indicates that some process(es) might be
  27.  * sleeping on `wait'.
  28.  */
  29. atomic_t count;
  30. wait_queue_head_t wait;
  31. #if WAITQUEUE_DEBUG
  32. long __magic;
  33. #endif
  34. };
  35. #if WAITQUEUE_DEBUG
  36. # define __SEM_DEBUG_INIT(name) 
  37. , (long)&(name).__magic
  38. #else
  39. # define __SEM_DEBUG_INIT(name)
  40. #endif
  41. #define __SEMAPHORE_INITIALIZER(name, count) 
  42. { ATOMIC_INIT(count), 
  43.   __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) 
  44.   __SEM_DEBUG_INIT(name) }
  45. #define __MUTEX_INITIALIZER(name) 
  46. __SEMAPHORE_INITIALIZER(name, 1)
  47. #define __DECLARE_SEMAPHORE_GENERIC(name, count) 
  48. struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  49. #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
  50. #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
  51. static inline void sema_init (struct semaphore *sem, int val)
  52. {
  53. atomic_set(&sem->count, val);
  54. init_waitqueue_head(&sem->wait);
  55. #if WAITQUEUE_DEBUG
  56. sem->__magic = (long)&sem->__magic;
  57. #endif
  58. }
  59. static inline void init_MUTEX (struct semaphore *sem)
  60. {
  61. sema_init(sem, 1);
  62. }
  63. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  64. {
  65. sema_init(sem, 0);
  66. }
  67. extern void __down(struct semaphore * sem);
  68. extern int  __down_interruptible(struct semaphore * sem);
  69. extern void __up(struct semaphore * sem);
  70. extern inline void down(struct semaphore * sem)
  71. {
  72. #if WAITQUEUE_DEBUG
  73. CHECK_MAGIC(sem->__magic);
  74. #endif
  75. /*
  76.  * Try to get the semaphore, take the slow path if we fail.
  77.  */
  78. if (atomic_dec_return(&sem->count) < 0)
  79. __down(sem);
  80. smp_wmb();
  81. }
  82. extern inline int down_interruptible(struct semaphore * sem)
  83. {
  84. int ret = 0;
  85. #if WAITQUEUE_DEBUG
  86. CHECK_MAGIC(sem->__magic);
  87. #endif
  88. if (atomic_dec_return(&sem->count) < 0)
  89. ret = __down_interruptible(sem);
  90. smp_wmb();
  91. return ret;
  92. }
  93. extern inline int down_trylock(struct semaphore * sem)
  94. {
  95. int ret;
  96. #if WAITQUEUE_DEBUG
  97. CHECK_MAGIC(sem->__magic);
  98. #endif
  99. ret = atomic_dec_if_positive(&sem->count) < 0;
  100. smp_wmb();
  101. return ret;
  102. }
  103. extern inline void up(struct semaphore * sem)
  104. {
  105. #if WAITQUEUE_DEBUG
  106. CHECK_MAGIC(sem->__magic);
  107. #endif
  108. smp_wmb();
  109. if (atomic_inc_return(&sem->count) <= 0)
  110. __up(sem);
  111. }
  112. #endif /* __KERNEL__ */
  113. #endif /* !(_PPC_SEMAPHORE_H) */