cpuset.h revision 232852
1176730Sjeff/*- 2176730Sjeff * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org> 3176730Sjeff * All rights reserved. 4176730Sjeff * 5177904Sjeff * Copyright (c) 2008 Nokia Corporation 6177904Sjeff * All rights reserved. 7177904Sjeff * 8176730Sjeff * Redistribution and use in source and binary forms, with or without 9176730Sjeff * modification, are permitted provided that the following conditions 10176730Sjeff * are met: 11176730Sjeff * 1. Redistributions of source code must retain the above copyright 12176730Sjeff * notice unmodified, this list of conditions, and the following 13176730Sjeff * disclaimer. 14176730Sjeff * 2. Redistributions in binary form must reproduce the above copyright 15176730Sjeff * notice, this list of conditions and the following disclaimer in the 16176730Sjeff * documentation and/or other materials provided with the distribution. 17176730Sjeff * 18176730Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19176730Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20176730Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21176730Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22176730Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23176730Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24176730Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25176730Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26176730Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27176730Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28176730Sjeff * 29176730Sjeff * $FreeBSD: head/sys/sys/cpuset.h 232852 2012-03-12 07:02:16Z mav $ 30176730Sjeff */ 31176730Sjeff 32176730Sjeff#ifndef _SYS_CPUSET_H_ 33176730Sjeff#define _SYS_CPUSET_H_ 34176730Sjeff 35222813Sattilio#include <sys/_cpuset.h> 36176730Sjeff 37222813Sattilio#define CPUSETBUFSIZ ((2 + sizeof(long) * 2) * _NCPUWORDS) 38176730Sjeff 39232852Smav/* 40232852Smav * Macros addressing word and bit within it, tuned to make compiler 41232852Smav * optimize cases when CPU_SETSIZE fits into single machine word. 42232852Smav */ 43232852Smav#define __cpuset_mask(n) \ 44232852Smav ((long)1 << ((_NCPUWORDS == 1) ? (__size_t)(n) : ((n) % _NCPUBITS))) 45232852Smav#define __cpuset_word(n) ((_NCPUWORDS == 1) ? 0 : ((n) / _NCPUBITS)) 46232852Smav 47232852Smav#define CPU_CLR(n, p) ((p)->__bits[__cpuset_word(n)] &= ~__cpuset_mask(n)) 48176730Sjeff#define CPU_COPY(f, t) (void)(*(t) = *(f)) 49232852Smav#define CPU_ISSET(n, p) (((p)->__bits[__cpuset_word(n)] & __cpuset_mask(n)) != 0) 50232852Smav#define CPU_SET(n, p) ((p)->__bits[__cpuset_word(n)] |= __cpuset_mask(n)) 51176730Sjeff#define CPU_ZERO(p) do { \ 52176730Sjeff __size_t __i; \ 53176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 54176730Sjeff (p)->__bits[__i] = 0; \ 55176730Sjeff} while (0) 56176730Sjeff 57194685Sjeff#define CPU_FILL(p) do { \ 58194685Sjeff __size_t __i; \ 59194685Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 60194685Sjeff (p)->__bits[__i] = -1; \ 61194685Sjeff} while (0) 62194685Sjeff 63222813Sattilio#define CPU_SETOF(n, p) do { \ 64222813Sattilio CPU_ZERO(p); \ 65232852Smav ((p)->__bits[__cpuset_word(n)] = __cpuset_mask(n)); \ 66222813Sattilio} while (0) 67222813Sattilio 68176811Sjeff/* Is p empty. */ 69176730Sjeff#define CPU_EMPTY(p) __extension__ ({ \ 70176730Sjeff __size_t __i; \ 71176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 72176730Sjeff if ((p)->__bits[__i]) \ 73176730Sjeff break; \ 74176730Sjeff __i == _NCPUWORDS; \ 75176730Sjeff}) 76176730Sjeff 77222813Sattilio/* Is p full set. */ 78222813Sattilio#define CPU_ISFULLSET(p) __extension__ ({ \ 79222813Sattilio __size_t __i; \ 80222813Sattilio for (__i = 0; __i < _NCPUWORDS; __i++) \ 81222813Sattilio if ((p)->__bits[__i] != (long)-1) \ 82222813Sattilio break; \ 83222813Sattilio __i == _NCPUWORDS; \ 84222813Sattilio}) 85222813Sattilio 86176811Sjeff/* Is c a subset of p. */ 87176811Sjeff#define CPU_SUBSET(p, c) __extension__ ({ \ 88176811Sjeff __size_t __i; \ 89176811Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 90176811Sjeff if (((c)->__bits[__i] & \ 91176811Sjeff (p)->__bits[__i]) != \ 92176811Sjeff (c)->__bits[__i]) \ 93176811Sjeff break; \ 94176811Sjeff __i == _NCPUWORDS; \ 95176811Sjeff}) 96176811Sjeff 97176811Sjeff/* Are there any common bits between b & c? */ 98176811Sjeff#define CPU_OVERLAP(p, c) __extension__ ({ \ 99176811Sjeff __size_t __i; \ 100176811Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 101176811Sjeff if (((c)->__bits[__i] & \ 102176811Sjeff (p)->__bits[__i]) != 0) \ 103176811Sjeff break; \ 104176811Sjeff __i != _NCPUWORDS; \ 105176811Sjeff}) 106176811Sjeff 107177738Sjeff/* Compare two sets, returns 0 if equal 1 otherwise. */ 108177738Sjeff#define CPU_CMP(p, c) __extension__ ({ \ 109177738Sjeff __size_t __i; \ 110177738Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 111177738Sjeff if (((c)->__bits[__i] != \ 112177738Sjeff (p)->__bits[__i])) \ 113177738Sjeff break; \ 114177738Sjeff __i != _NCPUWORDS; \ 115177738Sjeff}) 116177738Sjeff 117176730Sjeff#define CPU_OR(d, s) do { \ 118176730Sjeff __size_t __i; \ 119176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 120176730Sjeff (d)->__bits[__i] |= (s)->__bits[__i]; \ 121176730Sjeff} while (0) 122176730Sjeff 123176730Sjeff#define CPU_AND(d, s) do { \ 124176730Sjeff __size_t __i; \ 125176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 126176730Sjeff (d)->__bits[__i] &= (s)->__bits[__i]; \ 127176730Sjeff} while (0) 128176730Sjeff 129176730Sjeff#define CPU_NAND(d, s) do { \ 130176730Sjeff __size_t __i; \ 131176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 132176730Sjeff (d)->__bits[__i] &= ~(s)->__bits[__i]; \ 133176730Sjeff} while (0) 134176730Sjeff 135222813Sattilio#define CPU_CLR_ATOMIC(n, p) \ 136232852Smav atomic_clear_long(&(p)->__bits[__cpuset_word(n)], __cpuset_mask(n)) 137222813Sattilio 138222813Sattilio#define CPU_SET_ATOMIC(n, p) \ 139232852Smav atomic_set_long(&(p)->__bits[__cpuset_word(n)], __cpuset_mask(n)) 140222813Sattilio 141223759Sattilio/* Convenience functions catering special cases. */ 142222813Sattilio#define CPU_OR_ATOMIC(d, s) do { \ 143222813Sattilio __size_t __i; \ 144222813Sattilio for (__i = 0; __i < _NCPUWORDS; __i++) \ 145222813Sattilio atomic_set_long(&(d)->__bits[__i], \ 146222813Sattilio (s)->__bits[__i]); \ 147222813Sattilio} while (0) 148222813Sattilio 149222813Sattilio#define CPU_COPY_STORE_REL(f, t) do { \ 150222813Sattilio __size_t __i; \ 151222813Sattilio for (__i = 0; __i < _NCPUWORDS; __i++) \ 152222813Sattilio atomic_store_rel_long(&(t)->__bits[__i], \ 153222813Sattilio (f)->__bits[__i]); \ 154222813Sattilio} while (0) 155222813Sattilio 156176730Sjeff/* 157176730Sjeff * Valid cpulevel_t values. 158176730Sjeff */ 159176730Sjeff#define CPU_LEVEL_ROOT 1 /* All system cpus. */ 160176730Sjeff#define CPU_LEVEL_CPUSET 2 /* Available cpus for which. */ 161176730Sjeff#define CPU_LEVEL_WHICH 3 /* Actual mask/id for which. */ 162176730Sjeff 163176730Sjeff/* 164176730Sjeff * Valid cpuwhich_t values. 165176730Sjeff */ 166176730Sjeff#define CPU_WHICH_TID 1 /* Specifies a thread id. */ 167176730Sjeff#define CPU_WHICH_PID 2 /* Specifies a process id. */ 168176730Sjeff#define CPU_WHICH_CPUSET 3 /* Specifies a set id. */ 169178092Sjeff#define CPU_WHICH_IRQ 4 /* Specifies an irq #. */ 170185435Sbz#define CPU_WHICH_JAIL 5 /* Specifies a jail id. */ 171176730Sjeff 172176730Sjeff/* 173176730Sjeff * Reserved cpuset identifiers. 174176730Sjeff */ 175176730Sjeff#define CPUSET_INVALID -1 176176730Sjeff#define CPUSET_DEFAULT 0 177176730Sjeff 178176730Sjeff#ifdef _KERNEL 179176730SjeffLIST_HEAD(setlist, cpuset); 180176730Sjeff 181176730Sjeff/* 182176730Sjeff * cpusets encapsulate cpu binding information for one or more threads. 183176730Sjeff * 184176730Sjeff * a - Accessed with atomics. 185176730Sjeff * s - Set at creation, never modified. Only a ref required to read. 186176730Sjeff * c - Locked internally by a cpuset lock. 187176730Sjeff * 188176730Sjeff * The bitmask is only modified while holding the cpuset lock. It may be 189176730Sjeff * read while only a reference is held but the consumer must be prepared 190176730Sjeff * to deal with inconsistent results. 191176730Sjeff */ 192176730Sjeffstruct cpuset { 193176730Sjeff cpuset_t cs_mask; /* bitmask of valid cpus. */ 194176730Sjeff volatile u_int cs_ref; /* (a) Reference count. */ 195176730Sjeff int cs_flags; /* (s) Flags from below. */ 196176730Sjeff cpusetid_t cs_id; /* (s) Id or INVALID. */ 197176730Sjeff struct cpuset *cs_parent; /* (s) Pointer to our parent. */ 198176730Sjeff LIST_ENTRY(cpuset) cs_link; /* (c) All identified sets. */ 199176730Sjeff LIST_ENTRY(cpuset) cs_siblings; /* (c) Sibling set link. */ 200176730Sjeff struct setlist cs_children; /* (c) List of children. */ 201176730Sjeff}; 202176730Sjeff 203176730Sjeff#define CPU_SET_ROOT 0x0001 /* Set is a root set. */ 204176730Sjeff#define CPU_SET_RDONLY 0x0002 /* No modification allowed. */ 205176730Sjeff 206177738Sjeffextern cpuset_t *cpuset_root; 207192895Sjamiestruct prison; 208185435Sbzstruct proc; 209177738Sjeff 210176730Sjeffstruct cpuset *cpuset_thread0(void); 211176730Sjeffstruct cpuset *cpuset_ref(struct cpuset *); 212177738Sjeffvoid cpuset_rel(struct cpuset *); 213177738Sjeffint cpuset_setthread(lwpid_t id, cpuset_t *); 214192895Sjamieint cpuset_create_root(struct prison *, struct cpuset **); 215185435Sbzint cpuset_setproc_update_set(struct proc *, struct cpuset *); 216222813Sattilioint cpusetobj_ffs(const cpuset_t *); 217222813Sattiliochar *cpusetobj_strprint(char *, const cpuset_t *); 218222813Sattilioint cpusetobj_strscan(cpuset_t *, const char *); 219177738Sjeff 220176730Sjeff#else 221176730Sjeff__BEGIN_DECLS 222176730Sjeffint cpuset(cpusetid_t *); 223176730Sjeffint cpuset_setid(cpuwhich_t, id_t, cpusetid_t); 224176730Sjeffint cpuset_getid(cpulevel_t, cpuwhich_t, id_t, cpusetid_t *); 225177597Sruint cpuset_getaffinity(cpulevel_t, cpuwhich_t, id_t, size_t, cpuset_t *); 226177597Sruint cpuset_setaffinity(cpulevel_t, cpuwhich_t, id_t, size_t, const cpuset_t *); 227176730Sjeff__END_DECLS 228176730Sjeff#endif 229176730Sjeff#endif /* !_SYS_CPUSET_H_ */ 230