linux/include/asm-sh/semaphore.h
<<
>>
Prefs
   1#ifndef __ASM_SH_SEMAPHORE_H
   2#define __ASM_SH_SEMAPHORE_H
   3
   4#include <linux/linkage.h>
   5
   6#ifdef __KERNEL__
   7/*
   8 * SMP- and interrupt-safe semaphores.
   9 *
  10 * (C) Copyright 1996 Linus Torvalds
  11 *
  12 * SuperH verison by Niibe Yutaka
  13 *  (Currently no asm implementation but generic C code...)
  14 */
  15
  16#include <linux/spinlock.h>
  17#include <linux/rwsem.h>
  18#include <linux/wait.h>
  19
  20#include <asm/system.h>
  21#include <asm/atomic.h>
  22
  23struct semaphore {
  24        atomic_t count;
  25        int sleepers;
  26        wait_queue_head_t wait;
  27};
  28
  29#define __SEMAPHORE_INITIALIZER(name, n)                                \
  30{                                                                       \
  31        .count          = ATOMIC_INIT(n),                               \
  32        .sleepers       = 0,                                            \
  33        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
  34}
  35
  36#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
  37        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  38
  39#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  40
  41static inline void sema_init (struct semaphore *sem, int val)
  42{
  43/*
  44 *      *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
  45 *
  46 * i'd rather use the more flexible initialization above, but sadly
  47 * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
  48 */
  49        atomic_set(&sem->count, val);
  50        sem->sleepers = 0;
  51        init_waitqueue_head(&sem->wait);
  52}
  53
  54static inline void init_MUTEX (struct semaphore *sem)
  55{
  56        sema_init(sem, 1);
  57}
  58
  59static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  60{
  61        sema_init(sem, 0);
  62}
  63
  64#if 0
  65asmlinkage void __down_failed(void /* special register calling convention */);
  66asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
  67asmlinkage int  __down_failed_trylock(void  /* params in registers */);
  68asmlinkage void __up_wakeup(void /* special register calling convention */);
  69#endif
  70
  71asmlinkage void __down(struct semaphore * sem);
  72asmlinkage int  __down_interruptible(struct semaphore * sem);
  73asmlinkage int  __down_trylock(struct semaphore * sem);
  74asmlinkage void __up(struct semaphore * sem);
  75
  76extern spinlock_t semaphore_wake_lock;
  77
  78static inline void down(struct semaphore * sem)
  79{
  80        might_sleep();
  81        if (atomic_dec_return(&sem->count) < 0)
  82                __down(sem);
  83}
  84
  85static inline int down_interruptible(struct semaphore * sem)
  86{
  87        int ret = 0;
  88
  89        might_sleep();
  90        if (atomic_dec_return(&sem->count) < 0)
  91                ret = __down_interruptible(sem);
  92        return ret;
  93}
  94
  95static inline int down_trylock(struct semaphore * sem)
  96{
  97        int ret = 0;
  98
  99        if (atomic_dec_return(&sem->count) < 0)
 100                ret = __down_trylock(sem);
 101        return ret;
 102}
 103
 104/*
 105 * Note! This is subtle. We jump to wake people up only if
 106 * the semaphore was negative (== somebody was waiting on it).
 107 */
 108static inline void up(struct semaphore * sem)
 109{
 110        if (atomic_inc_return(&sem->count) <= 0)
 111                __up(sem);
 112}
 113
 114#endif
 115#endif /* __ASM_SH_SEMAPHORE_H */
 116