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