cpuset.h revision 192895
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 192895 2009-05-27 14:11:23Z jamie $ 30176730Sjeff */ 31176730Sjeff 32176730Sjeff#ifndef _SYS_CPUSET_H_ 33176730Sjeff#define _SYS_CPUSET_H_ 34176730Sjeff 35176730Sjeff#ifdef _KERNEL 36176730Sjeff#define CPU_SETSIZE MAXCPU 37176730Sjeff#endif 38176730Sjeff 39176730Sjeff#define CPU_MAXSIZE 128 40176730Sjeff 41176730Sjeff#ifndef CPU_SETSIZE 42176730Sjeff#define CPU_SETSIZE CPU_MAXSIZE 43176730Sjeff#endif 44176730Sjeff 45176730Sjeff#define _NCPUBITS (sizeof(long) * NBBY) /* bits per mask */ 46176730Sjeff#define _NCPUWORDS howmany(CPU_SETSIZE, _NCPUBITS) 47176730Sjeff 48176730Sjefftypedef struct _cpuset { 49176730Sjeff long __bits[howmany(CPU_SETSIZE, _NCPUBITS)]; 50176730Sjeff} cpuset_t; 51176730Sjeff 52176730Sjeff#define __cpuset_mask(n) ((long)1 << ((n) % _NCPUBITS)) 53176730Sjeff#define CPU_CLR(n, p) ((p)->__bits[(n)/_NCPUBITS] &= ~__cpuset_mask(n)) 54176730Sjeff#define CPU_COPY(f, t) (void)(*(t) = *(f)) 55176730Sjeff#define CPU_ISSET(n, p) (((p)->__bits[(n)/_NCPUBITS] & __cpuset_mask(n)) != 0) 56176730Sjeff#define CPU_SET(n, p) ((p)->__bits[(n)/_NCPUBITS] |= __cpuset_mask(n)) 57176730Sjeff#define CPU_ZERO(p) do { \ 58176730Sjeff __size_t __i; \ 59176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 60176730Sjeff (p)->__bits[__i] = 0; \ 61176730Sjeff} while (0) 62176730Sjeff 63176811Sjeff/* Is p empty. */ 64176730Sjeff#define CPU_EMPTY(p) __extension__ ({ \ 65176730Sjeff __size_t __i; \ 66176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 67176730Sjeff if ((p)->__bits[__i]) \ 68176730Sjeff break; \ 69176730Sjeff __i == _NCPUWORDS; \ 70176730Sjeff}) 71176730Sjeff 72176811Sjeff/* Is c a subset of p. */ 73176811Sjeff#define CPU_SUBSET(p, c) __extension__ ({ \ 74176811Sjeff __size_t __i; \ 75176811Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 76176811Sjeff if (((c)->__bits[__i] & \ 77176811Sjeff (p)->__bits[__i]) != \ 78176811Sjeff (c)->__bits[__i]) \ 79176811Sjeff break; \ 80176811Sjeff __i == _NCPUWORDS; \ 81176811Sjeff}) 82176811Sjeff 83176811Sjeff/* Are there any common bits between b & c? */ 84176811Sjeff#define CPU_OVERLAP(p, c) __extension__ ({ \ 85176811Sjeff __size_t __i; \ 86176811Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 87176811Sjeff if (((c)->__bits[__i] & \ 88176811Sjeff (p)->__bits[__i]) != 0) \ 89176811Sjeff break; \ 90176811Sjeff __i != _NCPUWORDS; \ 91176811Sjeff}) 92176811Sjeff 93177738Sjeff/* Compare two sets, returns 0 if equal 1 otherwise. */ 94177738Sjeff#define CPU_CMP(p, c) __extension__ ({ \ 95177738Sjeff __size_t __i; \ 96177738Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 97177738Sjeff if (((c)->__bits[__i] != \ 98177738Sjeff (p)->__bits[__i])) \ 99177738Sjeff break; \ 100177738Sjeff __i != _NCPUWORDS; \ 101177738Sjeff}) 102177738Sjeff 103176730Sjeff#define CPU_OR(d, s) do { \ 104176730Sjeff __size_t __i; \ 105176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 106176730Sjeff (d)->__bits[__i] |= (s)->__bits[__i]; \ 107176730Sjeff} while (0) 108176730Sjeff 109176730Sjeff#define CPU_AND(d, s) do { \ 110176730Sjeff __size_t __i; \ 111176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 112176730Sjeff (d)->__bits[__i] &= (s)->__bits[__i]; \ 113176730Sjeff} while (0) 114176730Sjeff 115176730Sjeff#define CPU_NAND(d, s) do { \ 116176730Sjeff __size_t __i; \ 117176730Sjeff for (__i = 0; __i < _NCPUWORDS; __i++) \ 118176730Sjeff (d)->__bits[__i] &= ~(s)->__bits[__i]; \ 119176730Sjeff} while (0) 120176730Sjeff 121176730Sjeff/* 122176730Sjeff * Valid cpulevel_t values. 123176730Sjeff */ 124176730Sjeff#define CPU_LEVEL_ROOT 1 /* All system cpus. */ 125176730Sjeff#define CPU_LEVEL_CPUSET 2 /* Available cpus for which. */ 126176730Sjeff#define CPU_LEVEL_WHICH 3 /* Actual mask/id for which. */ 127176730Sjeff 128176730Sjeff/* 129176730Sjeff * Valid cpuwhich_t values. 130176730Sjeff */ 131176730Sjeff#define CPU_WHICH_TID 1 /* Specifies a thread id. */ 132176730Sjeff#define CPU_WHICH_PID 2 /* Specifies a process id. */ 133176730Sjeff#define CPU_WHICH_CPUSET 3 /* Specifies a set id. */ 134178092Sjeff#define CPU_WHICH_IRQ 4 /* Specifies an irq #. */ 135185435Sbz#define CPU_WHICH_JAIL 5 /* Specifies a jail id. */ 136176730Sjeff 137176730Sjeff/* 138176730Sjeff * Reserved cpuset identifiers. 139176730Sjeff */ 140176730Sjeff#define CPUSET_INVALID -1 141176730Sjeff#define CPUSET_DEFAULT 0 142176730Sjeff 143176730Sjeff#ifdef _KERNEL 144176730SjeffLIST_HEAD(setlist, cpuset); 145176730Sjeff 146176730Sjeff/* 147176730Sjeff * cpusets encapsulate cpu binding information for one or more threads. 148176730Sjeff * 149176730Sjeff * a - Accessed with atomics. 150176730Sjeff * s - Set at creation, never modified. Only a ref required to read. 151176730Sjeff * c - Locked internally by a cpuset lock. 152176730Sjeff * 153176730Sjeff * The bitmask is only modified while holding the cpuset lock. It may be 154176730Sjeff * read while only a reference is held but the consumer must be prepared 155176730Sjeff * to deal with inconsistent results. 156176730Sjeff */ 157176730Sjeffstruct cpuset { 158176730Sjeff cpuset_t cs_mask; /* bitmask of valid cpus. */ 159176730Sjeff volatile u_int cs_ref; /* (a) Reference count. */ 160176730Sjeff int cs_flags; /* (s) Flags from below. */ 161176730Sjeff cpusetid_t cs_id; /* (s) Id or INVALID. */ 162176730Sjeff struct cpuset *cs_parent; /* (s) Pointer to our parent. */ 163176730Sjeff LIST_ENTRY(cpuset) cs_link; /* (c) All identified sets. */ 164176730Sjeff LIST_ENTRY(cpuset) cs_siblings; /* (c) Sibling set link. */ 165176730Sjeff struct setlist cs_children; /* (c) List of children. */ 166176730Sjeff}; 167176730Sjeff 168176730Sjeff#define CPU_SET_ROOT 0x0001 /* Set is a root set. */ 169176730Sjeff#define CPU_SET_RDONLY 0x0002 /* No modification allowed. */ 170176730Sjeff 171177738Sjeffextern cpuset_t *cpuset_root; 172192895Sjamiestruct prison; 173185435Sbzstruct proc; 174177738Sjeff 175176730Sjeffstruct cpuset *cpuset_thread0(void); 176176730Sjeffstruct cpuset *cpuset_ref(struct cpuset *); 177177738Sjeffvoid cpuset_rel(struct cpuset *); 178177738Sjeffint cpuset_setthread(lwpid_t id, cpuset_t *); 179192895Sjamieint cpuset_create_root(struct prison *, struct cpuset **); 180185435Sbzint cpuset_setproc_update_set(struct proc *, struct cpuset *); 181177738Sjeff 182176730Sjeff#else 183176730Sjeff__BEGIN_DECLS 184176730Sjeffint cpuset(cpusetid_t *); 185176730Sjeffint cpuset_setid(cpuwhich_t, id_t, cpusetid_t); 186176730Sjeffint cpuset_getid(cpulevel_t, cpuwhich_t, id_t, cpusetid_t *); 187177597Sruint cpuset_getaffinity(cpulevel_t, cpuwhich_t, id_t, size_t, cpuset_t *); 188177597Sruint cpuset_setaffinity(cpulevel_t, cpuwhich_t, id_t, size_t, const cpuset_t *); 189176730Sjeff__END_DECLS 190176730Sjeff#endif 191176730Sjeff#endif /* !_SYS_CPUSET_H_ */ 192