Annotation of kernel/bsd/kern/kern_synch.c, revision 1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.