As part of the libcaps threading work a number of routines in lwkt_thread.c
[dragonfly.git] / sys / i386 / include / lock.h
CommitLineData
984263bc 1/*
8a8d5d85 2 * Copyright (c) 2003, Matthew Dillon, All rights reserved.
984263bc
MD
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
11 *
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
22 * SUCH DAMAGE.
23 *
24 * $FreeBSD: src/sys/i386/include/lock.h,v 1.11.2.2 2000/09/30 02:49:34 ps Exp $
1f2de5d4 25 * $DragonFly: src/sys/i386/include/Attic/lock.h,v 1.6 2003/08/07 21:17:22 dillon Exp $
984263bc
MD
26 */
27
984263bc
MD
28#ifndef _MACHINE_LOCK_H_
29#define _MACHINE_LOCK_H_
30
8a8d5d85 31#ifndef _MACHINE_PSL_H_
1f2de5d4 32#include "psl.h"
8a8d5d85 33#endif
984263bc 34
8a8d5d85
MD
35/*
36 * MP_FREE_LOCK is used by both assembly and C under SMP.
37 */
984263bc 38#ifdef SMP
8a8d5d85
MD
39#define MP_FREE_LOCK 0xffffffff /* value of lock when free */
40#endif
984263bc 41
8a8d5d85 42#ifdef LOCORE
984263bc
MD
43
44/*
8a8d5d85
MD
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.
48 *
49 * Under UP the spinlock routines still serve to disable/restore
50 * interrupts.
984263bc
MD
51 */
52
984263bc 53
8a8d5d85 54#ifdef SMP
984263bc 55
8a8d5d85
MD
56#define SPIN_INIT(mem) \
57 movl $0,mem ; \
58
59#define SPIN_INIT_NOREG(mem) \
60 SPIN_INIT(mem) ; \
61
62#define SPIN_LOCK(mem) \
63 pushfl ; \
64 popl %ecx ; /* flags */ \
65 cli ; \
66 orl $PSL_C,%ecx ; /* make sure non-zero */ \
677: ; \
68 movl $0,%eax ; /* expected contents of lock */ \
96728c05
MD
69 lock cmpxchgl %ecx,mem ; /* Z=1 (jz) on success */ \
70 jnz 7b ; \
8a8d5d85
MD
71
72#define SPIN_LOCK_PUSH_REGS \
73 subl $8,%esp ; \
74 movl %ecx,(%esp) ; \
75 movl %eax,4(%esp) ; \
76
77#define SPIN_LOCK_POP_REGS \
78 movl (%esp),%ecx ; \
79 movl 4(%esp),%eax ; \
80 addl $8,%esp ; \
81
82#define SPIN_LOCK_FRAME_SIZE 8
83
84#define SPIN_LOCK_NOREG(mem) \
85 SPIN_LOCK_PUSH_REGS ; \
86 SPIN_LOCK(mem) ; \
87 SPIN_LOCK_POP_REGS ; \
88
89#define SPIN_UNLOCK(mem) \
90 pushl mem ; \
91 movl $0,mem ; \
92 popfl ; \
93
94#define SPIN_UNLOCK_PUSH_REGS
95#define SPIN_UNLOCK_POP_REGS
96#define SPIN_UNLOCK_FRAME_SIZE 0
97
98#define SPIN_UNLOCK_NOREG(mem) \
99 SPIN_UNLOCK(mem) ; \
984263bc 100
8a8d5d85 101#else
984263bc 102
8a8d5d85
MD
103#define SPIN_LOCK(mem) \
104 pushfl ; \
105 cli ; \
106 orl $PSL_C,(%esp) ; \
107 popl mem ; \
984263bc 108
8a8d5d85
MD
109#define SPIN_LOCK_PUSH_RESG
110#define SPIN_LOCK_POP_REGS
111#define SPIN_LOCK_FRAME_SIZE 0
984263bc 112
8a8d5d85
MD
113#define SPIN_UNLOCK(mem) \
114 pushl mem ; \
115 movl $0,mem ; \
116 popfl ; \
984263bc 117
8a8d5d85
MD
118#define SPIN_UNLOCK_PUSH_REGS
119#define SPIN_UNLOCK_POP_REGS
120#define SPIN_UNLOCK_FRAME_SIZE 0
984263bc 121
8a8d5d85 122#endif /* SMP */
984263bc 123
e14cc54f
MD
124#else /* !LOCORE */
125
126#ifdef _KERNEL
984263bc 127
8a8d5d85
MD
128/*
129 * Spinlock functions (UP and SMP). Under UP a spinlock still serves
130 * to disable/restore interrupts even if it doesn't spin.
131 */
132struct spinlock {
133 volatile int opaque;
134};
984263bc 135
8a8d5d85
MD
136typedef struct spinlock *spinlock_t;
137
138void mpintr_lock(void); /* disables int / spinlock combo */
139void mpintr_unlock(void);
140void com_lock(void); /* disables int / spinlock combo */
141void com_unlock(void);
142void imen_lock(void); /* disables int / spinlock combo */
143void imen_unlock(void);
144void clock_lock(void); /* disables int / spinlock combo */
145void clock_unlock(void);
146void cons_lock(void); /* disables int / spinlock combo */
147void cons_unlock(void);
148
149extern struct spinlock smp_rv_spinlock;
150
151void spin_lock(spinlock_t lock);
152void spin_lock_np(spinlock_t lock);
153void spin_unlock(spinlock_t lock);
154void spin_unlock_np(spinlock_t lock);
155#if 0
156void spin_lock_init(spinlock_t lock);
157#endif
984263bc
MD
158
159/*
8a8d5d85
MD
160 * Inline version of spinlock routines -- overrides assembly. Only unlock
161 * and init here please.
984263bc 162 */
8a8d5d85
MD
163static __inline void
164spin_lock_init(spinlock_t lock)
165{
166 lock->opaque = 0;
167}
984263bc
MD
168
169/*
8a8d5d85
MD
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.
984263bc 172 */
8a8d5d85 173#ifdef SMP
984263bc 174
8a8d5d85
MD
175void get_mplock(void);
176int try_mplock(void);
177void rel_mplock(void);
178int cpu_try_mplock(void);
179#if 0
180void cpu_rel_mplock(void);
181#endif
182void cpu_get_initial_mplock(void);
984263bc 183
8a8d5d85 184extern u_int mp_lock;
984263bc 185
8a8d5d85
MD
186#define MP_LOCK_HELD() (mp_lock == mycpu->gd_cpuid)
187#define ASSERT_MP_LOCK_HELD() KKASSERT(MP_LOCK_HELD())
984263bc 188
984263bc 189static __inline void
8a8d5d85 190cpu_rel_mplock(void)
984263bc 191{
8a8d5d85 192 mp_lock = MP_FREE_LOCK;
984263bc
MD
193}
194
8a8d5d85 195#else
984263bc 196
8a8d5d85
MD
197#define get_mplock()
198#define try_mplock() 1
199#define rel_mplock()
200#define ASSERT_MP_LOCK_HELD()
984263bc 201
8a8d5d85 202#endif /* SMP */
e14cc54f 203#endif /* _KERNEL */
8a8d5d85
MD
204#endif /* LOCORE */
205#endif /* !_MACHINE_LOCK_H_ */