Annotation of kernel/bsd/kern/kern_synch.c, revision 1.1.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.