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

  1. #ifndef _H8300_SEMAPHORE_H
  2. #define _H8300_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.  
  13. #include <asm/system.h>
  14. #include <asm/atomic.h>
  15.  
  16. /*
  17.  * Interrupt-safe semaphores..
  18.  *
  19.  * (C) Copyright 1996 Linus Torvalds
  20.  *
  21.  * H8/300 version by Yoshinori Sato
  22.  */
  23.  
  24.  
  25. struct semaphore {
  26.     atomic_t count;
  27.     int sleepers;
  28.     wait_queue_head_t wait;
  29. };
  30.  
  31. #define __SEMAPHORE_INITIALIZER(name, n)                \
  32. {                                    \
  33.     .count        = ATOMIC_INIT(n),                \
  34.     .sleepers    = 0,                        \
  35.     .wait        = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
  36. }
  37.  
  38. #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
  39.     struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  40.  
  41. #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  42. #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  43.  
  44. static inline void sema_init (struct semaphore *sem, int val)
  45. {
  46.     *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
  47. }
  48.  
  49. static inline void init_MUTEX (struct semaphore *sem)
  50. {
  51.     sema_init(sem, 1);
  52. }
  53.  
  54. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  55. {
  56.     sema_init(sem, 0);
  57. }
  58.  
  59. asmlinkage void __down_failed(void /* special register calling convention */);
  60. asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
  61. asmlinkage int  __down_failed_trylock(void  /* params in registers */);
  62. asmlinkage void __up_wakeup(void /* special register calling convention */);
  63.  
  64. asmlinkage void __down(struct semaphore * sem);
  65. asmlinkage int  __down_interruptible(struct semaphore * sem);
  66. asmlinkage int  __down_trylock(struct semaphore * sem);
  67. asmlinkage void __up(struct semaphore * sem);
  68.  
  69. extern spinlock_t semaphore_wake_lock;
  70.  
  71. /*
  72.  * This is ugly, but we want the default case to fall through.
  73.  * "down_failed" is a special asm handler that calls the C
  74.  * routine that actually waits. See arch/m68k/lib/semaphore.S
  75.  */
  76. static inline void down(struct semaphore * sem)
  77. {
  78.     register atomic_t *count asm("er0");
  79.  
  80.     might_sleep();
  81.  
  82.     count = &(sem->count);
  83.     __asm__ __volatile__(
  84.         "stc ccr,r3l\n\t"
  85.         "orc #0x80,ccr\n\t"
  86.         "mov.l %2, er1\n\t"
  87.         "dec.l #1,er1\n\t"
  88.         "mov.l er1,%0\n\t"
  89.         "bpl 1f\n\t"
  90.         "ldc r3l,ccr\n\t"
  91.         "mov.l %1,er0\n\t"
  92.         "jsr @___down\n\t"
  93.         "bra 2f\n"
  94.         "1:\n\t"
  95.         "ldc r3l,ccr\n"
  96.         "2:"
  97.         : "=m"(*count)
  98.         : "g"(sem),"m"(*count)
  99.         : "cc",  "er1", "er2", "er3");
  100. }
  101.  
  102. static inline int down_interruptible(struct semaphore * sem)
  103. {
  104.     register atomic_t *count asm("er0");
  105.  
  106.     might_sleep();
  107.  
  108.     count = &(sem->count);
  109.     __asm__ __volatile__(
  110.         "stc ccr,r1l\n\t"
  111.         "orc #0x80,ccr\n\t"
  112.         "mov.l %3, er2\n\t"
  113.         "dec.l #1,er2\n\t"
  114.         "mov.l er2,%1\n\t"
  115.         "bpl 1f\n\t"
  116.         "ldc r1l,ccr\n\t"
  117.         "mov.l %2,er0\n\t"
  118.         "jsr @___down_interruptible\n\t"
  119.         "bra 2f\n"
  120.         "1:\n\t"
  121.         "ldc r1l,ccr\n\t"
  122.         "sub.l %0,%0\n\t"
  123.         "2:\n\t"
  124.         : "=r" (count),"=m" (*count)
  125.         : "g"(sem),"m"(*count)
  126.         : "cc", "er1", "er2", "er3");
  127.     return (int)count;
  128. }
  129.  
  130. static inline int down_trylock(struct semaphore * sem)
  131. {
  132.     register atomic_t *count asm("er0");
  133.  
  134.     count = &(sem->count);
  135.     __asm__ __volatile__(
  136.         "stc ccr,r3l\n\t"
  137.         "orc #0x80,ccr\n\t"
  138.         "mov.l %3,er2\n\t"
  139.         "dec.l #1,er2\n\t"
  140.         "mov.l er2,%0\n\t"
  141.         "bpl 1f\n\t"
  142.         "ldc r3l,ccr\n\t"
  143.         "jmp @3f\n\t"
  144.         LOCK_SECTION_START(".align 2\n\t")
  145.         "3:\n\t"
  146.         "mov.l %2,er0\n\t"
  147.         "jsr @___down_trylock\n\t"
  148.         "jmp @2f\n\t"
  149.         LOCK_SECTION_END
  150.         "1:\n\t"
  151.         "ldc r3l,ccr\n\t"
  152.         "sub.l %1,%1\n"
  153.         "2:"
  154.         : "=m" (*count),"=r"(count)
  155.         : "g"(sem),"m"(*count)
  156.         : "cc", "er1","er2", "er3");
  157.     return (int)count;
  158. }
  159.  
  160. /*
  161.  * Note! This is subtle. We jump to wake people up only if
  162.  * the semaphore was negative (== somebody was waiting on it).
  163.  * The default case (no contention) will result in NO
  164.  * jumps for both down() and up().
  165.  */
  166. static inline void up(struct semaphore * sem)
  167. {
  168.     register atomic_t *count asm("er0");
  169.  
  170.     count = &(sem->count);
  171.     __asm__ __volatile__(
  172.         "stc ccr,r3l\n\t"
  173.         "orc #0x80,ccr\n\t"
  174.         "mov.l %2,er1\n\t"
  175.         "inc.l #1,er1\n\t"
  176.         "mov.l er1,%0\n\t"
  177.         "ldc r3l,ccr\n\t"
  178.         "sub.l er2,er2\n\t"
  179.         "cmp.l er2,er1\n\t"
  180.         "bgt 1f\n\t"
  181.         "mov.l %1,er0\n\t"
  182.         "jsr @___up\n"
  183.         "1:"
  184.         : "=m"(*count)
  185.         : "g"(sem),"m"(*count)
  186.         : "cc", "er1", "er2", "er3");
  187. }
  188.  
  189. #endif /* __ASSEMBLY__ */
  190.  
  191. #endif
  192.