Annotation of XNU/osfmk/kern/syscall_subr.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:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  */
                     52: 
                     53: #include <cpus.h>
                     54: 
                     55: #include <mach/boolean.h>
                     56: #include <mach/thread_switch.h>
                     57: #include <ipc/ipc_port.h>
                     58: #include <ipc/ipc_space.h>
                     59: #include <kern/counters.h>
                     60: #include <kern/etap_macros.h>
                     61: #include <kern/ipc_kobject.h>
                     62: #include <kern/processor.h>
                     63: #include <kern/sched.h>
                     64: #include <kern/sched_prim.h>
                     65: #include <kern/spl.h>
                     66: #include <kern/task.h>
                     67: #include <kern/thread.h>
                     68: #include <kern/ast.h>
                     69: #include <mach/policy.h>
                     70: 
                     71: #include <kern/syscall_subr.h>
                     72: #include <mach/mach_host_server.h>
                     73: #include <mach/mach_syscalls.h>
                     74: 
                     75: #include <kern/sf.h>
                     76: 
                     77: /*
                     78:  *     swtch and swtch_pri both attempt to context switch (logic in
                     79:  *     thread_block no-ops the context switch if nothing would happen).
                     80:  *     A boolean is returned that indicates whether there is anything
                     81:  *     else runnable.
                     82:  *
                     83:  *     This boolean can be used by a thread waiting on a
                     84:  *     lock or condition:  If FALSE is returned, the thread is justified
                     85:  *     in becoming a resource hog by continuing to spin because there's
                     86:  *     nothing else useful that the processor could do.  If TRUE is
                     87:  *     returned, the thread should make one more check on the
                     88:  *     lock and then be a good citizen and really suspend.
                     89:  */
                     90: 
                     91: swtch_continue()
                     92: {
                     93:     boolean_t retval;
                     94:        register processor_t myprocessor;
                     95: 
                     96:     mp_disable_preemption();
                     97:        myprocessor = current_processor();
                     98:        retval = (
                     99: #if    NCPUS > 1
                    100:               myprocessor->runq.count > 0 ||
                    101: #endif /*NCPUS > 1*/
                    102:               myprocessor->processor_set->runq.count > 0);
                    103:        mp_enable_preemption();
                    104:        return retval;
                    105: }
                    106: 
                    107: boolean_t
                    108: swtch(void)
                    109: {
                    110:        register processor_t    myprocessor;
                    111:        boolean_t                               result;
                    112: 
                    113:        mp_disable_preemption();
                    114:        myprocessor = current_processor();
                    115:        if (
                    116: #if    NCPUS > 1
                    117:                        myprocessor->runq.count == 0                                    &&
                    118: #endif /* NCPUS > 1 */
                    119:                        myprocessor->processor_set->runq.count == 0                     ) {
                    120:                mp_enable_preemption();
                    121: 
                    122:                return (FALSE);
                    123:        }
                    124:        mp_enable_preemption();
                    125: 
                    126:        counter(c_swtch_block++);
                    127: 
                    128:        thread_block(swtch_continue);
                    129: 
                    130:        mp_disable_preemption();
                    131:        myprocessor = current_processor();
                    132:        result = 
                    133: #if    NCPUS > 1
                    134:                myprocessor->runq.count > 0                                                     ||
                    135: #endif /*NCPUS > 1*/
                    136:                myprocessor->processor_set->runq.count > 0;
                    137:        mp_enable_preemption();
                    138: 
                    139:        return (result);
                    140: }
                    141: 
                    142: boolean_t
                    143: swtch_pri(
                    144:        int                             pri)
                    145: {
                    146:        thread_t                                self = current_thread();
                    147:        register processor_t    myprocessor;
                    148:        boolean_t                               result;
                    149:        sched_policy_t                  *policy;
                    150:        spl_t                                   s;
                    151: 
                    152:        s = splsched();
                    153:        thread_lock(self);
                    154:        myprocessor = current_processor();
                    155:        if (
                    156: #if    NCPUS > 1
                    157:                        myprocessor->runq.count == 0                                    &&
                    158: #endif /* NCPUS > 1 */
                    159:                        myprocessor->processor_set->runq.count == 0                     ) {
                    160:                thread_unlock(self);
                    161:                splx(s);
                    162: 
                    163:                return (FALSE);
                    164:        }
                    165: 
                    166:        policy = &sched_policy[self->policy];
                    167:        thread_unlock(self);
                    168:        splx(s);
                    169: 
                    170:        policy->sp_ops.sp_swtch_pri(policy, pri);
                    171: 
                    172:        mp_disable_preemption();
                    173:        myprocessor = current_processor();
                    174:        result = 
                    175: #if    NCPUS > 1
                    176:                myprocessor->runq.count > 0                                                     ||
                    177: #endif /*NCPUS > 1*/
                    178:                myprocessor->processor_set->runq.count > 0;
                    179:        mp_enable_preemption();
                    180: 
                    181:        return (result);
                    182: }
                    183: 
                    184: /*
                    185:  *     thread_switch:
                    186:  *
                    187:  *     Context switch.  User may supply thread hint, if not use
                    188:  *     the currect thread activation as the hint.  This is the
                    189:  *     equivilent of providing NULL, but the underlying routines
                    190:  *     can't handle that anymore.
                    191:  */
                    192: kern_return_t
                    193: thread_switch(
                    194:        mach_port_name_t                thread_name,
                    195:        int                                             option,
                    196:        mach_msg_timeout_t              option_time)
                    197: {
                    198:     register thread_t          self = current_thread();
                    199:     register thread_act_t      thr_act = self->top_act;
                    200:        sched_policy_t                  *policy;
                    201:        spl_t                                   s;
                    202: 
                    203:     if (thread_name != MACH_PORT_NULL) {
                    204:                ipc_port_t                      port;
                    205: 
                    206:                if (ipc_port_translate_send(thr_act->task->itk_space,
                    207:                                                                                thread_name, &port) == KERN_SUCCESS) {
                    208:                        /* port is locked, but it might not be active */
                    209:                        /*
                    210:                         *      If it was a valid thread activation, pass that to the
                    211:                         *  real switching routine, otherwise pass ourself (which
                    212:                         *  will result in a noop.
                    213:                         */
                    214:                        if (ip_active(port) && ip_kotype(port) == IKOT_ACT) {
                    215:                                thr_act = (thread_act_t) port->ip_kobject;
                    216:                                (void) act_lock_thread(thr_act);
                    217:                        }
                    218: 
                    219:                        ip_unlock(port);
                    220:                }
                    221:        }
                    222: 
                    223:        s = splsched();
                    224:        thread_lock(self);
                    225:        policy = &sched_policy[self->policy];
                    226:        thread_unlock(self);
                    227:        splx(s);
                    228: 
                    229:     /*
                    230:      * This is a scheduling policy-dependent operation.
                    231:      * Call the routine associated with the thread's
                    232:      * scheduling policy.
                    233:      */
                    234:     return (policy->sp_ops.
                    235:                                sp_thread_switch(policy, thr_act, option, option_time));
                    236: }

unix.superglobalmegacorp.com

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