diff --git a/lib/libc/gen/sysconf.c b/lib/libc/gen/sysconf.c index 4f8e1459a269..b9180b20a5a5 100644 --- a/lib/libc/gen/sysconf.c +++ b/lib/libc/gen/sysconf.c @@ -1,4 +1,4 @@ -/* $NetBSD: sysconf.c,v 1.26 2008/01/15 03:37:14 rmind Exp $ */ +/* $NetBSD: sysconf.c,v 1.27 2008/01/26 17:55:30 rmind Exp $ */ /*- * Copyright (c) 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94"; #else -__RCSID("$NetBSD: sysconf.c,v 1.26 2008/01/15 03:37:14 rmind Exp $"); +__RCSID("$NetBSD: sysconf.c,v 1.27 2008/01/26 17:55:30 rmind Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -357,7 +357,7 @@ yesno: if (sysctl(mib, mib_len, &value, &len, NULL, 0) == -1) /* Native */ case _SC_SCHED_RT_TS: - if (sysctlgetmibinfo("kern.sched.rt_ts", &mib[0], &mib_len, + if (sysctlgetmibinfo("kern.sched.rtts", &mib[0], &mib_len, NULL, NULL, NULL, SYSCTL_VERSION)) return -1; break; diff --git a/lib/libpthread/pthread.h b/lib/libpthread/pthread.h index 05e07f1e4e83..4ad7360dde7e 100644 --- a/lib/libpthread/pthread.h +++ b/lib/libpthread/pthread.h @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.h,v 1.27 2008/01/19 16:05:34 christos Exp $ */ +/* $NetBSD: pthread.h,v 1.28 2008/01/26 17:55:30 rmind Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -44,9 +44,6 @@ #include /* For timespec */ #include #include -#ifdef _NETBSD_SOURCE -#include -#endif #include @@ -190,13 +187,14 @@ int pthread_barrierattr_destroy(pthread_barrierattr_t *); int pthread_getschedparam(pthread_t, int * __restrict, struct sched_param * __restrict); int pthread_setschedparam(pthread_t, int, const struct sched_param *); -int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *); -int pthread_setaffinity_np(pthread_t, size_t, cpuset_t *); int pthread_setschedprio(pthread_t, int); int *pthread__errno(void); #if defined(_NETBSD_SOURCE) +int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *); +int pthread_setaffinity_np(pthread_t, size_t, cpuset_t *); + int pthread_mutex_held_np(pthread_mutex_t *); pthread_t pthread_mutex_owner_np(pthread_mutex_t *); diff --git a/lib/libpthread/pthread_misc.c b/lib/libpthread/pthread_misc.c index 42e77eae4a61..2c161b655f21 100644 --- a/lib/libpthread/pthread_misc.c +++ b/lib/libpthread/pthread_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_misc.c,v 1.4 2008/01/15 03:37:14 rmind Exp $ */ +/* $NetBSD: pthread_misc.c,v 1.5 2008/01/26 17:55:30 rmind Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__RCSID("$NetBSD: pthread_misc.c,v 1.4 2008/01/15 03:37:14 rmind Exp $"); +__RCSID("$NetBSD: pthread_misc.c,v 1.5 2008/01/26 17:55:30 rmind Exp $"); #include #include @@ -68,15 +68,15 @@ __strong_alias(__libc_thr_yield,pthread__sched_yield) int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param) { - int error; if (pthread__find(thread) != 0) return ESRCH; - error = _sched_getparam(getpid(), thread->pt_lid, param); - if (error == 0) - *policy = param->sched_class; - return error; + if (_sched_getparam(getpid(), thread->pt_lid, param) < 0) + return errno; + + *policy = param->sched_class; + return 0; } int @@ -90,7 +90,10 @@ pthread_setschedparam(pthread_t thread, int policy, memcpy(&sp, param, sizeof(struct sched_param)); sp.sched_class = policy; - return _sched_setparam(getpid(), thread->pt_lid, &sp); + if (_sched_setparam(getpid(), thread->pt_lid, &sp) < 0) + return errno; + + return 0; } int @@ -100,7 +103,10 @@ pthread_getaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset) if (pthread__find(thread) != 0) return ESRCH; - return _sched_getaffinity(getpid(), thread->pt_lid, size, cpuset); + if (_sched_getaffinity(getpid(), thread->pt_lid, size, cpuset) < 0) + return errno; + + return 0; } int @@ -110,7 +116,10 @@ pthread_setaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset) if (pthread__find(thread) != 0) return ESRCH; - return _sched_setaffinity(getpid(), thread->pt_lid, size, cpuset); + if (_sched_setaffinity(getpid(), thread->pt_lid, size, cpuset) < 0) + return errno; + + return 0; } int @@ -123,7 +132,10 @@ pthread_setschedprio(pthread_t thread, int prio) sp.sched_class = SCHED_NONE; sp.sched_priority = prio; - return _sched_setparam(getpid(), thread->pt_lid, &sp); + if (_sched_setparam(getpid(), thread->pt_lid, &sp) < 0) + return errno; + + return 0; } int diff --git a/lib/librt/sched.c b/lib/librt/sched.c index 263bebf3a3a4..e2e14bdf6f79 100644 --- a/lib/librt/sched.c +++ b/lib/librt/sched.c @@ -1,4 +1,4 @@ -/* $NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $ */ +/* $NetBSD: sched.c,v 1.2 2008/01/26 17:55:30 rmind Exp $ */ /* * Copyright (c) 2008, Mindaugas Rasiukevicius @@ -27,7 +27,7 @@ */ #include -__RCSID("$NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $"); +__RCSID("$NetBSD: sched.c,v 1.2 2008/01/26 17:55:30 rmind Exp $"); #include #include @@ -37,6 +37,9 @@ __RCSID("$NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $"); #include #include +/* All LWPs in the process */ +#define P_ALL_LWPS 0 + /* * Scheduling parameters. */ @@ -44,36 +47,51 @@ __RCSID("$NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $"); int sched_setparam(pid_t pid, const struct sched_param *param) { + struct sched_param sp; - return _sched_setparam(pid, 0, param); + memset(&sp, 0, sizeof(struct sched_param)); + sp.sched_priority = param->sched_priority; + sp.sched_class = SCHED_NONE; + return _sched_setparam(pid, P_ALL_LWPS, &sp); } int sched_getparam(pid_t pid, struct sched_param *param) { - return _sched_getparam(pid, 0, param); + return _sched_getparam(pid, P_ALL_LWPS, param); } int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param) { struct sched_param sp; + int ret, old_policy; - memcpy(&sp, param, sizeof(struct sched_param)); + ret = _sched_getparam(pid, P_ALL_LWPS, &sp); + if (ret < 0) + return ret; + old_policy = sp.sched_class; + + memset(&sp, 0, sizeof(struct sched_param)); + sp.sched_priority = param->sched_priority; sp.sched_class = policy; - return _sched_setparam(pid, 0, &sp); + ret = _sched_setparam(pid, P_ALL_LWPS, &sp); + if (ret < 0) + return ret; + + return old_policy; } int sched_getscheduler(pid_t pid) { struct sched_param sp; - int error; + int ret; - error = _sched_getparam(pid, 0, &sp); - if (error) - return error; + ret = _sched_getparam(pid, P_ALL_LWPS, &sp); + if (ret < 0) + return ret; return sp.sched_class; } @@ -86,6 +104,10 @@ int sched_get_priority_max(int policy) { + if (policy < SCHED_OTHER || policy > SCHED_RR) { + errno = EINVAL; + return -1; + } return sysconf(_SC_SCHED_PRI_MAX); } @@ -93,6 +115,10 @@ int sched_get_priority_min(int policy) { + if (policy < SCHED_OTHER || policy > SCHED_RR) { + errno = EINVAL; + return -1; + } return sysconf(_SC_SCHED_PRI_MIN); } @@ -113,5 +139,5 @@ int pset_bind(psetid_t psid, idtype_t idtype, id_t id, psetid_t *opsid) { - return _pset_bind(idtype, id, 0, psid, opsid); + return _pset_bind(idtype, id, P_ALL_LWPS, psid, opsid); } diff --git a/sys/kern/sys_sched.c b/sys/kern/sys_sched.c index d90a51bc3dab..263c4b432a65 100644 --- a/sys/kern/sys_sched.c +++ b/sys/kern/sys_sched.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_sched.c,v 1.6 2008/01/24 14:41:12 rmind Exp $ */ +/* $NetBSD: sys_sched.c,v 1.7 2008/01/26 17:55:29 rmind Exp $ */ /* * Copyright (c) 2008, Mindaugas Rasiukevicius @@ -33,7 +33,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.6 2008/01/24 14:41:12 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.7 2008/01/26 17:55:29 rmind Exp $"); #include @@ -51,6 +51,51 @@ __KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.6 2008/01/24 14:41:12 rmind Exp $"); #include #include +/* + * Convert user priority or the in-kernel priority or convert the current + * priority to the appropriate range according to the policy change. + */ +static pri_t +convert_pri(lwp_t *l, int policy, pri_t pri) +{ + int delta = 0; + + if (policy == SCHED_NONE) + policy = l->l_class; + + switch (policy) { + case SCHED_OTHER: + delta = PRI_USER; + break; + case SCHED_FIFO: + case SCHED_RR: + delta = PRI_USER_RT; + break; + default: + panic("upri_to_kpri"); + } + + if (pri != PRI_NONE) { + /* Convert user priority to the in-kernel */ + KASSERT(pri >= SCHED_PRI_MIN && pri <= SCHED_PRI_MAX); + return pri + delta; + } + if (l->l_class == policy) + return l->l_priority; + + /* Change the current priority to the appropriate range */ + if (l->l_class == SCHED_OTHER) { + KASSERT(policy == SCHED_FIFO || policy == SCHED_RR); + return l->l_priority + delta; + } + if (policy == SCHED_OTHER) { + KASSERT(l->l_class == SCHED_FIFO || l->l_class == SCHED_RR); + return l->l_priority - delta; + } + KASSERT(l->l_class != SCHED_OTHER && policy != SCHED_OTHER); + return l->l_class; +} + /* * Set scheduling parameters. */ @@ -66,103 +111,87 @@ sys__sched_setparam(struct lwp *l, const struct sys__sched_setparam_args *uap, struct sched_param *sp; struct proc *p; struct lwp *t; - pid_t pid; lwpid_t lid; u_int lcnt; + int policy; pri_t pri; int error; /* Available only for super-user */ if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) - return EACCES; + return EPERM; /* Get the parameters from the user-space */ sp = kmem_zalloc(sizeof(struct sched_param), KM_SLEEP); error = copyin(SCARG(uap, params), sp, sizeof(struct sched_param)); - if (error) - goto error; - - /* - * Validate scheduling class and priority. - * Convert the user priority to the in-kernel value. - */ + if (error) { + kmem_free(sp, sizeof(struct sched_param)); + return error; + } pri = sp->sched_priority; - if (pri != PRI_NONE && (pri < SCHED_PRI_MIN || pri > SCHED_PRI_MAX)) { - error = EINVAL; - goto error; - } - switch (sp->sched_class) { - case SCHED_OTHER: - if (pri == PRI_NONE) - pri = PRI_USER; - else - pri += PRI_USER; - break; - case SCHED_RR: - case SCHED_FIFO: - if (pri == PRI_NONE) - pri = PRI_USER_RT; - else - pri += PRI_USER_RT; - break; - case SCHED_NONE: - break; - default: - error = EINVAL; - goto error; - } + policy = sp->sched_class; + kmem_free(sp, sizeof(struct sched_param)); - /* Find the process */ - pid = SCARG(uap, pid); - p = p_find(pid, PFIND_UNLOCK_FAIL); - if (p == NULL) { - error = ESRCH; - goto error; - } - mutex_enter(&p->p_smutex); - mutex_exit(&proclist_lock); + /* If no parameters specified, just return (this should not happen) */ + if (pri == PRI_NONE && policy == SCHED_NONE) + return 0; - /* Disallow modification of system processes */ - if (p->p_flag & PK_SYSTEM) { - mutex_exit(&p->p_smutex); - error = EACCES; - goto error; + /* Validate scheduling class */ + if (policy != SCHED_NONE && (policy < SCHED_OTHER || policy > SCHED_RR)) + return EINVAL; + + /* Validate priority */ + if (pri != PRI_NONE && (pri < SCHED_PRI_MIN || pri > SCHED_PRI_MAX)) + return EINVAL; + + if (SCARG(uap, pid) != 0) { + /* Find the process */ + p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL); + if (p == NULL) + return ESRCH; + mutex_enter(&p->p_smutex); + mutex_exit(&proclist_lock); + /* Disallow modification of system processes */ + if (p->p_flag & PK_SYSTEM) { + mutex_exit(&p->p_smutex); + return EPERM; + } + } else { + /* Use the calling process */ + p = l->l_proc; + mutex_enter(&p->p_smutex); } /* Find the LWP(s) */ lcnt = 0; lid = SCARG(uap, lid); LIST_FOREACH(t, &p->p_lwps, l_sibling) { - bool chpri; + pri_t kpri; if (lid && lid != t->l_lid) continue; + KASSERT(pri != PRI_NONE || policy != SCHED_NONE); + lwp_lock(t); + + /* + * Note that, priority may need to be changed to get into + * the correct priority range of the new scheduling class. + */ + kpri = convert_pri(t, policy, pri); /* Set the scheduling class */ - lwp_lock(t); - if (sp->sched_class != SCHED_NONE) { - /* - * Priority must be changed to get into the correct - * priority range of the new scheduling class. - */ - chpri = (t->l_class != sp->sched_class); - t->l_class = sp->sched_class; - } else - chpri = false; + if (policy != SCHED_NONE) + t->l_class = policy; /* Change the priority */ - if (sp->sched_priority != PRI_NONE || chpri) - lwp_changepri(t, pri); + if (t->l_priority != kpri) + lwp_changepri(t, kpri); lwp_unlock(t); lcnt++; } mutex_exit(&p->p_smutex); - if (lcnt == 0) - error = ESRCH; -error: - kmem_free(sp, sizeof(struct sched_param)); - return error; + return (lcnt == 0) ? ESRCH : error; } /* @@ -179,12 +208,26 @@ sys__sched_getparam(struct lwp *l, const struct sys__sched_getparam_args *uap, } */ struct sched_param *sp; struct lwp *t; + lwpid_t lid; int error; sp = kmem_zalloc(sizeof(struct sched_param), KM_SLEEP); - /* Locks the LWP */ - t = lwp_find2(SCARG(uap, pid), SCARG(uap, lid)); + /* If not specified, use the first LWP */ + lid = SCARG(uap, lid) == 0 ? 1 : SCARG(uap, lid); + + if (SCARG(uap, pid) != 0) { + /* Locks the LWP */ + t = lwp_find2(SCARG(uap, pid), lid); + } else { + struct proc *p = l->l_proc; + /* Use the calling process */ + mutex_enter(&p->p_smutex); + t = lwp_find(p, lid); + if (t != NULL) + lwp_lock(t); + mutex_exit(&p->p_smutex); + } if (t == NULL) { kmem_free(sp, sizeof(struct sched_param)); return ESRCH; @@ -231,7 +274,7 @@ sys__sched_setaffinity(struct lwp *l, /* Available only for super-user */ if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) - return EACCES; + return EPERM; if (SCARG(uap, size) <= 0) return EINVAL; @@ -253,19 +296,25 @@ sys__sched_setaffinity(struct lwp *l, cpuset = NULL; } - /* Find the process */ - p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL); - if (p == NULL) { - error = ESRCH; - goto error; + if (SCARG(uap, pid) != 0) { + /* Find the process */ + p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL); + if (p == NULL) { + error = ESRCH; + goto error; + } + mutex_enter(&p->p_smutex); + mutex_exit(&proclist_lock); + } else { + /* Use the calling process */ + p = l->l_proc; + mutex_enter(&p->p_smutex); } - mutex_enter(&p->p_smutex); - mutex_exit(&proclist_lock); /* Disallow modification of system processes */ if (p->p_flag & PK_SYSTEM) { mutex_exit(&p->p_smutex); - error = EACCES; + error = EPERM; goto error; } @@ -313,6 +362,7 @@ sys__sched_getaffinity(struct lwp *l, } */ struct lwp *t; void *cpuset; + lwpid_t lid; int error; if (SCARG(uap, size) <= 0) @@ -320,8 +370,21 @@ sys__sched_getaffinity(struct lwp *l, cpuset = kmem_zalloc(sizeof(cpuset_t), KM_SLEEP); - /* Locks the LWP */ - t = lwp_find2(SCARG(uap, pid), SCARG(uap, lid)); + /* If not specified, use the first LWP */ + lid = SCARG(uap, lid) == 0 ? 1 : SCARG(uap, lid); + + if (SCARG(uap, pid) != 0) { + /* Locks the LWP */ + t = lwp_find2(SCARG(uap, pid), lid); + } else { + struct proc *p = l->l_proc; + /* Use the calling process */ + mutex_enter(&p->p_smutex); + t = lwp_find(p, lid); + if (t != NULL) + lwp_lock(t); + mutex_exit(&p->p_smutex); + } if (t == NULL) { kmem_free(cpuset, sizeof(cpuset_t)); return ESRCH; diff --git a/sys/sys/lwp.h b/sys/sys/lwp.h index ea9bceff97f9..1c3673107545 100644 --- a/sys/sys/lwp.h +++ b/sys/sys/lwp.h @@ -1,4 +1,4 @@ -/* $NetBSD: lwp.h,v 1.77 2008/01/15 03:37:12 rmind Exp $ */ +/* $NetBSD: lwp.h,v 1.78 2008/01/26 17:55:29 rmind Exp $ */ /*- * Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc. @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/sys/sys/pset.h b/sys/sys/pset.h index 7f07b1471879..f54349157bb1 100644 --- a/sys/sys/pset.h +++ b/sys/sys/pset.h @@ -1,4 +1,4 @@ -/* $NetBSD: pset.h,v 1.1 2008/01/15 03:41:50 rmind Exp $ */ +/* $NetBSD: pset.h,v 1.2 2008/01/26 17:55:29 rmind Exp $ */ /* * Copyright (c) 2008, Mindaugas Rasiukevicius @@ -52,32 +52,6 @@ int pset_create(psetid_t *); int pset_destroy(psetid_t); __END_DECLS -/* Size of the CPU set bitmap */ -#define CPUSET_SHIFT 5 -#define CPUSET_MASK 31 -#if MAXCPUS > 32 -#define CPUSET_SIZE (MAXCPUS >> CPUSET_SHIFT) -#else -#define CPUSET_SIZE 1 -#endif - -/* Bitmap of the CPUs */ -typedef struct { - uint32_t bits[CPUSET_SIZE]; -} cpuset_t; - -#define CPU_ZERO(c) \ - (memset(c, 0, sizeof(cpuset_t))) - -#define CPU_ISSET(i, c) \ - ((1 << (i & CPUSET_MASK)) & (c)->bits[i >> CPUSET_SHIFT]) - -#define CPU_SET(i, c) \ - ((c)->bits[i >> CPUSET_SHIFT] |= 1 << (i & CPUSET_MASK)) - -#define CPU_CLR(i, c) \ - ((c)->bits[i >> CPUSET_SHIFT] &= ~(1 << (i & CPUSET_MASK))) - #ifdef _NETBSD_SOURCE int _pset_bind(idtype_t, id_t, id_t, psetid_t, psetid_t *); #endif /* _NETBSD_SOURCE */ diff --git a/sys/sys/sched.h b/sys/sys/sched.h index 9fff1196df53..4bd88fde0695 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $NetBSD: sched.h,v 1.45 2008/01/15 03:37:12 rmind Exp $ */ +/* $NetBSD: sched.h,v 1.46 2008/01/26 17:55:29 rmind Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2007 The NetBSD Foundation, Inc. @@ -101,6 +101,32 @@ struct sched_param { #if defined(_NETBSD_SOURCE) +/* XXX: Size of the CPU set bitmap */ +#define CPUSET_SHIFT 5 +#define CPUSET_MASK 31 +#if MAXCPUS > 32 +#define CPUSET_SIZE (MAXCPUS >> CPUSET_SHIFT) +#else +#define CPUSET_SIZE 1 +#endif + +/* Bitmap of the CPUs */ +typedef struct { + uint32_t bits[CPUSET_SIZE]; +} cpuset_t; + +#define CPU_ZERO(c) \ + (memset(c, 0, sizeof(cpuset_t))) + +#define CPU_ISSET(i, c) \ + ((1 << (i & CPUSET_MASK)) & (c)->bits[i >> CPUSET_SHIFT]) + +#define CPU_SET(i, c) \ + ((c)->bits[i >> CPUSET_SHIFT] |= 1 << (i & CPUSET_MASK)) + +#define CPU_CLR(i, c) \ + ((c)->bits[i >> CPUSET_SHIFT] &= ~(1 << (i & CPUSET_MASK))) + int _sched_getaffinity(pid_t, lwpid_t, size_t, void *); int _sched_setaffinity(pid_t, lwpid_t, size_t, void *); int _sched_getparam(pid_t, lwpid_t, struct sched_param *);