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
6 * Copyright (C) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
8 * This implemenation of synchronization variables is heavily based on
9 * one done by Steve Lord <lord@sgi.com>
11 * Paul Cassella <pwc@sgi.com>
14 #ifndef _ASM_IA64_SN_SV_H
15 #define _ASM_IA64_SN_SV_H
17 #include <linux/spinlock.h>
18 #include <asm/semaphore.h>
22 #define ASSERT(x) do { \
24 printk(KERN_ERR "%s\n", "Assertion failed: " # x); \
31 typedef void sv_mon_lock_t;
32 typedef void (*sv_mon_unlock_func_t)(sv_mon_lock_t *lock);
34 /* sv_flags values: */
36 #define SV_ORDER_FIFO 0x001
37 #define SV_ORDER_FILO 0x002
38 #define SV_ORDER_LIFO SV_ORDER_FILO
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
44 #define SV_ORDER_MASK 0x00f
47 #define SV_MON_SEMA 0x010
48 #define SV_MON_SPIN 0x020
50 #define SV_MON_MASK 0x0f0
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
58 This is currently only valid when the monitor lock is a spinlock.
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.
66 /* ditto for bottom halves */
71 /* sv_wait_flag values: */
72 #define SV_WAIT_SIG 0x001 /* Allow sv_wait to be interrupted by a signal */
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. */
82 #define DECLARE_SYNC_VARIABLE(sv, l, f) sv_t sv = sv_init(&sv, l, f)
85 * @sv the sync variable to initialize
86 * @monitor_lock the lock enforcing exclusive running in the monitor
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
96 void sv_init(sv_t *sv, sv_mon_lock_t *monitor_lock, int flags);
99 * Set SV_WAIT_SIG in sv_wait_flags to let the sv_wait be interrupted by signals.
101 * timeout is how long to wait before giving up, or 0 to wait
102 * indefinitely. It is given in jiffies, and is relative.
104 * The associated lock must be locked on entry. It is unlocked on return.
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
112 extern signed long sv_wait(sv_t *sv, int sv_wait_flags,
113 unsigned long timeout /* relative jiffies */);
115 static 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)
118 ASSERT(sv_mon_type == (sv->sv_flags & SV_MON_MASK));
120 ASSERT(lock == sv->sv_mon_lock);
122 sv->sv_mon_lock = lock;
124 return sv_wait(sv, sv_wait_flags, timeout);
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
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)
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)
141 /* These work as in Irix. */
142 void sv_signal(sv_t *sv);
143 void sv_broadcast(sv_t *sv);
145 /* This works as in Irix. */
146 void sv_destroy(sv_t *sv);
153 #endif /* _ASM_IA64_SN_SV_H */