Deleted Added
sdiff udiff text old ( 82585 ) new ( 83366 )
full compact
1/*-
2 * Copyright (C) 1994, David Greenman
3 * Copyright (c) 1990, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the University of Utah, and William Jolitz.
8 *

--- 21 unchanged lines hidden (view full) ---

30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91
38 * $FreeBSD: head/sys/kern/subr_trap.c 82585 2001-08-30 18:50:57Z dillon $
39 */
40
41#ifdef __i386__
42#include "opt_npx.h"
43#endif
44
45#include <sys/param.h>
46#include <sys/bus.h>

--- 10 unchanged lines hidden (view full) ---

57
58/*
59 * Define the code needed before returning to user mode, for
60 * trap and syscall.
61 *
62 * MPSAFE
63 */
64void
65userret(p, frame, oticks)
66 struct proc *p;
67 struct trapframe *frame;
68 u_int oticks;
69{
70 int sig;
71
72 mtx_lock(&Giant);
73 PROC_LOCK(p);
74 while ((sig = CURSIG(p)) != 0)
75 postsig(sig);
76 PROC_UNLOCK(p);
77 mtx_unlock(&Giant);
78
79 mtx_lock_spin(&sched_lock);
80 p->p_pri.pri_level = p->p_pri.pri_user;
81 if (p->p_sflag & PS_NEEDRESCHED) {
82 /*
83 * Since we are curproc, a clock interrupt could
84 * change our priority without changing run queues
85 * (the running process is not kept on a run queue).
86 * If this happened after we setrunqueue ourselves but
87 * before we switch()'ed, we might not be on the queue
88 * indicated by our priority.
89 */
90 DROP_GIANT_NOSWITCH();
91 setrunqueue(p);
92 p->p_stats->p_ru.ru_nivcsw++;
93 mi_switch();
94 mtx_unlock_spin(&sched_lock);
95 PICKUP_GIANT();
96 mtx_lock(&Giant);
97 PROC_LOCK(p);
98 while ((sig = CURSIG(p)) != 0)
99 postsig(sig);
100 mtx_unlock(&Giant);
101 PROC_UNLOCK(p);
102 } else
103 mtx_unlock_spin(&sched_lock);
104
105 /*
106 * Charge system time if profiling.
107 */
108 if (p->p_sflag & PS_PROFIL)
109 addupc_task(p, TRAPF_PC(frame),
110 ((u_int)p->p_sticks - oticks) * psratio);
111}
112
113/*
114 * Process an asynchronous software trap.
115 * This is relatively easy.
116 * This function will return with preemption disabled.
117 */
118void
119ast(framep)
120 struct trapframe *framep;
121{
122 struct proc *p = CURPROC;
123 u_int prticks, sticks;
124 critical_t s;
125 int sflag;
126#if defined(DEV_NPX) && !defined(SMP)
127 int ucode;
128#endif
129
130 KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode"));
131#ifdef WITNESS
132 if (witness_list(p))
133 panic("Returning to user mode with mutex(s) held");
134#endif
135 mtx_assert(&Giant, MA_NOTOWNED);
136 s = critical_enter();
137 while ((p->p_sflag & (PS_ASTPENDING | PS_NEEDRESCHED)) != 0) {
138 critical_exit(s);
139 p->p_frame = framep;
140 /*
141 * This updates the p_sflag's for the checks below in one
142 * "atomic" operation with turning off the astpending flag.
143 * If another AST is triggered while we are handling the
144 * AST's saved in sflag, the astpending flag will be set and
145 * we will loop again.
146 */
147 mtx_lock_spin(&sched_lock);
148 sticks = p->p_sticks;
149 sflag = p->p_sflag;
150 p->p_sflag &= ~(PS_OWEUPC | PS_ALRMPEND | PS_PROFPEND |
151 PS_ASTPENDING);
152 cnt.v_soft++;
153 if (sflag & PS_OWEUPC) {
154 prticks = p->p_stats->p_prof.pr_ticks;
155 p->p_stats->p_prof.pr_ticks = 0;
156 mtx_unlock_spin(&sched_lock);
157 addupc_task(p, p->p_stats->p_prof.pr_addr, prticks);
158 } else
159 mtx_unlock_spin(&sched_lock);
160 if (sflag & PS_ALRMPEND) {
161 PROC_LOCK(p);
162 psignal(p, SIGVTALRM);
163 PROC_UNLOCK(p);
164 }
165#if defined(DEV_NPX) && !defined(SMP)

--- 7 unchanged lines hidden (view full) ---

173 }
174#endif
175 if (sflag & PS_PROFPEND) {
176 PROC_LOCK(p);
177 psignal(p, SIGPROF);
178 PROC_UNLOCK(p);
179 }
180
181 userret(p, framep, sticks);
182 s = critical_enter();
183 }
184 mtx_assert(&Giant, MA_NOTOWNED);
185 /*
186 * We need to keep interrupts disabled so that if any further AST's
187 * come in, the interrupt they come in on will be delayed until we
188 * finish returning to userland. We assume that the return to userland
189 * will perform the equivalent of critical_exit().
190 */
191}