cpuset.h revision 223759
1/*- 2 * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org> 3 * All rights reserved. 4 * 5 * Copyright (c) 2008 Nokia Corporation 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice unmodified, this list of conditions, and the following 13 * disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $FreeBSD: head/sys/sys/cpuset.h 223759 2011-07-04 12:18:12Z attilio $ 30 */ 31 32#ifndef _SYS_CPUSET_H_ 33#define _SYS_CPUSET_H_ 34 35#include <sys/_cpuset.h> 36 37#define CPUSETBUFSIZ ((2 + sizeof(long) * 2) * _NCPUWORDS) 38 39#define __cpuset_mask(n) ((long)1 << ((n) % _NCPUBITS)) 40#define CPU_CLR(n, p) ((p)->__bits[(n)/_NCPUBITS] &= ~__cpuset_mask(n)) 41#define CPU_COPY(f, t) (void)(*(t) = *(f)) 42#define CPU_ISSET(n, p) (((p)->__bits[(n)/_NCPUBITS] & __cpuset_mask(n)) != 0) 43#define CPU_SET(n, p) ((p)->__bits[(n)/_NCPUBITS] |= __cpuset_mask(n)) 44#define CPU_ZERO(p) do { \ 45 __size_t __i; \ 46 for (__i = 0; __i < _NCPUWORDS; __i++) \ 47 (p)->__bits[__i] = 0; \ 48} while (0) 49 50#define CPU_FILL(p) do { \ 51 __size_t __i; \ 52 for (__i = 0; __i < _NCPUWORDS; __i++) \ 53 (p)->__bits[__i] = -1; \ 54} while (0) 55 56#define CPU_SETOF(n, p) do { \ 57 CPU_ZERO(p); \ 58 ((p)->__bits[(n)/_NCPUBITS] = __cpuset_mask(n)); \ 59} while (0) 60 61/* Is p empty. */ 62#define CPU_EMPTY(p) __extension__ ({ \ 63 __size_t __i; \ 64 for (__i = 0; __i < _NCPUWORDS; __i++) \ 65 if ((p)->__bits[__i]) \ 66 break; \ 67 __i == _NCPUWORDS; \ 68}) 69 70/* Is p full set. */ 71#define CPU_ISFULLSET(p) __extension__ ({ \ 72 __size_t __i; \ 73 for (__i = 0; __i < _NCPUWORDS; __i++) \ 74 if ((p)->__bits[__i] != (long)-1) \ 75 break; \ 76 __i == _NCPUWORDS; \ 77}) 78 79/* Is c a subset of p. */ 80#define CPU_SUBSET(p, c) __extension__ ({ \ 81 __size_t __i; \ 82 for (__i = 0; __i < _NCPUWORDS; __i++) \ 83 if (((c)->__bits[__i] & \ 84 (p)->__bits[__i]) != \ 85 (c)->__bits[__i]) \ 86 break; \ 87 __i == _NCPUWORDS; \ 88}) 89 90/* Are there any common bits between b & c? */ 91#define CPU_OVERLAP(p, c) __extension__ ({ \ 92 __size_t __i; \ 93 for (__i = 0; __i < _NCPUWORDS; __i++) \ 94 if (((c)->__bits[__i] & \ 95 (p)->__bits[__i]) != 0) \ 96 break; \ 97 __i != _NCPUWORDS; \ 98}) 99 100/* Compare two sets, returns 0 if equal 1 otherwise. */ 101#define CPU_CMP(p, c) __extension__ ({ \ 102 __size_t __i; \ 103 for (__i = 0; __i < _NCPUWORDS; __i++) \ 104 if (((c)->__bits[__i] != \ 105 (p)->__bits[__i])) \ 106 break; \ 107 __i != _NCPUWORDS; \ 108}) 109 110#define CPU_OR(d, s) do { \ 111 __size_t __i; \ 112 for (__i = 0; __i < _NCPUWORDS; __i++) \ 113 (d)->__bits[__i] |= (s)->__bits[__i]; \ 114} while (0) 115 116#define CPU_AND(d, s) do { \ 117 __size_t __i; \ 118 for (__i = 0; __i < _NCPUWORDS; __i++) \ 119 (d)->__bits[__i] &= (s)->__bits[__i]; \ 120} while (0) 121 122#define CPU_NAND(d, s) do { \ 123 __size_t __i; \ 124 for (__i = 0; __i < _NCPUWORDS; __i++) \ 125 (d)->__bits[__i] &= ~(s)->__bits[__i]; \ 126} while (0) 127 128#define CPU_CLR_ATOMIC(n, p) \ 129 atomic_clear_long(&(p)->__bits[(n)/_NCPUBITS], __cpuset_mask(n)) 130 131#define CPU_SET_ATOMIC(n, p) \ 132 atomic_set_long(&(p)->__bits[(n)/_NCPUBITS], __cpuset_mask(n)) 133 134/* Convenience functions catering special cases. */ 135#define CPU_OR_ATOMIC(d, s) do { \ 136 __size_t __i; \ 137 for (__i = 0; __i < _NCPUWORDS; __i++) \ 138 atomic_set_long(&(d)->__bits[__i], \ 139 (s)->__bits[__i]); \ 140} while (0) 141 142#define CPU_COPY_STORE_REL(f, t) do { \ 143 __size_t __i; \ 144 for (__i = 0; __i < _NCPUWORDS; __i++) \ 145 atomic_store_rel_long(&(t)->__bits[__i], \ 146 (f)->__bits[__i]); \ 147} while (0) 148 149/* 150 * Valid cpulevel_t values. 151 */ 152#define CPU_LEVEL_ROOT 1 /* All system cpus. */ 153#define CPU_LEVEL_CPUSET 2 /* Available cpus for which. */ 154#define CPU_LEVEL_WHICH 3 /* Actual mask/id for which. */ 155 156/* 157 * Valid cpuwhich_t values. 158 */ 159#define CPU_WHICH_TID 1 /* Specifies a thread id. */ 160#define CPU_WHICH_PID 2 /* Specifies a process id. */ 161#define CPU_WHICH_CPUSET 3 /* Specifies a set id. */ 162#define CPU_WHICH_IRQ 4 /* Specifies an irq #. */ 163#define CPU_WHICH_JAIL 5 /* Specifies a jail id. */ 164 165/* 166 * Reserved cpuset identifiers. 167 */ 168#define CPUSET_INVALID -1 169#define CPUSET_DEFAULT 0 170 171#ifdef _KERNEL 172LIST_HEAD(setlist, cpuset); 173 174/* 175 * cpusets encapsulate cpu binding information for one or more threads. 176 * 177 * a - Accessed with atomics. 178 * s - Set at creation, never modified. Only a ref required to read. 179 * c - Locked internally by a cpuset lock. 180 * 181 * The bitmask is only modified while holding the cpuset lock. It may be 182 * read while only a reference is held but the consumer must be prepared 183 * to deal with inconsistent results. 184 */ 185struct cpuset { 186 cpuset_t cs_mask; /* bitmask of valid cpus. */ 187 volatile u_int cs_ref; /* (a) Reference count. */ 188 int cs_flags; /* (s) Flags from below. */ 189 cpusetid_t cs_id; /* (s) Id or INVALID. */ 190 struct cpuset *cs_parent; /* (s) Pointer to our parent. */ 191 LIST_ENTRY(cpuset) cs_link; /* (c) All identified sets. */ 192 LIST_ENTRY(cpuset) cs_siblings; /* (c) Sibling set link. */ 193 struct setlist cs_children; /* (c) List of children. */ 194}; 195 196#define CPU_SET_ROOT 0x0001 /* Set is a root set. */ 197#define CPU_SET_RDONLY 0x0002 /* No modification allowed. */ 198 199extern cpuset_t *cpuset_root; 200struct prison; 201struct proc; 202 203struct cpuset *cpuset_thread0(void); 204struct cpuset *cpuset_ref(struct cpuset *); 205void cpuset_rel(struct cpuset *); 206int cpuset_setthread(lwpid_t id, cpuset_t *); 207int cpuset_create_root(struct prison *, struct cpuset **); 208int cpuset_setproc_update_set(struct proc *, struct cpuset *); 209int cpusetobj_ffs(const cpuset_t *); 210char *cpusetobj_strprint(char *, const cpuset_t *); 211int cpusetobj_strscan(cpuset_t *, const char *); 212 213#else 214__BEGIN_DECLS 215int cpuset(cpusetid_t *); 216int cpuset_setid(cpuwhich_t, id_t, cpusetid_t); 217int cpuset_getid(cpulevel_t, cpuwhich_t, id_t, cpusetid_t *); 218int cpuset_getaffinity(cpulevel_t, cpuwhich_t, id_t, size_t, cpuset_t *); 219int cpuset_setaffinity(cpulevel_t, cpuwhich_t, id_t, size_t, const cpuset_t *); 220__END_DECLS 221#endif 222#endif /* !_SYS_CPUSET_H_ */ 223