linux-old/include/asm-parisc/semaphore.h
<<
>>
Prefs
   1#ifndef _ASM_PARISC_SEMAPHORE_H
   2#define _ASM_PARISC_SEMAPHORE_H
   3
   4/*
   5 * SMP- and interrupt-safe semaphores.
   6 *
   7 * (C) Copyright 1996 Linus Torvalds
   8 *
   9 * PA-RISC version by Matthew Wilcox
  10 *
  11 */
  12
  13#include <linux/spinlock.h>
  14#include <linux/wait.h>
  15#include <linux/rwsem.h>
  16
  17#include <asm/system.h>
  18
  19/*
  20 * The `count' is initialised to the number of people who are allowed to
  21 * take the lock.  (Normally we want a mutex, so this is `1').  if
  22 * `count' is positive, the lock can be taken.  if it's 0, no-one is
  23 * waiting on it.  if it's -1, at least one task is waiting.
  24 */
  25struct semaphore {
  26        spinlock_t      sentry;
  27        int             count;
  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{ SPIN_LOCK_UNLOCKED, count, __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
  54extern 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
  69static inline int sem_getcount(struct semaphore *sem)
  70{
  71        return sem->count;
  72}
  73
  74asmlinkage void __down(struct semaphore * sem);
  75asmlinkage int  __down_interruptible(struct semaphore * sem);
  76asmlinkage void __up(struct semaphore * sem);
  77
  78/* Semaphores can be `tried' from irq context.  So we have to disable
  79 * interrupts while we're messing with the semaphore.  Sorry.
  80 */
  81
  82extern __inline__ void down(struct semaphore * sem)
  83{
  84#if WAITQUEUE_DEBUG
  85        CHECK_MAGIC(sem->__magic);
  86#endif
  87
  88        spin_lock_irq(&sem->sentry);
  89        if (sem->count > 0) {
  90                sem->count--;
  91        } else {
  92                __down(sem);
  93        }
  94        spin_unlock_irq(&sem->sentry);
  95}
  96
  97extern __inline__ int down_interruptible(struct semaphore * sem)
  98{
  99        int ret = 0;
 100#if WAITQUEUE_DEBUG
 101        CHECK_MAGIC(sem->__magic);
 102#endif
 103
 104        spin_lock_irq(&sem->sentry);
 105        if (sem->count > 0) {
 106                sem->count--;
 107        } else {
 108                ret = __down_interruptible(sem);
 109        }
 110        spin_unlock_irq(&sem->sentry);
 111        return ret;
 112}
 113
 114/*
 115 * down_trylock returns 0 on success, 1 if we failed to get the lock.
 116 * May not sleep, but must preserve irq state
 117 */
 118extern __inline__ int down_trylock(struct semaphore * sem)
 119{
 120        int flags, count;
 121#if WAITQUEUE_DEBUG
 122        CHECK_MAGIC(sem->__magic);
 123#endif
 124
 125        spin_lock_irqsave(&sem->sentry, flags);
 126        count = sem->count - 1;
 127        if (count >= 0)
 128                sem->count = count;
 129        spin_unlock_irqrestore(&sem->sentry, flags);
 130        return (count < 0);
 131}
 132
 133/*
 134 * Note! This is subtle. We jump to wake people up only if
 135 * the semaphore was negative (== somebody was waiting on it).
 136 */
 137extern __inline__ void up(struct semaphore * sem)
 138{
 139        int flags;
 140#if WAITQUEUE_DEBUG
 141        CHECK_MAGIC(sem->__magic);
 142#endif
 143        spin_lock_irqsave(&sem->sentry, flags);
 144        if (sem->count < 0) {
 145                __up(sem);
 146        } else {
 147                sem->count++;
 148        }
 149        spin_unlock_irqrestore(&sem->sentry, flags);
 150}
 151
 152#endif /* _ASM_PARISC_SEMAPHORE_H */
 153
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.