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-s390 / semaphore.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  2.5 KB  |  108 lines

  1. /*
  2.  *  include/asm-s390/semaphore.h
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *
  7.  *  Derived from "include/asm-i386/semaphore.h"
  8.  *    (C) Copyright 1996 Linus Torvalds
  9.  */
  10.  
  11. #ifndef _S390_SEMAPHORE_H
  12. #define _S390_SEMAPHORE_H
  13.  
  14. #include <asm/system.h>
  15. #include <asm/atomic.h>
  16. #include <linux/wait.h>
  17. #include <linux/rwsem.h>
  18.  
  19. struct semaphore {
  20.     /*
  21.      * Note that any negative value of count is equivalent to 0,
  22.      * but additionally indicates that some process(es) might be
  23.      * sleeping on `wait'.
  24.      */
  25.     atomic_t count;
  26.     wait_queue_head_t wait;
  27. };
  28.  
  29. #define __SEMAPHORE_INITIALIZER(name,count) \
  30.     { ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
  31.  
  32. #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
  33.     struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  34.  
  35. #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  36. #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  37.  
  38. static inline void sema_init (struct semaphore *sem, int val)
  39. {
  40.     *sem = (struct semaphore) __SEMAPHORE_INITIALIZER((*sem),val);
  41. }
  42.  
  43. static inline void init_MUTEX (struct semaphore *sem)
  44. {
  45.     sema_init(sem, 1);
  46. }
  47.  
  48. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  49. {
  50.     sema_init(sem, 0);
  51. }
  52.  
  53. asmlinkage void __down(struct semaphore * sem);
  54. asmlinkage int  __down_interruptible(struct semaphore * sem);
  55. asmlinkage int  __down_trylock(struct semaphore * sem);
  56. asmlinkage void __up(struct semaphore * sem);
  57.  
  58. static inline void down(struct semaphore * sem)
  59. {
  60.     might_sleep();
  61.     if (atomic_dec_return(&sem->count) < 0)
  62.         __down(sem);
  63. }
  64.  
  65. static inline int down_interruptible(struct semaphore * sem)
  66. {
  67.     int ret = 0;
  68.  
  69.     might_sleep();
  70.     if (atomic_dec_return(&sem->count) < 0)
  71.         ret = __down_interruptible(sem);
  72.     return ret;
  73. }
  74.  
  75. static inline int down_trylock(struct semaphore * sem)
  76. {
  77.     int old_val, new_val;
  78.  
  79.     /*
  80.      * This inline assembly atomically implements the equivalent
  81.      * to the following C code:
  82.      *   old_val = sem->count.counter;
  83.      *   if ((new_val = old_val) > 0)
  84.      *       sem->count.counter = --new_val;
  85.      * In the ppc code this is called atomic_dec_if_positive.
  86.      */
  87.     __asm__ __volatile__ (
  88.         "   l    %0,0(%3)\n"
  89.         "0: ltr  %1,%0\n"
  90.         "   jle  1f\n"
  91.         "   ahi  %1,-1\n"
  92.         "   cs   %0,%1,0(%3)\n"
  93.         "   jl   0b\n"
  94.         "1:"
  95.         : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count.counter)
  96.         : "a" (&sem->count.counter), "m" (sem->count.counter)
  97.         : "cc", "memory" );
  98.     return old_val <= 0;
  99. }
  100.  
  101. static inline void up(struct semaphore * sem)
  102. {
  103.     if (atomic_inc_return(&sem->count) <= 0)
  104.         __up(sem);
  105. }
  106.  
  107. #endif
  108.