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

  1. #ifndef _M68K_SEMAPHORE_H
  2. #define _M68K_SEMAPHORE_H
  3.  
  4. #define RW_LOCK_BIAS         0x01000000
  5.  
  6. #ifndef __ASSEMBLY__
  7.  
  8. #include <linux/linkage.h>
  9. #include <linux/wait.h>
  10. #include <linux/spinlock.h>
  11. #include <linux/rwsem.h>
  12. #include <linux/stringify.h>
  13.  
  14. #include <asm/system.h>
  15. #include <asm/atomic.h>
  16.  
  17. /*
  18.  * Interrupt-safe semaphores..
  19.  *
  20.  * (C) Copyright 1996 Linus Torvalds
  21.  *
  22.  * m68k version by Andreas Schwab
  23.  */
  24.  
  25.  
  26. struct semaphore {
  27.     atomic_t count;
  28.     atomic_t waking;
  29.     wait_queue_head_t wait;
  30. };
  31.  
  32. #define __SEMAPHORE_INITIALIZER(name, n)                \
  33. {                                    \
  34.     .count        = ATOMIC_INIT(n),                \
  35.     .waking        = ATOMIC_INIT(0),                \
  36.     .wait        = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
  37. }
  38.  
  39. #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
  40.     struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  41.  
  42. #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  43. #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  44.  
  45. static inline void sema_init(struct semaphore *sem, int val)
  46. {
  47.     *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
  48. }
  49.  
  50. static inline void init_MUTEX (struct semaphore *sem)
  51. {
  52.     sema_init(sem, 1);
  53. }
  54.  
  55. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  56. {
  57.     sema_init(sem, 0);
  58. }
  59.  
  60. asmlinkage void __down_failed(void /* special register calling convention */);
  61. asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
  62. asmlinkage int  __down_failed_trylock(void  /* params in registers */);
  63. asmlinkage void __up_wakeup(void /* special register calling convention */);
  64.  
  65. asmlinkage void __down(struct semaphore * sem);
  66. asmlinkage int  __down_interruptible(struct semaphore * sem);
  67. asmlinkage int  __down_trylock(struct semaphore * sem);
  68. asmlinkage void __up(struct semaphore * sem);
  69.  
  70. /*
  71.  * This is ugly, but we want the default case to fall through.
  72.  * "down_failed" is a special asm handler that calls the C
  73.  * routine that actually waits. See arch/m68k/lib/semaphore.S
  74.  */
  75. static inline void down(struct semaphore *sem)
  76. {
  77.     register struct semaphore *sem1 __asm__ ("%a1") = sem;
  78.  
  79.     might_sleep();
  80.     __asm__ __volatile__(
  81.         "| atomic down operation\n\t"
  82.         "subql #1,%0@\n\t"
  83.         "jmi 2f\n\t"
  84.         "1:\n"
  85.         LOCK_SECTION_START(".even\n\t")
  86.         "2:\tpea 1b\n\t"
  87.         "jbra __down_failed\n"
  88.         LOCK_SECTION_END
  89.         : /* no outputs */
  90.         : "a" (sem1)
  91.         : "memory");
  92. }
  93.  
  94. static inline int down_interruptible(struct semaphore *sem)
  95. {
  96.     register struct semaphore *sem1 __asm__ ("%a1") = sem;
  97.     register int result __asm__ ("%d0");
  98.  
  99.     might_sleep();
  100.     __asm__ __volatile__(
  101.         "| atomic interruptible down operation\n\t"
  102.         "subql #1,%1@\n\t"
  103.         "jmi 2f\n\t"
  104.         "clrl %0\n"
  105.         "1:\n"
  106.         LOCK_SECTION_START(".even\n\t")
  107.         "2:\tpea 1b\n\t"
  108.         "jbra __down_failed_interruptible\n"
  109.         LOCK_SECTION_END
  110.         : "=d" (result)
  111.         : "a" (sem1)
  112.         : "memory");
  113.     return result;
  114. }
  115.  
  116. static inline int down_trylock(struct semaphore *sem)
  117. {
  118.     register struct semaphore *sem1 __asm__ ("%a1") = sem;
  119.     register int result __asm__ ("%d0");
  120.  
  121.     __asm__ __volatile__(
  122.         "| atomic down trylock operation\n\t"
  123.         "subql #1,%1@\n\t"
  124.         "jmi 2f\n\t"
  125.         "clrl %0\n"
  126.         "1:\n"
  127.         LOCK_SECTION_START(".even\n\t")
  128.         "2:\tpea 1b\n\t"
  129.         "jbra __down_failed_trylock\n"
  130.         LOCK_SECTION_END
  131.         : "=d" (result)
  132.         : "a" (sem1)
  133.         : "memory");
  134.     return result;
  135. }
  136.  
  137. /*
  138.  * Note! This is subtle. We jump to wake people up only if
  139.  * the semaphore was negative (== somebody was waiting on it).
  140.  * The default case (no contention) will result in NO
  141.  * jumps for both down() and up().
  142.  */
  143. static inline void up(struct semaphore *sem)
  144. {
  145.     register struct semaphore *sem1 __asm__ ("%a1") = sem;
  146.  
  147.     __asm__ __volatile__(
  148.         "| atomic up operation\n\t"
  149.         "addql #1,%0@\n\t"
  150.         "jle 2f\n"
  151.         "1:\n"
  152.         LOCK_SECTION_START(".even\n\t")
  153.         "2:\t"
  154.         "pea 1b\n\t"
  155.         "jbra __up_wakeup\n"
  156.         LOCK_SECTION_END
  157.         : /* no outputs */
  158.         : "a" (sem1)
  159.         : "memory");
  160. }
  161.  
  162. #endif /* __ASSEMBLY__ */
  163.  
  164. #endif
  165.