1 /* 2 * Copyright (c) 2005 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Sergey Glushchenko <deen@smz.com.ua> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $DragonFly: src/sys/kern/kern_usched.c,v 1.1 2005/11/16 02:24:30 dillon Exp $ 35 */ 36 37 #include <sys/errno.h> 38 #include <sys/globaldata.h> /* curthread */ 39 #include <sys/proc.h> 40 #include <sys/sysproto.h> /* struct usched_set_args */ 41 #include <sys/systm.h> /* strcmp() */ 42 #include <sys/usched.h> 43 44 static TAILQ_HEAD(, usched) usched_list = TAILQ_HEAD_INITIALIZER(usched_list); 45 46 /* 47 * Called from very low level boot code, i386/i386/machdep.c/init386(). 48 * We cannot do anything fancy. no malloc's, no nothing other then 49 * static initialization. 50 */ 51 struct usched * 52 usched_init(void) 53 { 54 /* 55 * Add the bsd4 userland scheduler to the system. 56 */ 57 usched_ctl(&usched_bsd4, USCH_ADD); 58 return(&usched_bsd4); 59 } 60 61 /* 62 * USCHED_CTL 63 * 64 * SYNOPSIS: 65 * Add/remove usched to/from list. 66 * 67 * ARGUMENTS: 68 * usched - pointer to target scheduler 69 * action - addition or removal ? 70 * 71 * RETURN VALUES: 72 * 0 - success 73 * EINVAL - error 74 */ 75 int 76 usched_ctl(struct usched *usched, int action) 77 { 78 struct usched *item; /* temporaly for TAILQ processing */ 79 int error = 0; 80 81 switch(action) { 82 case USCH_ADD: 83 /* 84 * Make sure it isn't already on the list 85 */ 86 #ifdef INVARIANTS 87 TAILQ_FOREACH(item, &usched_list, entry) { 88 KKASSERT(item != usched); 89 } 90 #endif 91 /* 92 * Optional callback to the scheduler before we officially 93 * add it to the list. 94 */ 95 if (usched->usched_register) 96 usched->usched_register(); 97 TAILQ_INSERT_TAIL(&usched_list, usched, entry); 98 break; 99 case USCH_REM: 100 /* 101 * Do not allow the default scheduler to be removed 102 */ 103 if (strcmp(usched->name, "bsd4") == 0) { 104 error = EINVAL; 105 break; 106 } 107 TAILQ_FOREACH(item, &usched_list, entry) { 108 if (item == usched) 109 break; 110 } 111 if (item) { 112 if (item->usched_unregister) 113 item->usched_unregister(); 114 TAILQ_REMOVE(&usched_list, item, entry); 115 } else { 116 error = EINVAL; 117 } 118 break; 119 default: 120 error = EINVAL; 121 break; 122 } 123 return (error); 124 } 125 126 /* 127 * USCHED_SET(syscall) 128 * 129 * SYNOPSIS: 130 * Setting up a proc's usched. 131 * 132 * ARGUMENTS: 133 * name - usched's name 134 * 135 * RETURN VALUES: 136 * 0 - success 137 * EINVAL - error 138 */ 139 int 140 usched_set(struct usched_set_args *uap) 141 { 142 struct proc *p = curthread->td_proc; 143 struct usched *item; /* temporaly for TAILQ processing */ 144 int error; 145 146 if ((error = suser(curthread)) != 0) 147 return (error); 148 149 TAILQ_FOREACH(item, &usched_list, entry) { 150 if (strcmp(item->name, uap->name) == 0) 151 break; 152 } 153 154 /* 155 * If the scheduler for a process is being changed, disassociate 156 * the old scheduler before switching to the new one. 157 * 158 * XXX we might have to add an additional ABI call to do a 'full 159 * disassociation' and another ABI call to do a 'full reassociation' 160 */ 161 if (item && item != p->p_usched) { 162 p->p_usched->release_curproc(&p->p_lwp); 163 p->p_usched = item; 164 } else if (item == NULL) { 165 error = EINVAL; 166 } 167 return (error); 168 } 169 170