home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-alpha / semaphore.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  3.1 KB  |  151 lines

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