2 * Copyright (c) 2003, Matthew Dillon, All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. The name of the developer may NOT be used to endorse or promote products
10 * derived from this software without specific prior written permission.
12 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * $FreeBSD: src/sys/i386/include/lock.h,v 1.11.2.2 2000/09/30 02:49:34 ps Exp $
25 * $DragonFly: src/sys/i386/include/Attic/lock.h,v 1.6 2003/08/07 21:17:22 dillon Exp $
28 #ifndef _MACHINE_LOCK_H_
29 #define _MACHINE_LOCK_H_
31 #ifndef _MACHINE_PSL_H_
36 * MP_FREE_LOCK is used by both assembly and C under SMP.
39 #define MP_FREE_LOCK 0xffffffff /* value of lock when free */
45 * Spinlock assembly support. Note: eax and ecx can be tromped. No
46 * other register will be. Note that these routines are sometimes
47 * called with (%edx) as the mem argument.
49 * Under UP the spinlock routines still serve to disable/restore
56 #define SPIN_INIT(mem) \
59 #define SPIN_INIT_NOREG(mem) \
62 #define SPIN_LOCK(mem) \
64 popl %ecx ; /* flags */ \
66 orl $PSL_C,%ecx ; /* make sure non-zero */ \
68 movl $0,%eax ; /* expected contents of lock */ \
69 lock cmpxchgl %ecx,mem ; /* Z=1 (jz) on success */ \
72 #define SPIN_LOCK_PUSH_REGS \
77 #define SPIN_LOCK_POP_REGS \
82 #define SPIN_LOCK_FRAME_SIZE 8
84 #define SPIN_LOCK_NOREG(mem) \
85 SPIN_LOCK_PUSH_REGS ; \
87 SPIN_LOCK_POP_REGS ; \
89 #define SPIN_UNLOCK(mem) \
94 #define SPIN_UNLOCK_PUSH_REGS
95 #define SPIN_UNLOCK_POP_REGS
96 #define SPIN_UNLOCK_FRAME_SIZE 0
98 #define SPIN_UNLOCK_NOREG(mem) \
103 #define SPIN_LOCK(mem) \
106 orl $PSL_C,(%esp) ; \
109 #define SPIN_LOCK_PUSH_RESG
110 #define SPIN_LOCK_POP_REGS
111 #define SPIN_LOCK_FRAME_SIZE 0
113 #define SPIN_UNLOCK(mem) \
118 #define SPIN_UNLOCK_PUSH_REGS
119 #define SPIN_UNLOCK_POP_REGS
120 #define SPIN_UNLOCK_FRAME_SIZE 0
129 * Spinlock functions (UP and SMP). Under UP a spinlock still serves
130 * to disable/restore interrupts even if it doesn't spin.
136 typedef struct spinlock *spinlock_t;
138 void mpintr_lock(void); /* disables int / spinlock combo */
139 void mpintr_unlock(void);
140 void com_lock(void); /* disables int / spinlock combo */
141 void com_unlock(void);
142 void imen_lock(void); /* disables int / spinlock combo */
143 void imen_unlock(void);
144 void clock_lock(void); /* disables int / spinlock combo */
145 void clock_unlock(void);
146 void cons_lock(void); /* disables int / spinlock combo */
147 void cons_unlock(void);
149 extern struct spinlock smp_rv_spinlock;
151 void spin_lock(spinlock_t lock);
152 void spin_lock_np(spinlock_t lock);
153 void spin_unlock(spinlock_t lock);
154 void spin_unlock_np(spinlock_t lock);
156 void spin_lock_init(spinlock_t lock);
160 * Inline version of spinlock routines -- overrides assembly. Only unlock
161 * and init here please.
164 spin_lock_init(spinlock_t lock)
170 * MP LOCK functions for SMP and UP. Under UP the MP lock does not exist
171 * but we leave a few functions intact as macros for convenience.
175 void get_mplock(void);
176 int try_mplock(void);
177 void rel_mplock(void);
178 int cpu_try_mplock(void);
180 void cpu_rel_mplock(void);
182 void cpu_get_initial_mplock(void);
184 extern u_int mp_lock;
186 #define MP_LOCK_HELD() (mp_lock == mycpu->gd_cpuid)
187 #define ASSERT_MP_LOCK_HELD() KKASSERT(MP_LOCK_HELD())
192 mp_lock = MP_FREE_LOCK;
198 #define try_mplock() 1
200 #define ASSERT_MP_LOCK_HELD()
205 #endif /* !_MACHINE_LOCK_H_ */