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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  *
  26  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 /*      Copyright (c) 1988 AT&T     */
  30 /*        All Rights Reserved   */
  31 
  32 #ifndef _SYS_CLASS_H
  33 #define _SYS_CLASS_H
  34 
  35 #include <sys/t_lock.h>
  36 #include <sys/cred.h>
  37 #include <sys/thread.h>
  38 #include <sys/priocntl.h>
  39 #include <sys/mutex.h>
  40 #include <sys/uio.h>
  41 
  42 #ifdef  __cplusplus
  43 extern "C" {
  44 #endif
  45 
  46 /*
  47  * NOTE: Developers making use of the scheduler class switch mechanism
  48  * to develop scheduling class modules should be aware that the
  49  * architecture is not frozen and the kernel interface for scheduling
  50  * class modules may change in future releases of System V.  Support
  51  * for the current interface is not guaranteed and class modules
  52  * developed to this interface may require changes in order to work
  53  * with future releases of the system.
  54  */
  55 
  56 /*
  57  * three different ops vectors are bundled together, here.
  58  * one is for each of the fundamental objects acted upon
  59  * by these operators: procs, threads, and the class manager itself.
  60  */
  61 
  62 typedef struct class_ops {
  63         int     (*cl_admin)(caddr_t, cred_t *);
  64         int     (*cl_getclinfo)(void *);
  65         int     (*cl_parmsin)(void *);
  66         int     (*cl_parmsout)(void *, pc_vaparms_t *);
  67         int     (*cl_vaparmsin)(void *, pc_vaparms_t *);
  68         int     (*cl_vaparmsout)(void *, pc_vaparms_t *);
  69         int     (*cl_getclpri)(pcpri_t *);
  70         int     (*cl_alloc)(void **, int);
  71         void    (*cl_free)(void *);
  72 } class_ops_t;
  73 
  74 typedef struct thread_ops {
  75         int     (*cl_enterclass)(kthread_t *, id_t, void *, cred_t *, void *);
  76         void    (*cl_exitclass)(void *);
  77         int     (*cl_canexit)(kthread_t *, cred_t *);
  78         int     (*cl_fork)(kthread_t *, kthread_t *, void *);
  79         void    (*cl_forkret)(kthread_t *, kthread_t *);
  80         void    (*cl_parmsget)(kthread_t *, void *);
  81         int     (*cl_parmsset)(kthread_t *, void *, id_t, cred_t *);
  82         void    (*cl_stop)(kthread_t *, int, int);
  83         void    (*cl_exit)(kthread_t *);
  84         void    (*cl_active)(kthread_t *);
  85         void    (*cl_inactive)(kthread_t *);
  86         pri_t   (*cl_swapin)(kthread_t *, int);
  87         pri_t   (*cl_swapout)(kthread_t *, int);
  88         void    (*cl_trapret)(kthread_t *);
  89         void    (*cl_preempt)(kthread_t *);
  90         void    (*cl_setrun)(kthread_t *);
  91         void    (*cl_sleep)(kthread_t *);
  92         void    (*cl_tick)(kthread_t *);
  93         void    (*cl_wakeup)(kthread_t *);
  94         int     (*cl_donice)(kthread_t *, cred_t *, int, int *);
  95         pri_t   (*cl_globpri)(kthread_t *);
  96         void    (*cl_set_process_group)(pid_t, pid_t, pid_t);
  97         void    (*cl_yield)(kthread_t *);
  98         int     (*cl_doprio)(kthread_t *, cred_t *, int, int *);
  99 } thread_ops_t;
 100 
 101 typedef struct classfuncs {
 102         class_ops_t     sclass;
 103         thread_ops_t    thread;
 104 } classfuncs_t;
 105 
 106 typedef struct sclass {
 107         char            *cl_name;       /* class name */
 108         /* class specific initialization function */
 109         pri_t           (*cl_init)(id_t, int, classfuncs_t **);
 110         classfuncs_t    *cl_funcs;      /* pointer to classfuncs structure */
 111         krwlock_t       *cl_lock;       /* class structure read/write lock */
 112         int             cl_count;       /* # of threads trying to load class */
 113 } sclass_t;
 114 
 115 #define STATIC_SCHED            (krwlock_t *)0xffffffff
 116 #define LOADABLE_SCHED(s)       ((s)->cl_lock != STATIC_SCHED)
 117 #define SCHED_INSTALLED(s)      ((s)->cl_funcs != NULL)
 118 #define ALLOCATED_SCHED(s)      ((s)->cl_lock != NULL)
 119 
 120 #if defined(_KERNEL) || defined(_FAKE_KERNEL)
 121 
 122 #define CLASS_KERNEL(cid)       ((cid) == syscid || (cid) == sysdccid)
 123 
 124 extern int      nclass;         /* number of configured scheduling classes */
 125 extern char     *defaultclass;  /* default class for newproc'd processes */
 126 extern struct sclass sclass[];  /* the class table */
 127 extern kmutex_t class_lock;     /* lock protecting class table */
 128 extern int      loaded_classes; /* number of classes loaded */
 129 
 130 extern pri_t    minclsyspri;
 131 extern id_t     syscid;         /* system scheduling class ID */
 132 extern id_t     sysdccid;       /* system duty-cycle scheduling class ID */
 133 extern id_t     defaultcid;     /* "default" class id; see dispadmin(1M) */
 134 
 135 extern int      alloc_cid(char *, id_t *);
 136 extern int      scheduler_load(char *, sclass_t *);
 137 extern int      getcid(char *, id_t *);
 138 extern int      getcidbyname(char *, id_t *);
 139 extern int      parmsin(pcparms_t *, pc_vaparms_t *);
 140 extern int      parmsout(pcparms_t *, pc_vaparms_t *);
 141 extern int      parmsset(pcparms_t *, kthread_t *);
 142 extern void     parmsget(kthread_t *, pcparms_t *);
 143 extern int      vaparmsout(char *, pcparms_t *, pc_vaparms_t *, uio_seg_t);
 144 
 145 #endif
 146 
 147 #define CL_ADMIN(clp, uaddr, reqpcredp) \
 148         (*(clp)->cl_funcs->sclass.cl_admin)(uaddr, reqpcredp)
 149 
 150 #define CL_ENTERCLASS(t, cid, clparmsp, credp, bufp) \
 151         (sclass[cid].cl_funcs->thread.cl_enterclass) (t, cid, \
 152             (void *)clparmsp, credp, bufp)
 153 
 154 #define CL_EXITCLASS(cid, clprocp)\
 155         (sclass[cid].cl_funcs->thread.cl_exitclass) ((void *)clprocp)
 156 
 157 #define CL_CANEXIT(t, cr)       (*(t)->t_clfuncs->cl_canexit)(t, cr)
 158 
 159 #define CL_FORK(tp, ct, bufp)   (*(tp)->t_clfuncs->cl_fork)(tp, ct, bufp)
 160 
 161 #define CL_FORKRET(t, ct)       (*(t)->t_clfuncs->cl_forkret)(t, ct)
 162 
 163 #define CL_GETCLINFO(clp, clinfop) \
 164         (*(clp)->cl_funcs->sclass.cl_getclinfo)((void *)clinfop)
 165 
 166 #define CL_GETCLPRI(clp, clprip) \
 167         (*(clp)->cl_funcs->sclass.cl_getclpri)(clprip)
 168 
 169 #define CL_PARMSGET(t, clparmsp) \
 170         (*(t)->t_clfuncs->cl_parmsget)(t, (void *)clparmsp)
 171 
 172 #define CL_PARMSIN(clp, clparmsp) \
 173         (clp)->cl_funcs->sclass.cl_parmsin((void *)clparmsp)
 174 
 175 #define CL_PARMSOUT(clp, clparmsp, vaparmsp) \
 176         (clp)->cl_funcs->sclass.cl_parmsout((void *)clparmsp, vaparmsp)
 177 
 178 #define CL_VAPARMSIN(clp, clparmsp, vaparmsp) \
 179         (clp)->cl_funcs->sclass.cl_vaparmsin((void *)clparmsp, vaparmsp)
 180 
 181 #define CL_VAPARMSOUT(clp, clparmsp, vaparmsp) \
 182         (clp)->cl_funcs->sclass.cl_vaparmsout((void *)clparmsp, vaparmsp)
 183 
 184 #define CL_PARMSSET(t, clparmsp, cid, curpcredp) \
 185         (*(t)->t_clfuncs->cl_parmsset)(t, (void *)clparmsp, cid, curpcredp)
 186 
 187 #define CL_PREEMPT(tp)          (*(tp)->t_clfuncs->cl_preempt)(tp)
 188 
 189 #define CL_SETRUN(tp)           (*(tp)->t_clfuncs->cl_setrun)(tp)
 190 
 191 #define CL_SLEEP(tp)            (*(tp)->t_clfuncs->cl_sleep)(tp)
 192 
 193 #define CL_STOP(t, why, what)   (*(t)->t_clfuncs->cl_stop)(t, why, what)
 194 
 195 #define CL_EXIT(t)              (*(t)->t_clfuncs->cl_exit)(t)
 196 
 197 #define CL_ACTIVE(t)            (*(t)->t_clfuncs->cl_active)(t)
 198 
 199 #define CL_INACTIVE(t)          (*(t)->t_clfuncs->cl_inactive)(t)
 200 
 201 #define CL_SWAPIN(t, flags)     (*(t)->t_clfuncs->cl_swapin)(t, flags)
 202 
 203 #define CL_SWAPOUT(t, flags)    (*(t)->t_clfuncs->cl_swapout)(t, flags)
 204 
 205 #define CL_TICK(t)              (*(t)->t_clfuncs->cl_tick)(t)
 206 
 207 #define CL_TRAPRET(t)           (*(t)->t_clfuncs->cl_trapret)(t)
 208 
 209 #define CL_WAKEUP(t)            (*(t)->t_clfuncs->cl_wakeup)(t)
 210 
 211 #define CL_DONICE(t, cr, inc, ret) \
 212         (*(t)->t_clfuncs->cl_donice)(t, cr, inc, ret)
 213 
 214 #define CL_DOPRIO(t, cr, inc, ret) \
 215         (*(t)->t_clfuncs->cl_doprio)(t, cr, inc, ret)
 216 
 217 #define CL_GLOBPRI(t)           (*(t)->t_clfuncs->cl_globpri)(t)
 218 
 219 #define CL_SET_PROCESS_GROUP(t, s, b, f) \
 220         (*(t)->t_clfuncs->cl_set_process_group)(s, b, f)
 221 
 222 #define CL_YIELD(tp)            (*(tp)->t_clfuncs->cl_yield)(tp)
 223 
 224 #define CL_ALLOC(pp, cid, flag) \
 225         (sclass[cid].cl_funcs->sclass.cl_alloc) (pp, flag)
 226 
 227 #define CL_FREE(cid, bufp)      (sclass[cid].cl_funcs->sclass.cl_free) (bufp)
 228 
 229 #ifdef  __cplusplus
 230 }
 231 #endif
 232 
 233 #endif  /* _SYS_CLASS_H */