summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/gen/sysconf.c6
-rw-r--r--lib/libpthread/pthread.h10
-rw-r--r--lib/libpthread/pthread_misc.c34
-rw-r--r--lib/librt/sched.c48
-rw-r--r--sys/kern/sys_sched.c223
-rw-r--r--sys/sys/lwp.h3
-rw-r--r--sys/sys/pset.h28
-rw-r--r--sys/sys/sched.h28
8 files changed, 240 insertions, 140 deletions
diff --git a/lib/libc/gen/sysconf.c b/lib/libc/gen/sysconf.c
index 4f8e1459a26..b9180b20a5a 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 05e07f1e4e8..4ad7360dde7 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 <time.h> /* For timespec */
#include <sched.h>
#include <sys/featuretest.h>
-#ifdef _NETBSD_SOURCE
-#include <sys/pset.h>
-#endif
#include <pthread_types.h>
@@ -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 42e77eae4a6..2c161b655f2 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 <sys/cdefs.h>
-__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 <errno.h>
#include <string.h>
@@ -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 263bebf3a3a..e2e14bdf6f7 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 <rmind at NetBSD org>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__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 <string.h>
#include <unistd.h>
@@ -37,6 +37,9 @@ __RCSID("$NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $");
#include <sys/pset.h>
#include <sys/types.h>
+/* 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 d90a51bc3da..263c4b432a6 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 <rmind at NetBSD org>
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__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 <sys/param.h>
@@ -52,6 +52,51 @@ __KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.6 2008/01/24 14:41:12 rmind Exp $");
#include <sys/unistd.h>
/*
+ * 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.
*/
int
@@ -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.
- */
- 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;
+ if (error) {
+ kmem_free(sp, sizeof(struct sched_param));
+ return error;
}
+ pri = sp->sched_priority;
+ 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 ea9bceff97f..1c367310754 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 <sys/condvar.h>
#include <sys/pset.h>
#include <sys/signalvar.h>
+#include <sys/sched.h>
#include <sys/specificdata.h>
#include <sys/syncobj.h>
diff --git a/sys/sys/pset.h b/sys/sys/pset.h
index 7f07b147187..f54349157bb 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 <rmind at NetBSD org>
@@ -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 9fff1196df5..4bd88fde069 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 *);