subr_trap.c (b454c6dd299fab058187dc012666a5c059dfef68) | subr_trap.c (79065dba2a88baf780767cbb1bb31d4525a08528) |
---|---|
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 * --- 56 unchanged lines hidden (view full) --- 65userret(td, frame, oticks) 66 struct thread *td; 67 struct trapframe *frame; 68 u_int oticks; 69{ 70 struct proc *p = td->td_proc; 71 struct kse *ke = td->td_kse; 72 struct ksegrp *kg = td->td_ksegrp; | 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 * --- 56 unchanged lines hidden (view full) --- 65userret(td, frame, oticks) 66 struct thread *td; 67 struct trapframe *frame; 68 u_int oticks; 69{ 70 struct proc *p = td->td_proc; 71 struct kse *ke = td->td_kse; 72 struct ksegrp *kg = td->td_ksegrp; |
73 int sig; | |
74 | 73 |
74#ifdef INVARIANTS 75 /* Check that we called signotify() enough. */ |
|
75 mtx_lock(&Giant); 76 PROC_LOCK(p); | 76 mtx_lock(&Giant); 77 PROC_LOCK(p); |
77 while ((sig = CURSIG(p)) != 0) 78 postsig(sig); | 78 mtx_lock_spin(&sched_lock); 79 if (SIGPENDING(p) && ((p->p_sflag & PS_NEEDSIGCHK) == 0 || 80 (p->p_kse.ke_flags & KEF_ASTPENDING) == 0)) 81 printf("failed to set signal flags proprly for ast()\n"); 82 mtx_unlock_spin(&sched_lock); |
79 PROC_UNLOCK(p); 80 mtx_unlock(&Giant); | 83 PROC_UNLOCK(p); 84 mtx_unlock(&Giant); |
85#endif |
|
81 | 86 |
82 mtx_lock_spin(&sched_lock); 83 td->td_priority = kg->kg_user_pri; 84 if (ke->ke_flags & KEF_NEEDRESCHED) { 85 DROP_GIANT(); 86 setrunqueue(td); 87 p->p_stats->p_ru.ru_nivcsw++; 88 mi_switch(); 89 mtx_unlock_spin(&sched_lock); 90 PICKUP_GIANT(); 91 mtx_lock(&Giant); 92 PROC_LOCK(p); 93 while ((sig = CURSIG(p)) != 0) 94 postsig(sig); 95 mtx_unlock(&Giant); 96 PROC_UNLOCK(p); | 87 /* 88 * XXX we cheat slightly on the locking here to avoid locking in 89 * the usual case. Setting td_priority here is essentially an 90 * incomplete workaround for not setting it properly elsewhere. 91 * Now that some interrupt handlers are threads, not setting it 92 * properly elsewhere can clobber it in the window between setting 93 * it here and returning to user mode, so don't waste time setting 94 * it perfectly here. 95 */ 96 if (td->td_priority != kg->kg_user_pri) { |
97 mtx_lock_spin(&sched_lock); | 97 mtx_lock_spin(&sched_lock); |
98 td->td_priority = kg->kg_user_pri; 99 mtx_unlock_spin(&sched_lock); |
|
98 } 99 100 /* 101 * Charge system time if profiling. | 100 } 101 102 /* 103 * Charge system time if profiling. |
104 * 105 * XXX should move PS_PROFIL to a place that can obviously be 106 * accessed safely without sched_lock. |
|
102 */ 103 if (p->p_sflag & PS_PROFIL) { 104 quad_t ticks; 105 | 107 */ 108 if (p->p_sflag & PS_PROFIL) { 109 quad_t ticks; 110 |
111 mtx_lock_spin(&sched_lock); |
|
106 ticks = ke->ke_sticks - oticks; 107 mtx_unlock_spin(&sched_lock); 108 addupc_task(ke, TRAPF_PC(frame), (u_int)ticks * psratio); | 112 ticks = ke->ke_sticks - oticks; 113 mtx_unlock_spin(&sched_lock); 114 addupc_task(ke, TRAPF_PC(frame), (u_int)ticks * psratio); |
109 } else 110 mtx_unlock_spin(&sched_lock); | 115 } |
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 thread *td = curthread; 123 struct proc *p = td->td_proc; 124 struct kse *ke = td->td_kse; | 116} 117 118/* 119 * Process an asynchronous software trap. 120 * This is relatively easy. 121 * This function will return with preemption disabled. 122 */ 123void 124ast(framep) 125 struct trapframe *framep; 126{ 127 struct thread *td = curthread; 128 struct proc *p = td->td_proc; 129 struct kse *ke = td->td_kse; |
130 struct ksegrp *kg = td->td_ksegrp; |
|
125 u_int prticks, sticks; 126 int sflag; 127 int flags; | 131 u_int prticks, sticks; 132 int sflag; 133 int flags; |
134 int sig; |
|
128#if defined(DEV_NPX) && !defined(SMP) 129 int ucode; 130#endif 131 132 KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode")); 133#ifdef WITNESS 134 if (witness_list(td)) 135 panic("Returning to user mode with mutex(s) held"); 136#endif 137 mtx_assert(&Giant, MA_NOTOWNED); | 135#if defined(DEV_NPX) && !defined(SMP) 136 int ucode; 137#endif 138 139 KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode")); 140#ifdef WITNESS 141 if (witness_list(td)) 142 panic("Returning to user mode with mutex(s) held"); 143#endif 144 mtx_assert(&Giant, MA_NOTOWNED); |
145 mtx_assert(&sched_lock, MA_NOTOWNED); |
|
138 prticks = 0; /* XXX: Quiet warning. */ 139 td->td_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 * ast() will be called again. 146 */ 147 mtx_lock_spin(&sched_lock); 148 sticks = ke->ke_sticks; 149 sflag = p->p_sflag; 150 flags = ke->ke_flags; | 146 prticks = 0; /* XXX: Quiet warning. */ 147 td->td_frame = framep; 148 /* 149 * This updates the p_sflag's for the checks below in one 150 * "atomic" operation with turning off the astpending flag. 151 * If another AST is triggered while we are handling the 152 * AST's saved in sflag, the astpending flag will be set and 153 * ast() will be called again. 154 */ 155 mtx_lock_spin(&sched_lock); 156 sticks = ke->ke_sticks; 157 sflag = p->p_sflag; 158 flags = ke->ke_flags; |
151 p->p_sflag &= ~(PS_PROFPEND | PS_ALRMPEND); 152 ke->ke_flags &= ~(KEF_OWEUPC | KEF_ASTPENDING); | 159 p->p_sflag &= ~(PS_ALRMPEND | PS_NEEDSIGCHK | PS_PROFPEND); 160 ke->ke_flags &= ~(KEF_ASTPENDING | KEF_NEEDRESCHED | KEF_OWEUPC); |
153 cnt.v_soft++; 154 if (flags & KEF_OWEUPC && sflag & PS_PROFIL) { 155 prticks = p->p_stats->p_prof.pr_ticks; 156 p->p_stats->p_prof.pr_ticks = 0; 157 } 158 mtx_unlock_spin(&sched_lock); 159 160 if (td->td_ucred != p->p_ucred) --- 15 unchanged lines hidden (view full) --- 176 } 177 } 178#endif 179 if (sflag & PS_PROFPEND) { 180 PROC_LOCK(p); 181 psignal(p, SIGPROF); 182 PROC_UNLOCK(p); 183 } | 161 cnt.v_soft++; 162 if (flags & KEF_OWEUPC && sflag & PS_PROFIL) { 163 prticks = p->p_stats->p_prof.pr_ticks; 164 p->p_stats->p_prof.pr_ticks = 0; 165 } 166 mtx_unlock_spin(&sched_lock); 167 168 if (td->td_ucred != p->p_ucred) --- 15 unchanged lines hidden (view full) --- 184 } 185 } 186#endif 187 if (sflag & PS_PROFPEND) { 188 PROC_LOCK(p); 189 psignal(p, SIGPROF); 190 PROC_UNLOCK(p); 191 } |
192 if (flags & KEF_NEEDRESCHED) { 193 mtx_lock_spin(&sched_lock); 194 td->td_priority = kg->kg_user_pri; 195 setrunqueue(td); 196 p->p_stats->p_ru.ru_nivcsw++; 197 mi_switch(); 198 mtx_unlock_spin(&sched_lock); 199 } 200 if (sflag & PS_NEEDSIGCHK) { 201 mtx_lock(&Giant); 202 PROC_LOCK(p); 203 while ((sig = CURSIG(p)) != 0) 204 postsig(sig); 205 PROC_UNLOCK(p); 206 mtx_unlock(&Giant); 207 } |
|
184 185 userret(td, framep, sticks); 186#ifdef DIAGNOSTIC 187 cred_free_thread(td); 188#endif 189 mtx_assert(&Giant, MA_NOTOWNED); 190} | 208 209 userret(td, framep, sticks); 210#ifdef DIAGNOSTIC 211 cred_free_thread(td); 212#endif 213 mtx_assert(&Giant, MA_NOTOWNED); 214} |