1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved 7 * 8 * This implemenation of synchronization variables is heavily based on 9 * one done by Steve Lord <lord@sgi.com> 10 * 11 * Paul Cassella <pwc@sgi.com> 12 */ 13 14#ifndef _ASM_IA64_SN_SV_H 15#define _ASM_IA64_SN_SV_H 16 17#include <linux/spinlock.h> 18#include <asm/semaphore.h> 19 20#ifndef ASSERT 21 22#define ASSERT(x) do { \ 23 if(!(x)) { \ 24 printk(KERN_ERR "%s\n", "Assertion failed: " # x); \ 25 BUG(); \ 26 } \ 27 } while(0) 28#define _SV_ASSERT 29#endif 30 31typedef void sv_mon_lock_t; 32typedef void (*sv_mon_unlock_func_t)(sv_mon_lock_t *lock); 33 34/* sv_flags values: */ 35 36#define SV_ORDER_FIFO 0x001 37#define SV_ORDER_FILO 0x002 38#define SV_ORDER_LIFO SV_ORDER_FILO 39 40/* If at some point one order becomes preferable to others, we can 41 switch to it if the caller of sv_init doesn't specify. */ 42#define SV_ORDER_DEFAULT SV_ORDER_FIFO 43 44#define SV_ORDER_MASK 0x00f 45 46 47#define SV_MON_SEMA 0x010 48#define SV_MON_SPIN 0x020 49 50#define SV_MON_MASK 0x0f0 51 52 53/* 54 If the monitor lock can be aquired from interrupts. Note that this 55 is a superset of the cases in which the sv can be touched from 56 interrupts. 57 58 This is currently only valid when the monitor lock is a spinlock. 59 60 If this is used, sv_wait, sv_signal, and sv_broadcast must all be 61 called with interrupts disabled, which has to happen anyway to have 62 acquired the monitor spinlock. 63 */ 64#define SV_INTS 0x100 65 66/* ditto for bottom halves */ 67#define SV_BHS 0x200 68 69 70 71/* sv_wait_flag values: */ 72#define SV_WAIT_SIG 0x001 /* Allow sv_wait to be interrupted by a signal */ 73 74typedef struct sv_s { 75 wait_queue_head_t sv_waiters; 76 sv_mon_lock_t *sv_mon_lock; /* Lock held for exclusive access to monitor. */ 77 sv_mon_unlock_func_t sv_mon_unlock_func; 78 spinlock_t sv_lock; /* Spinlock protecting the sv itself. */ 79 int sv_flags; 80} sv_t; 81 82#define DECLARE_SYNC_VARIABLE(sv, l, f) sv_t sv = sv_init(&sv, l, f) 83 84/* 85 * @sv the sync variable to initialize 86 * @monitor_lock the lock enforcing exclusive running in the monitor 87 * @flags one of 88 * SV_MON_SEMA monitor_lock is a semaphore 89 * SV_MON_SPIN monitor_lock is a spinlock 90 * and a bitwise or of some subset of 91 * SV_INTS - the monitor lock can be acquired from interrupts (and 92 * hence, whenever we hold it, interrupts are disabled or 93 * we're in an interrupt.) This is only valid when 94 * SV_MON_SPIN is set. 95 */ 96void sv_init(sv_t *sv, sv_mon_lock_t *monitor_lock, int flags); 97 98/* 99 * Set SV_WAIT_SIG in sv_wait_flags to let the sv_wait be interrupted by signals. 100 * 101 * timeout is how long to wait before giving up, or 0 to wait 102 * indefinately. It is given in jiffies, and is relative. 103 * 104 * The associated lock must be locked on entry. It is unlocked on return. 105 * 106 * Return values: 107 * 108 * n < 0 : interrupted, -n jiffies remaining on timeout, or -1 if timeout == 0 109 * n = 0 : timeout expired 110 * n > 0 : sv_signal()'d, n jiffies remaining on timeout, or 1 if timeout == 0 111 */ 112extern signed long sv_wait(sv_t *sv, int sv_wait_flags, 113 unsigned long timeout /* relative jiffies */); 114 115static inline int sv_wait_compat(sv_t *sv, sv_mon_lock_t *lock, int sv_wait_flags, 116 unsigned long timeout, int sv_mon_type) 117{ 118 ASSERT(sv_mon_type == (sv->sv_flags & SV_MON_MASK)); 119 if(sv->sv_mon_lock) 120 ASSERT(lock == sv->sv_mon_lock); 121 else 122 sv->sv_mon_lock = lock; 123 124 return sv_wait(sv, sv_wait_flags, timeout); 125} 126 127 128/* These work like Irix's sv_wait() and sv_wait_sig(), except the 129 caller must call the one correpsonding to the type of the monitor 130 lock. */ 131#define sv_spin_wait(sv, lock) \ 132 sv_wait_compat(sv, lock, 0, 0, SV_MON_SPIN) 133#define sv_spin_wait_sig(sv, lock) \ 134 sv_wait_compat(sv, lock, SV_WAIT_SIG, 0, SV_MON_SPIN) 135 136#define sv_sema_wait(sv, lock) \ 137 sv_wait_compat(sv, lock, 0, 0, SV_MON_SEMA) 138#define sv_sema_wait_sig(sv, lock) \ 139 sv_wait_compat(sv, lock, SV_WAIT_SIG, 0, SV_MON_SEMA) 140 141/* These work as in Irix. */ 142void sv_signal(sv_t *sv); 143void sv_broadcast(sv_t *sv); 144 145/* This works as in Irix. */ 146void sv_destroy(sv_t *sv); 147 148#ifdef _SV_ASSERT 149#undef ASSERT 150#undef _SV_ASSERT 151#endif 152 153#endif /* _ASM_IA64_SN_SV_H */ 154