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

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

unix.superglobalmegacorp.com

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