xref: /dragonfly/sys/kern/kern_usched.c (revision d600454b)
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