18a6472b7SPeter Dufault /* 28a6472b7SPeter Dufault * Copyright (c) 1996, 1997, 1998 38a6472b7SPeter Dufault * HD Associates, Inc. All rights reserved. 48a6472b7SPeter Dufault * 58a6472b7SPeter Dufault * Redistribution and use in source and binary forms, with or without 68a6472b7SPeter Dufault * modification, are permitted provided that the following conditions 78a6472b7SPeter Dufault * are met: 88a6472b7SPeter Dufault * 1. Redistributions of source code must retain the above copyright 98a6472b7SPeter Dufault * notice, this list of conditions and the following disclaimer. 108a6472b7SPeter Dufault * 2. Redistributions in binary form must reproduce the above copyright 118a6472b7SPeter Dufault * notice, this list of conditions and the following disclaimer in the 128a6472b7SPeter Dufault * documentation and/or other materials provided with the distribution. 138a6472b7SPeter Dufault * 3. All advertising materials mentioning features or use of this software 148a6472b7SPeter Dufault * must display the following acknowledgement: 158a6472b7SPeter Dufault * This product includes software developed by HD Associates, Inc 168a6472b7SPeter Dufault * 4. Neither the name of the author nor the names of any co-contributors 178a6472b7SPeter Dufault * may be used to endorse or promote products derived from this software 188a6472b7SPeter Dufault * without specific prior written permission. 198a6472b7SPeter Dufault * 208a6472b7SPeter Dufault * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND 218a6472b7SPeter Dufault * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 228a6472b7SPeter Dufault * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 238a6472b7SPeter Dufault * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE 248a6472b7SPeter Dufault * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 258a6472b7SPeter Dufault * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 268a6472b7SPeter Dufault * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 278a6472b7SPeter Dufault * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 288a6472b7SPeter Dufault * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 298a6472b7SPeter Dufault * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 308a6472b7SPeter Dufault * SUCH DAMAGE. 318a6472b7SPeter Dufault * 32365c5db0SPeter Wemm * $FreeBSD$ 338a6472b7SPeter Dufault */ 348a6472b7SPeter Dufault 358a6472b7SPeter Dufault /* p1003_1b: Real Time common code. 368a6472b7SPeter Dufault */ 378a6472b7SPeter Dufault 388a6472b7SPeter Dufault #include <sys/param.h> 398a6472b7SPeter Dufault #include <sys/systm.h> 408a6472b7SPeter Dufault #include <sys/kernel.h> 41fb919e4dSMark Murray #include <sys/lock.h> 428a6472b7SPeter Dufault #include <sys/module.h> 43fb919e4dSMark Murray #include <sys/mutex.h> 44fb919e4dSMark Murray #include <sys/proc.h> 458a6472b7SPeter Dufault #include <sys/sysctl.h> 46fb919e4dSMark Murray #include <sys/sysent.h> 47fb919e4dSMark Murray #include <sys/syslog.h> 48fb919e4dSMark Murray #include <sys/sysproto.h> 498a6472b7SPeter Dufault 508a6472b7SPeter Dufault #include <posix4/posix4.h> 518a6472b7SPeter Dufault 528a6472b7SPeter Dufault MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B"); 538a6472b7SPeter Dufault 542a61a110SPeter Dufault /* The system calls return ENOSYS if an entry is called that is 552a61a110SPeter Dufault * not run-time supported. I am also logging since some programs 562a61a110SPeter Dufault * start to use this when they shouldn't. That will be removed if annoying. 572a61a110SPeter Dufault */ 588a6472b7SPeter Dufault int 59b40ce416SJulian Elischer syscall_not_present(struct thread *td, const char *s, struct nosys_args *uap) 608a6472b7SPeter Dufault { 618a6472b7SPeter Dufault log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n", 62b40ce416SJulian Elischer td->td_proc->p_comm, td->td_proc->p_pid, s); 632a61a110SPeter Dufault 642a61a110SPeter Dufault /* a " return nosys(p, uap); " here causes a core dump. 652a61a110SPeter Dufault */ 662a61a110SPeter Dufault 672a61a110SPeter Dufault return ENOSYS; 688a6472b7SPeter Dufault } 698a6472b7SPeter Dufault 708a6472b7SPeter Dufault #if !defined(_KPOSIX_PRIORITY_SCHEDULING) 718a6472b7SPeter Dufault 72e9189611SPeter Wemm /* Not configured but loadable via a module: 738a6472b7SPeter Dufault */ 748a6472b7SPeter Dufault 758a6472b7SPeter Dufault static int sched_attach(void) 768a6472b7SPeter Dufault { 778a6472b7SPeter Dufault return 0; 788a6472b7SPeter Dufault } 798a6472b7SPeter Dufault 808a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setparam) 818a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getparam) 828a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setscheduler) 838a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getscheduler) 848a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_yield) 858a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_max) 868a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_min) 878a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_rr_get_interval) 888a6472b7SPeter Dufault 898a6472b7SPeter Dufault #else 908a6472b7SPeter Dufault 918a6472b7SPeter Dufault /* Configured in kernel version: 928a6472b7SPeter Dufault */ 938a6472b7SPeter Dufault static struct ksched *ksched; 948a6472b7SPeter Dufault 958a6472b7SPeter Dufault static int sched_attach(void) 968a6472b7SPeter Dufault { 978a6472b7SPeter Dufault int ret = ksched_attach(&ksched); 988a6472b7SPeter Dufault 998a6472b7SPeter Dufault if (ret == 0) 1008a6472b7SPeter Dufault p31b_setcfg(CTL_P1003_1B_PRIORITY_SCHEDULING, 1); 1018a6472b7SPeter Dufault 1028a6472b7SPeter Dufault return ret; 1038a6472b7SPeter Dufault } 1048a6472b7SPeter Dufault 1052afac34dSMatthew Dillon /* 1062afac34dSMatthew Dillon * MPSAFE 1072afac34dSMatthew Dillon */ 108b40ce416SJulian Elischer int sched_setparam(struct thread *td, 1098a6472b7SPeter Dufault struct sched_setparam_args *uap) 1108a6472b7SPeter Dufault { 111b40ce416SJulian Elischer struct thread *targettd; 1121af55356SRobert Watson struct proc *targetp; 1138a6472b7SPeter Dufault int e; 114aebde782SPeter Dufault struct sched_param sched_param; 1152afac34dSMatthew Dillon 116e8f7a952SRobert Watson e = copyin(uap->param, &sched_param, sizeof(sched_param)); 117e8f7a952SRobert Watson if (e) 118e8f7a952SRobert Watson return (e); 119aebde782SPeter Dufault 1202afac34dSMatthew Dillon mtx_lock(&Giant); 121e84b7987SRobert Watson if (uap->pid == 0) { 122b40ce416SJulian Elischer targetp = td->td_proc; 123b40ce416SJulian Elischer targettd = td; 124e84b7987SRobert Watson PROC_LOCK(targetp); 125e84b7987SRobert Watson } else { 126e84b7987SRobert Watson targetp = pfind(uap->pid); 1272afac34dSMatthew Dillon if (targetp == NULL) { 1282afac34dSMatthew Dillon e = ESRCH; 1292afac34dSMatthew Dillon goto done2; 1302afac34dSMatthew Dillon } 131b40ce416SJulian Elischer targettd = &targetp->p_thread; /* XXXKSE */ 132e84b7987SRobert Watson } 133e84b7987SRobert Watson 134b40ce416SJulian Elischer e = p_cansched(td->td_proc, targetp); 135e84b7987SRobert Watson PROC_UNLOCK(targetp); 1362afac34dSMatthew Dillon if (e == 0) { 137b40ce416SJulian Elischer e = ksched_setparam(&td->td_retval[0], ksched, targettd, 13864e55bf4SRobert Watson (const struct sched_param *)&sched_param); 1392afac34dSMatthew Dillon } 1402afac34dSMatthew Dillon done2: 1412afac34dSMatthew Dillon mtx_unlock(&Giant); 14264e55bf4SRobert Watson return (e); 1438a6472b7SPeter Dufault } 1448a6472b7SPeter Dufault 1452afac34dSMatthew Dillon /* 1462afac34dSMatthew Dillon * MPSAFE 1472afac34dSMatthew Dillon */ 148b40ce416SJulian Elischer int sched_getparam(struct thread *td, 1498a6472b7SPeter Dufault struct sched_getparam_args *uap) 1508a6472b7SPeter Dufault { 1518a6472b7SPeter Dufault int e; 152aebde782SPeter Dufault struct sched_param sched_param; 153b40ce416SJulian Elischer struct thread *targettd; 1541af55356SRobert Watson struct proc *targetp; 1558a6472b7SPeter Dufault 1562afac34dSMatthew Dillon mtx_lock(&Giant); 157e84b7987SRobert Watson if (uap->pid == 0) { 158b40ce416SJulian Elischer targetp = td->td_proc; 159b40ce416SJulian Elischer targettd = td; 160e84b7987SRobert Watson PROC_LOCK(targetp); 161e84b7987SRobert Watson } else { 162e84b7987SRobert Watson targetp = pfind(uap->pid); 1632afac34dSMatthew Dillon if (targetp == NULL) { 1642afac34dSMatthew Dillon e = ESRCH; 1652afac34dSMatthew Dillon goto done2; 1662afac34dSMatthew Dillon } 167b40ce416SJulian Elischer targettd = &targetp->p_thread; /* XXXKSE */ 168e84b7987SRobert Watson } 169e84b7987SRobert Watson 170b40ce416SJulian Elischer e = p_cansee(td->td_proc, targetp); 171e84b7987SRobert Watson PROC_UNLOCK(targetp); 17264e55bf4SRobert Watson if (e) 1732afac34dSMatthew Dillon goto done2; 174e84b7987SRobert Watson 175b40ce416SJulian Elischer e = ksched_getparam(&td->td_retval[0], ksched, targettd, &sched_param); 1762afac34dSMatthew Dillon if (e == 0) 17764e55bf4SRobert Watson e = copyout(&sched_param, uap->param, sizeof(sched_param)); 1782afac34dSMatthew Dillon done2: 1792afac34dSMatthew Dillon mtx_unlock(&Giant); 18064e55bf4SRobert Watson return (e); 1818a6472b7SPeter Dufault } 182b40ce416SJulian Elischer 1832afac34dSMatthew Dillon /* 1842afac34dSMatthew Dillon * MPSAFE 1852afac34dSMatthew Dillon */ 186b40ce416SJulian Elischer int sched_setscheduler(struct thread *td, 1878a6472b7SPeter Dufault struct sched_setscheduler_args *uap) 1888a6472b7SPeter Dufault { 1898a6472b7SPeter Dufault int e; 190aebde782SPeter Dufault struct sched_param sched_param; 191b40ce416SJulian Elischer struct thread *targettd; 1921af55356SRobert Watson struct proc *targetp; 1931af55356SRobert Watson 194e8f7a952SRobert Watson e = copyin(uap->param, &sched_param, sizeof(sched_param)); 195e8f7a952SRobert Watson if (e) 196e8f7a952SRobert Watson return (e); 197aebde782SPeter Dufault 1982afac34dSMatthew Dillon mtx_lock(&Giant); 199e84b7987SRobert Watson if (uap->pid == 0) { 200b40ce416SJulian Elischer targetp = td->td_proc; 201b40ce416SJulian Elischer targettd = td; 202e84b7987SRobert Watson PROC_LOCK(targetp); 203e84b7987SRobert Watson } else { 204e84b7987SRobert Watson targetp = pfind(uap->pid); 2052afac34dSMatthew Dillon if (targetp == NULL) { 2062afac34dSMatthew Dillon e = ESRCH; 2072afac34dSMatthew Dillon goto done2; 2082afac34dSMatthew Dillon } 209b40ce416SJulian Elischer targettd = &targetp->p_thread; /* XXXKSE */ 210e84b7987SRobert Watson } 211e84b7987SRobert Watson 212b40ce416SJulian Elischer e = p_cansched(td->td_proc, targetp); 213e84b7987SRobert Watson PROC_UNLOCK(targetp); 2142afac34dSMatthew Dillon if (e == 0) { 215b40ce416SJulian Elischer e = ksched_setscheduler(&td->td_retval[0], ksched, targettd, 216b40ce416SJulian Elischer uap->policy, (const struct sched_param *)&sched_param); 2172afac34dSMatthew Dillon } 2182afac34dSMatthew Dillon done2: 2192afac34dSMatthew Dillon mtx_unlock(&Giant); 22064e55bf4SRobert Watson return (e); 2218a6472b7SPeter Dufault } 222b40ce416SJulian Elischer 2232afac34dSMatthew Dillon /* 2242afac34dSMatthew Dillon * MPSAFE 2252afac34dSMatthew Dillon */ 226b40ce416SJulian Elischer int sched_getscheduler(struct thread *td, 2278a6472b7SPeter Dufault struct sched_getscheduler_args *uap) 2288a6472b7SPeter Dufault { 2298a6472b7SPeter Dufault int e; 230b40ce416SJulian Elischer struct thread *targettd; 2311af55356SRobert Watson struct proc *targetp; 2328a6472b7SPeter Dufault 2332afac34dSMatthew Dillon mtx_lock(&Giant); 234e84b7987SRobert Watson if (uap->pid == 0) { 235b40ce416SJulian Elischer targetp = td->td_proc; 236b40ce416SJulian Elischer targettd = td; 237e84b7987SRobert Watson PROC_LOCK(targetp); 238e84b7987SRobert Watson } else { 239e84b7987SRobert Watson targetp = pfind(uap->pid); 2402afac34dSMatthew Dillon if (targetp == NULL) { 2412afac34dSMatthew Dillon e = ESRCH; 2422afac34dSMatthew Dillon goto done2; 2432afac34dSMatthew Dillon } 244b40ce416SJulian Elischer targettd = &targetp->p_thread; /* XXXKSE */ 245e84b7987SRobert Watson } 246e84b7987SRobert Watson 247b40ce416SJulian Elischer e = p_cansee(td->td_proc, targetp); 248e84b7987SRobert Watson PROC_UNLOCK(targetp); 2492afac34dSMatthew Dillon if (e == 0) 250b40ce416SJulian Elischer e = ksched_getscheduler(&td->td_retval[0], ksched, targettd); 25164e55bf4SRobert Watson 2522afac34dSMatthew Dillon done2: 2532afac34dSMatthew Dillon mtx_unlock(&Giant); 25464e55bf4SRobert Watson return (e); 2558a6472b7SPeter Dufault } 256b40ce416SJulian Elischer 2572afac34dSMatthew Dillon /* 2582afac34dSMatthew Dillon * MPSAFE 2592afac34dSMatthew Dillon */ 260b40ce416SJulian Elischer int sched_yield(struct thread *td, 2618a6472b7SPeter Dufault struct sched_yield_args *uap) 2628a6472b7SPeter Dufault { 2632afac34dSMatthew Dillon int error; 2642afac34dSMatthew Dillon 2652afac34dSMatthew Dillon mtx_lock(&Giant); 266b40ce416SJulian Elischer error = ksched_yield(&td->td_retval[0], ksched); 2672afac34dSMatthew Dillon mtx_unlock(&Giant); 2682afac34dSMatthew Dillon return (error); 2698a6472b7SPeter Dufault } 270b40ce416SJulian Elischer 2712afac34dSMatthew Dillon /* 2722afac34dSMatthew Dillon * MPSAFE 2732afac34dSMatthew Dillon */ 274b40ce416SJulian Elischer int sched_get_priority_max(struct thread *td, 2758a6472b7SPeter Dufault struct sched_get_priority_max_args *uap) 2768a6472b7SPeter Dufault { 2772afac34dSMatthew Dillon int error; 2782afac34dSMatthew Dillon 2792afac34dSMatthew Dillon mtx_lock(&Giant); 280b40ce416SJulian Elischer error = ksched_get_priority_max(&td->td_retval[0], ksched, uap->policy); 2812afac34dSMatthew Dillon mtx_unlock(&Giant); 2822afac34dSMatthew Dillon return (error); 2838a6472b7SPeter Dufault } 284b40ce416SJulian Elischer 2852afac34dSMatthew Dillon /* 2862afac34dSMatthew Dillon * MPSAFE 2872afac34dSMatthew Dillon */ 288b40ce416SJulian Elischer int sched_get_priority_min(struct thread *td, 2898a6472b7SPeter Dufault struct sched_get_priority_min_args *uap) 2908a6472b7SPeter Dufault { 2912afac34dSMatthew Dillon int error; 292b40ce416SJulian Elischer 2932afac34dSMatthew Dillon mtx_lock(&Giant); 294b40ce416SJulian Elischer error = ksched_get_priority_min(&td->td_retval[0], ksched, uap->policy); 2952afac34dSMatthew Dillon mtx_unlock(&Giant); 2962afac34dSMatthew Dillon return (error); 2978a6472b7SPeter Dufault } 298b40ce416SJulian Elischer 2992afac34dSMatthew Dillon /* 3002afac34dSMatthew Dillon * MPSAFE 3012afac34dSMatthew Dillon */ 302b40ce416SJulian Elischer int sched_rr_get_interval(struct thread *td, 3038a6472b7SPeter Dufault struct sched_rr_get_interval_args *uap) 3048a6472b7SPeter Dufault { 3058a6472b7SPeter Dufault int e; 306b40ce416SJulian Elischer struct thread *targettd; 3071af55356SRobert Watson struct proc *targetp; 3088a6472b7SPeter Dufault 3092afac34dSMatthew Dillon mtx_lock(&Giant); 310e84b7987SRobert Watson if (uap->pid == 0) { 311b40ce416SJulian Elischer targettd = td; 312b40ce416SJulian Elischer targetp = td->td_proc; 313e84b7987SRobert Watson PROC_LOCK(targetp); 314e84b7987SRobert Watson } else { 315e84b7987SRobert Watson targetp = pfind(uap->pid); 3162afac34dSMatthew Dillon if (targetp == NULL) { 3172afac34dSMatthew Dillon e = ESRCH; 3182afac34dSMatthew Dillon goto done2; 3192afac34dSMatthew Dillon } 320b40ce416SJulian Elischer targettd = &targetp->p_thread; /* XXXKSE */ 321e84b7987SRobert Watson } 322e84b7987SRobert Watson 323b40ce416SJulian Elischer e = p_cansee(td->td_proc, targetp); 324e84b7987SRobert Watson PROC_UNLOCK(targetp); 3252afac34dSMatthew Dillon if (e == 0) { 326b40ce416SJulian Elischer e = ksched_rr_get_interval(&td->td_retval[0], ksched, targettd, 3271af55356SRobert Watson uap->interval); 3282afac34dSMatthew Dillon } 3292afac34dSMatthew Dillon done2: 3302afac34dSMatthew Dillon mtx_unlock(&Giant); 33164e55bf4SRobert Watson return (e); 3328a6472b7SPeter Dufault } 3338a6472b7SPeter Dufault 3348a6472b7SPeter Dufault #endif 3358a6472b7SPeter Dufault 3368a6472b7SPeter Dufault static void p31binit(void *notused) 3378a6472b7SPeter Dufault { 3388a6472b7SPeter Dufault (void) sched_attach(); 339ce47711dSPeter Dufault p31b_setcfg(CTL_P1003_1B_PAGESIZE, PAGE_SIZE); 3408a6472b7SPeter Dufault } 3418a6472b7SPeter Dufault 3428a6472b7SPeter Dufault SYSINIT(p31b, SI_SUB_P1003_1B, SI_ORDER_FIRST, p31binit, NULL); 343