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-helper.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  2.7 KB  |  143 lines

  1. #ifndef _M68K_SEMAPHORE_HELPER_H
  2. #define _M68K_SEMAPHORE_HELPER_H
  3.  
  4. /*
  5.  * SMP- and interrupt-safe semaphores helper functions.
  6.  *
  7.  * (C) Copyright 1996 Linus Torvalds
  8.  *
  9.  * m68k version by Andreas Schwab
  10.  */
  11.  
  12. #include <linux/errno.h>
  13.  
  14. /*
  15.  * These two _must_ execute atomically wrt each other.
  16.  */
  17. static inline void wake_one_more(struct semaphore * sem)
  18. {
  19.     atomic_inc(&sem->waking);
  20. }
  21.  
  22. #ifndef CONFIG_RMW_INSNS
  23. extern spinlock_t semaphore_wake_lock;
  24. #endif
  25.  
  26. static inline int waking_non_zero(struct semaphore *sem)
  27. {
  28.     int ret;
  29. #ifndef CONFIG_RMW_INSNS
  30.     unsigned long flags;
  31.  
  32.     spin_lock_irqsave(&semaphore_wake_lock, flags);
  33.     ret = 0;
  34.     if (atomic_read(&sem->waking) > 0) {
  35.         atomic_dec(&sem->waking);
  36.         ret = 1;
  37.     }
  38.     spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  39. #else
  40.     int tmp1, tmp2;
  41.  
  42.     __asm__ __volatile__
  43.       ("1:    movel    %1,%2\n"
  44.        "    jle    2f\n"
  45.        "    subql    #1,%2\n"
  46.        "    casl    %1,%2,%3\n"
  47.        "    jne    1b\n"
  48.        "    moveq    #1,%0\n"
  49.        "2:"
  50.        : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
  51.        : "m" (sem->waking), "0" (0), "1" (sem->waking));
  52. #endif
  53.  
  54.     return ret;
  55. }
  56.  
  57. /*
  58.  * waking_non_zero_interruptible:
  59.  *    1    got the lock
  60.  *    0    go to sleep
  61.  *    -EINTR    interrupted
  62.  */
  63. static inline int waking_non_zero_interruptible(struct semaphore *sem,
  64.                         struct task_struct *tsk)
  65. {
  66.     int ret;
  67. #ifndef CONFIG_RMW_INSNS
  68.     unsigned long flags;
  69.  
  70.     spin_lock_irqsave(&semaphore_wake_lock, flags);
  71.     ret = 0;
  72.     if (atomic_read(&sem->waking) > 0) {
  73.         atomic_dec(&sem->waking);
  74.         ret = 1;
  75.     } else if (signal_pending(tsk)) {
  76.         atomic_inc(&sem->count);
  77.         ret = -EINTR;
  78.     }
  79.     spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  80. #else
  81.     int tmp1, tmp2;
  82.  
  83.     __asm__ __volatile__
  84.       ("1:    movel    %1,%2\n"
  85.        "    jle    2f\n"
  86.        "    subql    #1,%2\n"
  87.        "    casl    %1,%2,%3\n"
  88.        "    jne    1b\n"
  89.        "    moveq    #1,%0\n"
  90.        "    jra    %a4\n"
  91.        "2:"
  92.        : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
  93.        : "m" (sem->waking), "i" (&&next), "0" (0), "1" (sem->waking));
  94.     if (signal_pending(tsk)) {
  95.         atomic_inc(&sem->count);
  96.         ret = -EINTR;
  97.     }
  98. next:
  99. #endif
  100.  
  101.     return ret;
  102. }
  103.  
  104. /*
  105.  * waking_non_zero_trylock:
  106.  *    1    failed to lock
  107.  *    0    got the lock
  108.  */
  109. static inline int waking_non_zero_trylock(struct semaphore *sem)
  110. {
  111.     int ret;
  112. #ifndef CONFIG_RMW_INSNS
  113.     unsigned long flags;
  114.  
  115.     spin_lock_irqsave(&semaphore_wake_lock, flags);
  116.     ret = 1;
  117.     if (atomic_read(&sem->waking) > 0) {
  118.         atomic_dec(&sem->waking);
  119.         ret = 0;
  120.     } else
  121.         atomic_inc(&sem->count);
  122.     spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  123. #else
  124.     int tmp1, tmp2;
  125.  
  126.     __asm__ __volatile__
  127.       ("1:    movel    %1,%2\n"
  128.        "    jle    2f\n"
  129.        "    subql    #1,%2\n"
  130.        "    casl    %1,%2,%3\n"
  131.        "    jne    1b\n"
  132.        "    moveq    #0,%0\n"
  133.        "2:"
  134.        : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
  135.        : "m" (sem->waking), "0" (1), "1" (sem->waking));
  136.     if (ret)
  137.         atomic_inc(&sem->count);
  138. #endif
  139.     return ret;
  140. }
  141.  
  142. #endif
  143.