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