1*f14fb602SLionel Sambuc /* $NetBSD: cpuset.c,v 1.18 2012/03/09 15:41:16 christos Exp $ */
2b6cbf720SGianluca Guida
3b6cbf720SGianluca Guida /*-
4b6cbf720SGianluca Guida * Copyright (c) 2008 The NetBSD Foundation, Inc.
5b6cbf720SGianluca Guida * All rights reserved.
6b6cbf720SGianluca Guida *
7b6cbf720SGianluca Guida * This code is derived from software contributed to The NetBSD Foundation
8b6cbf720SGianluca Guida * by Christos Zoulas.
9b6cbf720SGianluca Guida *
10b6cbf720SGianluca Guida * Redistribution and use in source and binary forms, with or without
11b6cbf720SGianluca Guida * modification, are permitted provided that the following conditions
12b6cbf720SGianluca Guida * are met:
13b6cbf720SGianluca Guida * 1. Redistributions of source code must retain the above copyright
14b6cbf720SGianluca Guida * notice, this list of conditions and the following disclaimer.
15b6cbf720SGianluca Guida * 2. Redistributions in binary form must reproduce the above copyright
16b6cbf720SGianluca Guida * notice, this list of conditions and the following disclaimer in the
17b6cbf720SGianluca Guida * documentation and/or other materials provided with the distribution.
18b6cbf720SGianluca Guida *
19b6cbf720SGianluca Guida * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20b6cbf720SGianluca Guida * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21b6cbf720SGianluca Guida * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b6cbf720SGianluca Guida * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23b6cbf720SGianluca Guida * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24b6cbf720SGianluca Guida * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25b6cbf720SGianluca Guida * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26b6cbf720SGianluca Guida * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27b6cbf720SGianluca Guida * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28b6cbf720SGianluca Guida * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29b6cbf720SGianluca Guida * POSSIBILITY OF SUCH DAMAGE.
30b6cbf720SGianluca Guida */
31b6cbf720SGianluca Guida
32b6cbf720SGianluca Guida #ifndef _STANDALONE
33b6cbf720SGianluca Guida #include <sys/cdefs.h>
34b6cbf720SGianluca Guida #if defined(LIBC_SCCS) && !defined(lint)
35*f14fb602SLionel Sambuc __RCSID("$NetBSD: cpuset.c,v 1.18 2012/03/09 15:41:16 christos Exp $");
36b6cbf720SGianluca Guida #endif /* LIBC_SCCS and not lint */
37b6cbf720SGianluca Guida
38b6cbf720SGianluca Guida #include <sys/param.h>
39b6cbf720SGianluca Guida #include <sys/sched.h>
40b6cbf720SGianluca Guida #ifdef _KERNEL
41b6cbf720SGianluca Guida #include <sys/kmem.h>
42b6cbf720SGianluca Guida #include <lib/libkern/libkern.h>
43b6cbf720SGianluca Guida #include <sys/atomic.h>
44b6cbf720SGianluca Guida #else
45b6cbf720SGianluca Guida #include <errno.h>
46b6cbf720SGianluca Guida #include <string.h>
47b6cbf720SGianluca Guida #include <stdlib.h>
48b6cbf720SGianluca Guida #include <sys/sysctl.h>
49b6cbf720SGianluca Guida #endif
50b6cbf720SGianluca Guida
51b6cbf720SGianluca Guida #define CPUSET_SHIFT 5
52b6cbf720SGianluca Guida #define CPUSET_MASK 31
53b6cbf720SGianluca Guida #define CPUSET_NENTRIES(nc) ((nc) > 32 ? ((nc) >> CPUSET_SHIFT) : 1)
54b6cbf720SGianluca Guida #ifndef __lint__
55b6cbf720SGianluca Guida #define CPUSET_SIZE(n) (sizeof( \
56b6cbf720SGianluca Guida struct { \
57b6cbf720SGianluca Guida uint32_t bits[0]; \
58b6cbf720SGianluca Guida }) + sizeof(uint32_t) * (n))
59b6cbf720SGianluca Guida #else
60b6cbf720SGianluca Guida #define CPUSET_SIZE(n) 0
61b6cbf720SGianluca Guida #endif
62b6cbf720SGianluca Guida
63b6cbf720SGianluca Guida struct _cpuset {
64b6cbf720SGianluca Guida uint32_t bits[0];
65b6cbf720SGianluca Guida };
66b6cbf720SGianluca Guida
67*f14fb602SLionel Sambuc #ifndef _KERNEL
68b6cbf720SGianluca Guida
69b6cbf720SGianluca Guida static size_t cpuset_size = 0;
70b6cbf720SGianluca Guida static size_t cpuset_nentries = 0;
71b6cbf720SGianluca Guida
72b6cbf720SGianluca Guida size_t
73b6cbf720SGianluca Guida /*ARGSUSED*/
_cpuset_size(const cpuset_t * c)74b6cbf720SGianluca Guida _cpuset_size(const cpuset_t *c)
75b6cbf720SGianluca Guida {
76b6cbf720SGianluca Guida
77b6cbf720SGianluca Guida return cpuset_size;
78b6cbf720SGianluca Guida }
79b6cbf720SGianluca Guida
80b6cbf720SGianluca Guida void
_cpuset_zero(cpuset_t * c)81b6cbf720SGianluca Guida _cpuset_zero(cpuset_t *c)
82b6cbf720SGianluca Guida {
83b6cbf720SGianluca Guida
84b6cbf720SGianluca Guida memset(c->bits, 0, cpuset_nentries * sizeof(c->bits[0]));
85b6cbf720SGianluca Guida }
86b6cbf720SGianluca Guida
87b6cbf720SGianluca Guida int
_cpuset_isset(cpuid_t i,const cpuset_t * c)88b6cbf720SGianluca Guida _cpuset_isset(cpuid_t i, const cpuset_t *c)
89b6cbf720SGianluca Guida {
90b6cbf720SGianluca Guida const unsigned long j = i >> CPUSET_SHIFT;
91b6cbf720SGianluca Guida
92b6cbf720SGianluca Guida if (j >= cpuset_nentries) {
93b6cbf720SGianluca Guida errno = EINVAL;
94b6cbf720SGianluca Guida return -1;
95b6cbf720SGianluca Guida }
96*f14fb602SLionel Sambuc return ((1 << (unsigned int)(i & CPUSET_MASK)) & c->bits[j]) != 0;
97b6cbf720SGianluca Guida }
98b6cbf720SGianluca Guida
99b6cbf720SGianluca Guida int
_cpuset_set(cpuid_t i,cpuset_t * c)100b6cbf720SGianluca Guida _cpuset_set(cpuid_t i, cpuset_t *c)
101b6cbf720SGianluca Guida {
102b6cbf720SGianluca Guida const unsigned long j = i >> CPUSET_SHIFT;
103b6cbf720SGianluca Guida
104b6cbf720SGianluca Guida if (j >= cpuset_nentries) {
105b6cbf720SGianluca Guida errno = EINVAL;
106b6cbf720SGianluca Guida return -1;
107b6cbf720SGianluca Guida }
108*f14fb602SLionel Sambuc c->bits[j] |= 1 << (unsigned int)(i & CPUSET_MASK);
109b6cbf720SGianluca Guida return 0;
110b6cbf720SGianluca Guida }
111b6cbf720SGianluca Guida
112b6cbf720SGianluca Guida int
_cpuset_clr(cpuid_t i,cpuset_t * c)113b6cbf720SGianluca Guida _cpuset_clr(cpuid_t i, cpuset_t *c)
114b6cbf720SGianluca Guida {
115b6cbf720SGianluca Guida const unsigned long j = i >> CPUSET_SHIFT;
116b6cbf720SGianluca Guida
117b6cbf720SGianluca Guida if (j >= cpuset_nentries) {
118b6cbf720SGianluca Guida errno = EINVAL;
119b6cbf720SGianluca Guida return -1;
120b6cbf720SGianluca Guida }
121*f14fb602SLionel Sambuc c->bits[j] &= ~(1 << (unsigned int)(i & CPUSET_MASK));
122b6cbf720SGianluca Guida return 0;
123b6cbf720SGianluca Guida }
124b6cbf720SGianluca Guida
125b6cbf720SGianluca Guida cpuset_t *
_cpuset_create(void)126b6cbf720SGianluca Guida _cpuset_create(void)
127b6cbf720SGianluca Guida {
128b6cbf720SGianluca Guida
129b6cbf720SGianluca Guida if (cpuset_size == 0) {
130b6cbf720SGianluca Guida static int mib[2] = { CTL_HW, HW_NCPU };
131b6cbf720SGianluca Guida size_t len;
132b6cbf720SGianluca Guida u_int nc;
133b6cbf720SGianluca Guida
134b6cbf720SGianluca Guida len = sizeof(nc);
135*f14fb602SLionel Sambuc if (sysctl(mib, (unsigned int)__arraycount(mib), &nc, &len,
136*f14fb602SLionel Sambuc NULL, 0) == -1)
137b6cbf720SGianluca Guida return NULL;
138b6cbf720SGianluca Guida
139b6cbf720SGianluca Guida cpuset_nentries = CPUSET_NENTRIES(nc);
140b6cbf720SGianluca Guida cpuset_size = CPUSET_SIZE(cpuset_nentries);
141b6cbf720SGianluca Guida }
142b6cbf720SGianluca Guida return calloc(1, cpuset_size);
143b6cbf720SGianluca Guida }
144b6cbf720SGianluca Guida
145b6cbf720SGianluca Guida void
_cpuset_destroy(cpuset_t * c)146b6cbf720SGianluca Guida _cpuset_destroy(cpuset_t *c)
147b6cbf720SGianluca Guida {
148b6cbf720SGianluca Guida
149b6cbf720SGianluca Guida free(c);
150b6cbf720SGianluca Guida }
151b6cbf720SGianluca Guida
152b6cbf720SGianluca Guida #endif
153b6cbf720SGianluca Guida #endif
154