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