1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 30 #ifndef _SYS_DISP_H 31 #define _SYS_DISP_H 32 33 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.11 */ 34 35 #include <sys/priocntl.h> 36 #include <sys/thread.h> 37 #include <sys/class.h> 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /* 44 * The following is the format of a dispatcher queue entry. 45 */ 46 typedef struct dispq { 47 kthread_t *dq_first; /* first thread on queue or NULL */ 48 kthread_t *dq_last; /* last thread on queue or NULL */ 49 int dq_sruncnt; /* number of loaded, runnable */ 50 /* threads on queue */ 51 } dispq_t; 52 53 /* 54 * Dispatch queue structure. 55 */ 56 typedef struct _disp { 57 disp_lock_t disp_lock; /* protects dispatching fields */ 58 pri_t disp_npri; /* # of priority levels in queue */ 59 dispq_t *disp_q; /* the dispatch queue */ 60 dispq_t *disp_q_limit; /* ptr past end of dispatch queue */ 61 ulong_t *disp_qactmap; /* bitmap of active dispatch queues */ 62 63 /* 64 * Priorities: 65 * disp_maxrunpri is the maximum run priority of runnable threads 66 * on this queue. It is -1 if nothing is runnable. 67 * 68 * disp_max_unbound_pri is the maximum run priority of threads on 69 * this dispatch queue but runnable by any CPU. This may be left 70 * artificially high, then corrected when some CPU tries to take 71 * an unbound thread. It is -1 if nothing is runnable. 72 */ 73 pri_t disp_maxrunpri; /* maximum run priority */ 74 pri_t disp_max_unbound_pri; /* max pri of unbound threads */ 75 76 volatile int disp_nrunnable; /* runnable threads in cpu dispq */ 77 78 struct cpu *disp_cpu; /* cpu owning this queue or NULL */ 79 hrtime_t disp_steal; /* time when threads become stealable */ 80 } disp_t; 81 82 #if defined(_KERNEL) 83 84 #define MAXCLSYSPRI 99 85 #define MINCLSYSPRI 60 86 87 88 /* 89 * Global scheduling variables. 90 * - See sys/cpuvar.h for CPU-local variables. 91 */ 92 extern int nswapped; /* number of swapped threads */ 93 /* nswapped protected by swap_lock */ 94 95 extern pri_t minclsyspri; /* minimum level of any system class */ 96 extern pri_t maxclsyspri; /* maximum level of any system class */ 97 extern pri_t intr_pri; /* interrupt thread priority base level */ 98 99 /* 100 * Minimum amount of time that a thread can remain runnable before it can 101 * be stolen by another CPU (in nanoseconds). 102 */ 103 extern hrtime_t nosteal_nsec; 104 105 /* 106 * Kernel preemption occurs if a higher-priority thread is runnable with 107 * a priority at or above kpreemptpri. 108 * 109 * So that other processors can watch for such threads, a separate 110 * dispatch queue with unbound work above kpreemptpri is maintained. 111 * This is part of the CPU partition structure (cpupart_t). 112 */ 113 extern pri_t kpreemptpri; /* level above which preemption takes place */ 114 115 extern void disp_kp_alloc(disp_t *, pri_t); /* allocate kp queue */ 116 extern void disp_kp_free(disp_t *); /* free kp queue */ 117 118 /* 119 * Macro for use by scheduling classes to decide whether the thread is about 120 * to be scheduled or not. This returns the maximum run priority. 121 */ 122 #define DISP_MAXRUNPRI(t) ((t)->t_disp_queue->disp_maxrunpri) 123 124 /* 125 * Platform callbacks for various dispatcher operations 126 * 127 * idle_cpu() is invoked when a cpu goes idle, and has nothing to do. 128 * disp_enq_thread() is invoked when a thread is placed on a run queue. 129 */ 130 extern void (*idle_cpu)(); 131 extern void (*disp_enq_thread)(struct cpu *, int); 132 133 134 extern int dispdeq(kthread_t *); 135 extern void dispinit(void); 136 extern void disp_add(sclass_t *); 137 extern int intr_active(struct cpu *, int); 138 extern int servicing_interrupt(void); 139 extern void preempt(void); 140 extern void setbackdq(kthread_t *); 141 extern void setfrontdq(kthread_t *); 142 extern void swtch(void); 143 extern void swtch_to(kthread_t *); 144 extern void swtch_from_zombie(void) 145 __NORETURN; 146 extern void dq_sruninc(kthread_t *); 147 extern void dq_srundec(kthread_t *); 148 extern void cpu_rechoose(kthread_t *); 149 extern void cpu_surrender(kthread_t *); 150 extern void kpreempt(int); 151 extern struct cpu *disp_lowpri_cpu(struct cpu *, struct lgrp_ld *, pri_t, 152 struct cpu *); 153 extern int disp_bound_threads(struct cpu *, int); 154 extern int disp_bound_anythreads(struct cpu *, int); 155 extern int disp_bound_partition(struct cpu *, int); 156 extern void disp_cpu_init(struct cpu *); 157 extern void disp_cpu_fini(struct cpu *); 158 extern void disp_cpu_inactive(struct cpu *); 159 extern void disp_adjust_unbound_pri(kthread_t *); 160 extern void resume(kthread_t *); 161 extern void resume_from_intr(kthread_t *); 162 extern void resume_from_zombie(kthread_t *) 163 __NORETURN; 164 extern void disp_swapped_enq(kthread_t *); 165 extern int disp_anywork(void); 166 167 #define KPREEMPT_SYNC (-1) 168 #define kpreempt_disable() \ 169 { \ 170 curthread->t_preempt++; \ 171 ASSERT(curthread->t_preempt >= 1); \ 172 } 173 #define kpreempt_enable() \ 174 { \ 175 ASSERT(curthread->t_preempt >= 1); \ 176 if (--curthread->t_preempt == 0 && \ 177 CPU->cpu_kprunrun) \ 178 kpreempt(KPREEMPT_SYNC); \ 179 } 180 181 #endif /* _KERNEL */ 182 183 #ifdef __cplusplus 184 } 185 #endif 186 187 #endif /* _SYS_DISP_H */ 188