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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: semaphore.h,v 1.3 2001/05/08 13:54:09 bjornw Exp $ */
  2. /* On the i386 these are coded in asm, perhaps we should as well. Later.. */
  3. #ifndef _CRIS_SEMAPHORE_H
  4. #define _CRIS_SEMAPHORE_H
  5. #define RW_LOCK_BIAS             0x01000000
  6. #include <linux/wait.h>
  7. #include <linux/spinlock.h>
  8. #include <linux/rwsem.h>
  9. #include <asm/system.h>
  10. #include <asm/atomic.h>
  11. /*
  12.  * CRIS semaphores, implemented in C-only so far. 
  13.  */
  14. int printk(const char *fmt, ...);
  15. struct semaphore {
  16. int count; /* not atomic_t since we do the atomicity here already */
  17. atomic_t waking;
  18. wait_queue_head_t wait;
  19. #if WAITQUEUE_DEBUG
  20. long __magic;
  21. #endif
  22. };
  23. #if WAITQUEUE_DEBUG
  24. # define __SEM_DEBUG_INIT(name)         , (long)&(name).__magic
  25. #else
  26. # define __SEM_DEBUG_INIT(name)
  27. #endif
  28. #define __SEMAPHORE_INITIALIZER(name,count)             
  29.         { count, ATOMIC_INIT(0),          
  30.           __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    
  31.           __SEM_DEBUG_INIT(name) }
  32. #define __MUTEX_INITIALIZER(name) 
  33.         __SEMAPHORE_INITIALIZER(name,1)
  34. #define __DECLARE_SEMAPHORE_GENERIC(name,count) 
  35.         struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  36. #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  37. #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  38. extern inline void sema_init(struct semaphore *sem, int val)
  39. {
  40. *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
  41. }
  42. static inline void init_MUTEX (struct semaphore *sem)
  43. {
  44.         sema_init(sem, 1);
  45. }
  46. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  47. {
  48.         sema_init(sem, 0);
  49. }
  50. extern void __down(struct semaphore * sem);
  51. extern int __down_interruptible(struct semaphore * sem);
  52. extern int __down_trylock(struct semaphore * sem);
  53. extern void __up(struct semaphore * sem);
  54. /* notice - we probably can do cli/sti here instead of saving */
  55. extern inline void down(struct semaphore * sem)
  56. {
  57. unsigned long flags;
  58. int failed;
  59. #if WAITQUEUE_DEBUG
  60. CHECK_MAGIC(sem->__magic);
  61. #endif
  62. /* atomically decrement the semaphores count, and if its negative, we wait */
  63. save_flags(flags);
  64. cli();
  65. failed = --(sem->count) < 0;
  66. restore_flags(flags);
  67. if(failed) {
  68. __down(sem);
  69. }
  70. }
  71. /*
  72.  * This version waits in interruptible state so that the waiting
  73.  * process can be killed.  The down_interruptible routine
  74.  * returns negative for signalled and zero for semaphore acquired.
  75.  */
  76. extern inline int down_interruptible(struct semaphore * sem)
  77. {
  78. unsigned long flags;
  79. int failed;
  80. #if WAITQUEUE_DEBUG
  81. CHECK_MAGIC(sem->__magic);
  82. #endif
  83. /* atomically decrement the semaphores count, and if its negative, we wait */
  84. save_flags(flags);
  85. cli();
  86. failed = --(sem->count) < 0;
  87. restore_flags(flags);
  88. if(failed)
  89. failed = __down_interruptible(sem);
  90. return(failed);
  91. }
  92. extern inline int down_trylock(struct semaphore * sem)
  93. {
  94. unsigned long flags;
  95. int failed;
  96. #if WAITQUEUE_DEBUG
  97. CHECK_MAGIC(sem->__magic);
  98. #endif
  99. save_flags(flags);
  100. cli();
  101. failed = --(sem->count) < 0;
  102. restore_flags(flags);
  103. if(failed)
  104. failed = __down_trylock(sem);
  105. return(failed);
  106. }
  107. /*
  108.  * Note! This is subtle. We jump to wake people up only if
  109.  * the semaphore was negative (== somebody was waiting on it).
  110.  * The default case (no contention) will result in NO
  111.  * jumps for both down() and up().
  112.  */
  113. extern inline void up(struct semaphore * sem)
  114. {  
  115. unsigned long flags;
  116. int wakeup;
  117. #if WAITQUEUE_DEBUG
  118. CHECK_MAGIC(sem->__magic);
  119. #endif
  120. /* atomically increment the semaphores count, and if it was negative, we wake people */
  121. save_flags(flags);
  122. cli();
  123. wakeup = ++(sem->count) <= 0;
  124. restore_flags(flags);
  125. if(wakeup) {
  126. __up(sem);
  127. }
  128. }
  129. #endif