Annotation of XNU/osfmk/kern/mach_clock.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 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:  *     File:   clock_prim.c
                     54:  *     Author: Avadis Tevanian, Jr.
                     55:  *     Date:   1986
                     56:  *
                     57:  *     Clock primitives.
                     58:  */
                     59: #include <cpus.h>
                     60: #include <stat_time.h>
                     61: #include <mach_prof.h>
                     62: #include <gprof.h>
                     63: 
                     64: #include <mach/boolean.h>
                     65: #include <mach/machine.h>
                     66: #include <mach/time_value.h>
                     67: #include <mach/vm_param.h>
                     68: #include <mach/vm_prot.h>
                     69: #include <kern/clock.h>
                     70: #include <kern/counters.h>
                     71: #include <kern/cpu_number.h>
                     72: #include <kern/host.h>
                     73: #include <kern/lock.h>
                     74: #include <kern/mach_param.h>
                     75: #include <kern/misc_protos.h>
                     76: #include <kern/processor.h>
                     77: #include <kern/profile.h>
                     78: #include <kern/sched.h>
                     79: #include <kern/sched_prim.h>
                     80: #include <kern/spl.h>
                     81: #include <kern/thread.h>
                     82: #include <kern/thread_swap.h>
                     83: #include <kern/time_out.h>
                     84: #include <vm/vm_kern.h>                                        /* kernel_map */
                     85: #include <machine/mach_param.h>                        /* HZ */
                     86: 
                     87: #include <mach/clock_server.h>
                     88: #include <mach/clock_priv_server.h>
                     89: #include <mach/mach_host_server.h>
                     90: 
                     91: #include <profiling/profile-mk.h>
                     92: 
                     93: #if    STAT_TIME
                     94: #define        TICKBUMP(t)     timer_bump(t, (1000000/HZ))
                     95: #else
                     96: #define        TICKBUMP(t)
                     97: #endif
                     98: 
                     99: boolean_t      profile_kernel_services = TRUE; /* Indicates wether or not we
                    100:                                                                                         * account kernel services 
                    101:                                                                                         * samples for user task */
                    102: 
                    103: /*
                    104:  * Hertz rate clock interrupt servicing. Primarily used to
                    105:  * update CPU statistics, recompute thread priority, and to
                    106:  * do profiling
                    107:  */
                    108: void
                    109: hertz_tick(
                    110:        boolean_t                       usermode,       /* executing user code */
                    111:        natural_t                       pc)
                    112: {
                    113:        thread_act_t            thr_act;
                    114:        register int            my_cpu;
                    115:        register thread_t       thread = current_thread();
                    116:        int                                     state;
                    117: #if            MACH_PROF
                    118: #ifdef __MACHO__
                    119: #define        ETEXT                   etext
                    120:        extern long                     etext;
                    121: #else
                    122: #define        ETEXT                   &etext
                    123:        extern char                     etext;
                    124: #endif
                    125:        boolean_t                       inkernel;
                    126: #endif /* MACH_PROF */
                    127: #if GPROF
                    128:        struct profile_vars     *pv;
                    129:        prof_uptrint_t          s;
                    130: #endif
                    131: 
                    132: #ifdef lint
                    133:        pc++;
                    134: #endif /* lint */
                    135: 
                    136:        mp_disable_preemption();
                    137:        my_cpu = cpu_number();
                    138: 
                    139:        /*
                    140:         *      The system startup sequence initializes the clock
                    141:         *      before kicking off threads.   So it's possible,
                    142:         *      especially when debugging, to wind up here with
                    143:         *      no thread to bill against.  So ignore the tick.
                    144:         */
                    145:        if (thread == THREAD_NULL) {
                    146:                mp_enable_preemption();
                    147:                return;
                    148:        }
                    149: 
                    150: #if            MACH_PROF
                    151:        inkernel = !usermode && (pc < (unsigned int)ETEXT);
                    152: #endif /* MACH_PROF */
                    153: 
                    154:        /*
                    155:         * Hertz processing performed by all processors
                    156:         * includes statistics gathering, state tracking,
                    157:         * and quantum updating.
                    158:         */
                    159:        counter(c_clock_ticks++);
                    160: 
                    161: #if     GPROF
                    162:        pv = PROFILE_VARS(my_cpu);
                    163: #endif
                    164: 
                    165:        if (usermode) {
                    166:                TICKBUMP(&thread->user_timer);
                    167: #if 0
                    168:                if (thread->priority < BASEPRI_USER)
                    169:                        state = CPU_STATE_NICE;
                    170:                else
                    171: #endif
                    172:                        state = CPU_STATE_USER;
                    173: #if GPROF
                    174:                        if (pv->active)
                    175:                            PROF_CNT_INC(pv->stats.user_ticks);
                    176: #endif
                    177:        }
                    178:        else {
                    179:                switch(processor_ptr[my_cpu]->state) {
                    180: 
                    181:                case PROCESSOR_IDLE:
                    182:                        TICKBUMP(&thread->system_timer);
                    183:                        state = CPU_STATE_IDLE;
                    184:                        break;
                    185: 
                    186:                default:
                    187:                        TICKBUMP(&thread->system_timer);
                    188:                        state = CPU_STATE_SYSTEM;
                    189:                        break;
                    190:                }
                    191: #if GPROF
                    192:                if (pv->active) {
                    193:                        if (state == CPU_STATE_SYSTEM)
                    194:                                PROF_CNT_INC(pv->stats.kernel_ticks);
                    195:                        else
                    196:                                PROF_CNT_INC(pv->stats.idle_ticks);
                    197: 
                    198:                        if ((prof_uptrint_t)pc < _profile_vars.profil_info.lowpc)
                    199:                                PROF_CNT_INC(pv->stats.too_low);
                    200:                        else {
                    201:                                s = (prof_uptrint_t)pc - _profile_vars.profil_info.lowpc;
                    202:                                if (s < pv->profil_info.text_len) {
                    203:                                        LHISTCOUNTER *ptr = (LHISTCOUNTER *) pv->profil_buf;
                    204:                                        LPROF_CNT_INC(ptr[s / HISTFRACTION]);
                    205:                                }
                    206:                                else
                    207:                                        PROF_CNT_INC(pv->stats.too_high);
                    208:                        }
                    209:                }
                    210: #endif
                    211:        }
                    212: 
                    213:        machine_slot[my_cpu].cpu_ticks[state]++;
                    214:        thread_quantum_update(my_cpu, thread, 1, state);
                    215: 
                    216:        /*
                    217:         * Hertz processing performed by the master-cpu
                    218:         * exclusively.
                    219:         */
                    220:        if (my_cpu == master_cpu) {
                    221: #ifdef MACH_BSD
                    222:                {
                    223:                        extern void     bsd_hardclock(
                    224:                                                                boolean_t       usermode,
                    225:                                                                natural_t       pc,
                    226:                                                                int                     ticks);
                    227: 
                    228:                        bsd_hardclock(usermode, pc, 1);
                    229:                }
                    230: #endif /* MACH_BSD */
                    231:        }
                    232: 
                    233: #if    MACH_PROF
                    234:        thr_act = thread->top_act;
                    235:        if (thr_act->act_profiled && thread->sched_pri != DEPRESSPRI) {
                    236:                if (inkernel && thr_act->map != kernel_map) {
                    237:                        /* 
                    238:                         * Non-kernel thread running in kernel
                    239:                         * Register user pc (mach_msg, vm_allocate ...)
                    240:                         */
                    241:                        if (profile_kernel_services)
                    242:                                profile(user_pc(thr_act), thr_act->profil_buffer);
                    243:                }
                    244:                else
                    245:                        /*
                    246:                         * User thread and user mode or
                    247:                         * user (server) thread in kernel-loaded server or
                    248:                         * kernel thread and kernel mode
                    249:                         * register interrupted pc
                    250:                         */
                    251:                        profile(pc, thr_act->profil_buffer);
                    252:        }
                    253:        if (kernel_task->task_profiled && thread->sched_pri != DEPRESSPRI) {
                    254:                if (inkernel && thr_act->map != kernel_map)
                    255:                        /*
                    256:                         * User thread not profiled in kernel mode,
                    257:                         * kernel task profiled, register kernel pc
                    258:                         * for kernel task
                    259:                         */
                    260:                        profile(pc, kernel_task->profil_buffer);
                    261:        }
                    262: #endif /* MACH_PROF */
                    263:        mp_enable_preemption();
                    264: }
                    265: 
                    266: 
                    267: /*
                    268:  * Kernel timeout services.
                    269:  */
                    270: 
                    271: /*
                    272:  *     Set a timeout.
                    273:  *
                    274:  *     fcn:            function to call
                    275:  *     param:          parameter to pass to function
                    276:  *     interval:       timeout interval, in hz.
                    277:  */
                    278: void
                    279: timeout(
                    280:        timeout_fcn_t                   fcn,
                    281:        void                                    *param,
                    282:        int                                             interval)
                    283: {
                    284:        AbsoluteTime                    deadline;
                    285: 
                    286:        clock_interval_to_deadline(interval, NSEC_PER_SEC / hz, &deadline);
                    287:        thread_call_func_delayed((thread_call_func_t)fcn, param, deadline);
                    288: }
                    289: 
                    290: /*
                    291:  * Cancel a timeout.
                    292:  */
                    293: void
                    294: untimeout(
                    295:        register timeout_fcn_t          fcn,
                    296:        register void                           *param)
                    297: {
                    298:        thread_call_func_cancel((thread_call_func_t)fcn, param, FALSE);
                    299: }

unix.superglobalmegacorp.com

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