|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1987 Carnegie-Mellon University ! 28: * All rights reserved. The CMU software License Agreement specifies ! 29: * the terms and conditions for use and redistribution. ! 30: */ ! 31: ! 32: #import <cputypes.h> ! 33: #import <cpus.h> ! 34: ! 35: #import <sys/param.h> ! 36: #import <sys/systm.h> ! 37: #import <sys/proc.h> ! 38: #import <sys/user.h> ! 39: #import <sys/file.h> ! 40: #import <sys/vnode.h> ! 41: #import <sys/kernel.h> ! 42: #import <sys/buf.h> ! 43: ! 44: #import <machine/spl.h> ! 45: ! 46: #import <kern/ast.h> ! 47: #import <sys/callout.h> ! 48: #import <kern/queue.h> ! 49: #import <kern/lock.h> ! 50: #import <kern/thread.h> ! 51: #import <kern/sched.h> ! 52: #import <kern/sched_prim.h> ! 53: #import <mach/machine.h> ! 54: #import <kern/parallel.h> ! 55: #import <kern/processor.h> ! 56: ! 57: #import <machine/cpu.h> ! 58: #import <vm/pmap.h> ! 59: #import <vm/vm_kern.h> ! 60: ! 61: #import <kern/task.h> ! 62: #import <mach/time_value.h> ! 63: ! 64: /* ! 65: * Give up the processor till a wakeup occurs ! 66: * on chan, at which time the process ! 67: * enters the scheduling queue at priority pri. ! 68: * The most important effect of pri is that when ! 69: * pri<=PZERO a signal cannot disturb the sleep; ! 70: * if pri>PZERO signals will be processed. ! 71: * If pri&PCATCH is set, signals will cause sleep ! 72: * to return 1, rather than longjmp. ! 73: * Callers of this routine must be prepared for ! 74: * premature return, and check that the reason for ! 75: * sleeping has gone away. ! 76: */ ! 77: ! 78: static __inline__ ! 79: int _sleep(chan, pri, wmsg, timo) ! 80: caddr_t chan; ! 81: int pri; ! 82: char *wmsg; ! 83: int timo; ! 84: { ! 85: register struct proc *p; ! 86: register thread_t thread = current_thread(); ! 87: int sig, catch = pri & PCATCH; ! 88: int error = 0; ! 89: spl_t s; ! 90: ! 91: s = splhigh(); ! 92: ! 93: p = current_proc(); ! 94: #if KTRACE ! 95: if (KTRPOINT(p, KTR_CSW)) ! 96: ktrcsw(p->p_tracep, 1, 0); ! 97: #endif ! 98: p->p_priority = pri & PRIMASK; ! 99: ! 100: if (chan) ! 101: assert_wait(chan, (catch ? TRUE : FALSE)); ! 102: ! 103: if (timo) ! 104: thread_set_timeout(timo); ! 105: /* ! 106: * We start our timeout ! 107: * before calling CURSIG, as we could stop there, and a wakeup ! 108: * or a SIGCONT (or both) could occur while we were stopped. ! 109: * A SIGCONT would cause us to be marked as SSLEEP ! 110: * without resuming us, thus we must be ready for sleep ! 111: * when CURSIG is called. If the wakeup happens while we're ! 112: * stopped, p->p_wchan will be 0 upon return from CURSIG. ! 113: */ ! 114: ! 115: if (catch) { ! 116: unix_master(); ! 117: if (SHOULDissignal(p,thread->_uthread)) { ! 118: if (sig = CURSIG(p)) { ! 119: clear_wait(thread, THREAD_INTERRUPTED, TRUE); ! 120: if (p->p_sigacts->ps_sigintr & sigmask(sig)) ! 121: error = EINTR; ! 122: else ! 123: error = ERESTART; ! 124: unix_release(); ! 125: goto out; ! 126: } ! 127: } ! 128: if (thread_should_halt(thread)) { ! 129: clear_wait(thread, THREAD_SHOULD_TERMINATE, TRUE); ! 130: error = EINTR; ! 131: unix_release(); ! 132: goto out; ! 133: } ! 134: if (thread->wait_event == 0) { // already happened ! 135: unix_release(); ! 136: goto out; ! 137: } ! 138: unix_release(); ! 139: } ! 140: ! 141: thread->wait_mesg = wmsg; ! 142: (void) spl0(); ! 143: p->p_stats->p_ru.ru_nvcsw++; ! 144: ! 145: thread_block(); ! 146: ! 147: thread->wait_mesg = NULL; ! 148: switch (thread->wait_result) { ! 149: case THREAD_TIMED_OUT: ! 150: error = EWOULDBLOCK; ! 151: break; ! 152: case THREAD_AWAKENED: ! 153: /* ! 154: * Posix implies any signal should be delivered ! 155: * first, regardless of whether awakened due ! 156: * to receiving event. ! 157: */ ! 158: if (!catch) ! 159: break; ! 160: /* else fall through */ ! 161: case THREAD_INTERRUPTED: ! 162: case THREAD_SHOULD_TERMINATE: ! 163: if (catch) { ! 164: unix_master(); ! 165: if (thread_should_halt(thread)) { ! 166: error = EINTR; ! 167: } else if (SHOULDissignal(p,thread->_uthread)) { ! 168: if (sig = CURSIG(p)) { ! 169: if (p->p_sigacts->ps_sigintr & sigmask(sig)) ! 170: error = EINTR; ! 171: else ! 172: error = ERESTART; ! 173: } ! 174: if (thread_should_halt(thread)) { ! 175: error = EINTR; ! 176: } ! 177: } ! 178: unix_release(); ! 179: } ! 180: break; ! 181: } ! 182: out: ! 183: (void) splx(s); ! 184: return (error); ! 185: } ! 186: ! 187: int sleep(chan, pri) ! 188: void *chan; ! 189: int pri; ! 190: { ! 191: ! 192: return (_sleep((caddr_t)chan, pri, (char *)NULL, 0)); ! 193: ! 194: } ! 195: ! 196: int tsleep(chan, pri, wmsg, timo) ! 197: void *chan; ! 198: int pri; ! 199: char * wmsg; ! 200: int timo; ! 201: { ! 202: return(_sleep((caddr_t)chan, pri, wmsg, timo)); ! 203: } ! 204: ! 205: /* ! 206: * Wake up all processes sleeping on chan. ! 207: */ ! 208: void ! 209: wakeup(chan) ! 210: register void *chan; ! 211: { ! 212: int s; ! 213: ! 214: s = splhigh(); ! 215: thread_wakeup((caddr_t)chan); ! 216: splx(s); ! 217: } ! 218: ! 219: /* ! 220: * Wake up the first process sleeping on chan. ! 221: * ! 222: * Be very sure that the first process is really ! 223: * the right one to wakeup. ! 224: */ ! 225: wakeup_one(chan) ! 226: register caddr_t chan; ! 227: { ! 228: int s; ! 229: ! 230: s = splhigh(); ! 231: thread_wakeup_one(chan); ! 232: splx(s); ! 233: } ! 234: ! 235: /* ! 236: * Compute the priority of a process when running in user mode. ! 237: * Arrange to reschedule if the resulting priority is better ! 238: * than that of the current process. ! 239: */ ! 240: void ! 241: resetpriority(p) ! 242: register struct proc *p; ! 243: { ! 244: int newpri; ! 245: ! 246: if (p->p_nice < 0) ! 247: newpri = BASEPRI_USER + ! 248: (p->p_nice * (MAXPRI_USER - BASEPRI_USER)) / PRIO_MIN; ! 249: else ! 250: newpri = BASEPRI_USER - ! 251: (p->p_nice * BASEPRI_USER) / PRIO_MAX; ! 252: ! 253: (void)task_priority(p->task, newpri, TRUE); ! 254: } ! 255: ! 256: #if NCPUS > 1 ! 257: ! 258: slave_start() ! 259: { ! 260: register struct thread *th; ! 261: register int mycpu; ! 262: ! 263: /* Find a thread to execute */ ! 264: ! 265: mycpu = cpu_number(); ! 266: ! 267: splhigh(); ! 268: th = choose_thread(current_processor()); ! 269: if (th == NULL) { ! 270: printf("Slave %d failed to find any threads.\n", mycpu); ! 271: printf("Should have at least found idle thread.\n"); ! 272: halt_cpu(); ! 273: } ! 274: ! 275: /* ! 276: * Show that this cpu is using the kernel pmap ! 277: */ ! 278: PMAP_ACTIVATE(kernel_pmap, th, mycpu); ! 279: ! 280: active_threads[mycpu] = th; ! 281: ! 282: if (th->task->kernel_vm_space == FALSE) { ! 283: PMAP_ACTIVATE(vm_map_pmap(th->task->map), th, mycpu); ! 284: } ! 285: ! 286: /* ! 287: * Clock interrupt requires that this cpu have an active ! 288: * thread, hence it can't be done before this. ! 289: */ ! 290: #if NeXT ! 291: #else NeXT ! 292: startrtclock(); ! 293: #endif /* NeXT */ ! 294: ast_context(th, mycpu); ! 295: load_context(th); ! 296: /*NOTREACHED*/ ! 297: } ! 298: #endif /* NCPUS > 1 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.