linux-old/include/asm-m68k/semaphore.h
<<
>>
Prefs
   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
  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 * m68k version by Andreas Schwab
  22 */
  23
  24
  25struct semaphore {
  26        atomic_t count;
  27        atomic_t waking;
  28        wait_queue_head_t wait;
  29#if WAITQUEUE_DEBUG
  30        long __magic;
  31#endif
  32};
  33
  34#if WAITQUEUE_DEBUG
  35# define __SEM_DEBUG_INIT(name) \
  36                , (long)&(name).__magic
  37#else
  38# define __SEM_DEBUG_INIT(name)
  39#endif
  40
  41#define __SEMAPHORE_INITIALIZER(name,count) \
  42{ ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
  43        __SEM_DEBUG_INIT(name) }
  44
  45#define __MUTEX_INITIALIZER(name) \
  46        __SEMAPHORE_INITIALIZER(name,1)
  47
  48#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
  49        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  50
  51#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  52#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  53
  54static inline void sema_init(struct semaphore *sem, int val)
  55{
  56        *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
  57}
  58
  59static inline void init_MUTEX (struct semaphore *sem)
  60{
  61        sema_init(sem, 1);
  62}
  63
  64static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  65{
  66        sema_init(sem, 0);
  67}
  68
  69asmlinkage void __down_failed(void /* special register calling convention */);
  70asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
  71asmlinkage int  __down_failed_trylock(void  /* params in registers */);
  72asmlinkage void __up_wakeup(void /* special register calling convention */);
  73
  74asmlinkage void __down(struct semaphore * sem);
  75asmlinkage int  __down_interruptible(struct semaphore * sem);
  76asmlinkage int  __down_trylock(struct semaphore * sem);
  77asmlinkage void __up(struct semaphore * sem);
  78
  79/*
  80 * This is ugly, but we want the default case to fall through.
  81 * "down_failed" is a special asm handler that calls the C
  82 * routine that actually waits. See arch/m68k/lib/semaphore.S
  83 */
  84static inline void down(struct semaphore *sem)
  85{
  86        register struct semaphore *sem1 __asm__ ("%a1") = sem;
  87
  88#if WAITQUEUE_DEBUG
  89        CHECK_MAGIC(sem->__magic);
  90#endif
  91
  92        __asm__ __volatile__(
  93                "| atomic down operation\n\t"
  94                "subql #1,%0@\n\t"
  95                "jmi 2f\n\t"
  96                "1:\n"
  97                LOCK_SECTION_START(".even\n\t")
  98                "2:\tpea 1b\n\t"
  99                "jbra __down_failed\n"
 100                LOCK_SECTION_END
 101                : /* no outputs */
 102                : "a" (sem1)
 103                : "memory");
 104}
 105
 106static inline int down_interruptible(struct semaphore *sem)
 107{
 108        register struct semaphore *sem1 __asm__ ("%a1") = sem;
 109        register int result __asm__ ("%d0");
 110
 111#if WAITQUEUE_DEBUG
 112        CHECK_MAGIC(sem->__magic);
 113#endif
 114
 115        __asm__ __volatile__(
 116                "| atomic interruptible down operation\n\t"
 117                "subql #1,%1@\n\t"
 118                "jmi 2f\n\t"
 119                "clrl %0\n"
 120                "1:\n"
 121                LOCK_SECTION_START(".even\n\t")
 122                "2:\tpea 1b\n\t"
 123                "jbra __down_failed_interruptible\n"
 124                LOCK_SECTION_END
 125                : "=d" (result)
 126                : "a" (sem1)
 127                : "memory");
 128        return result;
 129}
 130
 131static inline int down_trylock(struct semaphore *sem)
 132{
 133        register struct semaphore *sem1 __asm__ ("%a1") = sem;
 134        register int result __asm__ ("%d0");
 135
 136#if WAITQUEUE_DEBUG
 137        CHECK_MAGIC(sem->__magic);
 138#endif
 139
 140        __asm__ __volatile__(
 141                "| atomic down trylock operation\n\t"
 142                "subql #1,%1@\n\t"
 143                "jmi 2f\n\t"
 144                "clrl %0\n"
 145                "1:\n"
 146                LOCK_SECTION_START(".even\n\t")
 147                "2:\tpea 1b\n\t"
 148                "jbra __down_failed_trylock\n"
 149                LOCK_SECTION_END
 150                : "=d" (result)
 151                : "a" (sem1)
 152                : "memory");
 153        return result;
 154}
 155
 156/*
 157 * Note! This is subtle. We jump to wake people up only if
 158 * the semaphore was negative (== somebody was waiting on it).
 159 * The default case (no contention) will result in NO
 160 * jumps for both down() and up().
 161 */
 162static inline void up(struct semaphore *sem)
 163{
 164        register struct semaphore *sem1 __asm__ ("%a1") = sem;
 165
 166#if WAITQUEUE_DEBUG
 167        CHECK_MAGIC(sem->__magic);
 168#endif
 169
 170        __asm__ __volatile__(
 171                "| atomic up operation\n\t"
 172                "addql #1,%0@\n\t"
 173                "jle 2f\n"
 174                "1:\n"
 175                LOCK_SECTION_START(".even\n\t")
 176                "2:\t"
 177                "pea 1b\n\t"
 178                "jbra __up_wakeup\n"
 179                LOCK_SECTION_END
 180                : /* no outputs */
 181                : "a" (sem1)
 182                : "memory");
 183}
 184
 185
 186static inline int sem_getcount(struct semaphore *sem)
 187{
 188        return atomic_read(&sem->count);
 189}
 190
 191#endif /* __ASSEMBLY__ */
 192
 193#endif
 194
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.