Sync usage with man page.
[netbsd-mini2440.git] / regress / sys / kern / priority_inheritance1 / test_priority_inheritance1.c
blob6e4a8a97e226ba6bfab919800df975eec8f16b49
1 /* $NetBSD: test_priority_inheritance1.c,v 1.1 2007/02/25 09:52:47 yamt Exp $ */
3 /*-
4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: test_priority_inheritance1.c,v 1.1 2007/02/25 09:52:47 yamt Exp $");
35 #include <sys/param.h>
36 #include <sys/ioctl.h>
37 #include <sys/systm.h>
38 #include <sys/proc.h>
39 #include <sys/kthread.h>
40 #include <sys/kernel.h>
42 #define SECONDS 5
44 int testcall(struct lwp *, void *, register_t *);
45 void dummy(void *);
46 void lowprio(void *);
47 void highprio(void *);
48 void thread_exit(int, int);
49 void thread_enter(int *, int);
51 kmutex_t test_mutex;
52 kcondvar_t test_cv;
53 bool test_exit;
55 int started;
56 kcondvar_t start_cv;
57 int exited;
58 kcondvar_t exit_cv;
60 void
61 changepri(int prio)
63 struct lwp *l = curlwp;
65 lwp_lock(l);
66 lwp_changepri(l, prio);
67 lwp_unlock(l);
70 void
71 printpri(const char *msg)
73 struct lwp *l = curlwp;
75 #if 0
76 printf("%s: %s: eprio=%d l_priority=%d l_usrpri=%d\n",
77 l->l_proc->p_comm, msg, lwp_eprio(l), l->l_priority, l->l_usrpri);
78 #else
79 printf("%s: %s: l_priority=%d l_usrpri=%d\n",
80 l->l_proc->p_comm, msg, l->l_priority, l->l_usrpri);
81 #endif
84 void
85 thread_enter(int *nlocks, int prio)
87 struct lwp *l = curlwp;
89 KERNEL_UNLOCK_ALL(l, nlocks);
90 changepri(prio);
91 yield(); /* XXX */
92 printpri("enter");
95 void
96 thread_exit(int nlocks, int prio)
98 struct lwp *l = curlwp;
100 mutex_enter(&test_mutex);
101 exited++;
102 cv_signal(&exit_cv);
103 mutex_exit(&test_mutex);
105 #if 0
106 if (lwp_eprio(l) != prio)
107 #else
108 if (l->l_priority != prio || l->l_usrpri != prio)
109 #endif
110 printpri("ERROR: priority changed");
112 printpri("exit");
114 KERNEL_LOCK(nlocks, curlwp);
115 kthread_exit(0);
118 void
119 dummy(void *cookie)
121 int count, nlocks;
122 int prio = (int)cookie;
124 thread_enter(&nlocks, prio);
126 mutex_enter(&test_mutex);
127 started++;
128 cv_signal(&start_cv);
129 mutex_exit(&test_mutex);
130 while (!test_exit)
131 yield();
133 thread_exit(nlocks, prio);
136 void
137 lowprio(void *cookie)
139 struct lwp *l = curlwp;
140 int count, nlocks;
141 int prio = (int)cookie;
143 thread_enter(&nlocks, prio);
145 mutex_enter(&test_mutex);
146 started++;
147 cv_signal(&start_cv);
149 changepri(PUSER-1);
150 kpause("test", false, hz, NULL);
152 printpri("have mutex");
153 mutex_exit(&test_mutex);
154 printpri("released mutex");
156 thread_exit(nlocks, PUSER-1);
159 void
160 highprio(void *cookie)
162 int count, nlocks;
163 int prio = (int)cookie;
165 thread_enter(&nlocks, prio);
167 printf("highprio start\n");
168 mutex_enter(&test_mutex);
169 while (started < ncpu + 1)
170 cv_wait(&start_cv, &test_mutex);
171 mutex_exit(&test_mutex);
172 printf("highprio done\n");
174 test_exit = true;
176 thread_exit(nlocks, prio);
180 testcall(struct lwp *l, void *uap, register_t *retval)
182 void (*func)(void *);
183 int i;
185 mutex_init(&test_mutex, MUTEX_DEFAULT, IPL_NONE);
186 cv_init(&start_cv, "startcv");
187 cv_init(&exit_cv, "exitcv");
188 cv_init(&test_cv, "testcv");
190 printf("test: creating threads\n");
192 test_exit = false;
193 started = exited = 0;
195 changepri(PUSER-30);
197 for (i = 0; i < ncpu; i++)
198 kthread_create1(dummy, (void *)(PUSER-10), NULL, "dummy-%d", i);
199 mutex_enter(&test_mutex);
200 while (started < ncpu)
201 cv_wait(&start_cv, &test_mutex);
202 mutex_exit(&test_mutex);
204 kthread_create1(lowprio, (void *)(PUSER-20), NULL, "lowprio");
205 i++;
206 kthread_create1(highprio, (void *)(PUSER-20), NULL, "highprio");
207 i++;
209 printf("test: sleeping\n");
210 kpause("test", false, hz * SECONDS, NULL);
211 printf("test: woken\n");
213 if (!test_exit)
214 printf("test: FAIL\n");
215 test_exit = true;
216 mutex_enter(&test_mutex);
217 while (exited != i) {
218 cv_wait(&exit_cv, &test_mutex);
220 mutex_exit(&test_mutex);
222 printf("test: finished\n");
224 cv_destroy(&test_cv);
225 mutex_destroy(&test_mutex);
227 return 0;