cpuset.h revision 176730
1176730Sjeff/*-
2176730Sjeff * Copyright (c) 2008,	Jeffrey Roberson <jeff@freebsd.org>
3176730Sjeff * All rights reserved.
4176730Sjeff *
5176730Sjeff * Redistribution and use in source and binary forms, with or without
6176730Sjeff * modification, are permitted provided that the following conditions
7176730Sjeff * are met:
8176730Sjeff * 1. Redistributions of source code must retain the above copyright
9176730Sjeff *    notice unmodified, this list of conditions, and the following
10176730Sjeff *    disclaimer.
11176730Sjeff * 2. Redistributions in binary form must reproduce the above copyright
12176730Sjeff *    notice, this list of conditions and the following disclaimer in the
13176730Sjeff *    documentation and/or other materials provided with the distribution.
14176730Sjeff *
15176730Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16176730Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17176730Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18176730Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19176730Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20176730Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21176730Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22176730Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23176730Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24176730Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25176730Sjeff *
26176730Sjeff * $FreeBSD: head/sys/sys/cpuset.h 176730 2008-03-02 07:39:22Z jeff $
27176730Sjeff */
28176730Sjeff
29176730Sjeff#ifndef _SYS_CPUSET_H_
30176730Sjeff#define	_SYS_CPUSET_H_
31176730Sjeff
32176730Sjeff#ifdef _KERNEL
33176730Sjeff#define	CPU_SETSIZE	MAXCPU
34176730Sjeff#endif
35176730Sjeff
36176730Sjeff#define	CPU_MAXSIZE	128
37176730Sjeff
38176730Sjeff#ifndef	CPU_SETSIZE
39176730Sjeff#define	CPU_SETSIZE	CPU_MAXSIZE
40176730Sjeff#endif
41176730Sjeff
42176730Sjeff#define	_NCPUBITS	(sizeof(long) * NBBY)	/* bits per mask */
43176730Sjeff#define	_NCPUWORDS	howmany(CPU_SETSIZE, _NCPUBITS)
44176730Sjeff
45176730Sjefftypedef	struct _cpuset {
46176730Sjeff	long	__bits[howmany(CPU_SETSIZE, _NCPUBITS)];
47176730Sjeff} cpuset_t;
48176730Sjeff
49176730Sjeff#define	__cpuset_mask(n)	((long)1 << ((n) % _NCPUBITS))
50176730Sjeff#define	CPU_CLR(n, p)	((p)->__bits[(n)/_NCPUBITS] &= ~__cpuset_mask(n))
51176730Sjeff#define	CPU_COPY(f, t)	(void)(*(t) = *(f))
52176730Sjeff#define	CPU_ISSET(n, p)	(((p)->__bits[(n)/_NCPUBITS] & __cpuset_mask(n)) != 0)
53176730Sjeff#define	CPU_SET(n, p)	((p)->__bits[(n)/_NCPUBITS] |= __cpuset_mask(n))
54176730Sjeff#define	CPU_ZERO(p) do {				\
55176730Sjeff	__size_t __i;					\
56176730Sjeff	for (__i = 0; __i < _NCPUWORDS; __i++)		\
57176730Sjeff		(p)->__bits[__i] = 0;			\
58176730Sjeff} while (0)
59176730Sjeff
60176730Sjeff#define	CPU_EMPTY(p) __extension__ ({			\
61176730Sjeff	__size_t __i;					\
62176730Sjeff	for (__i = 0; __i < _NCPUWORDS; __i++)		\
63176730Sjeff		if ((p)->__bits[__i])			\
64176730Sjeff			break;				\
65176730Sjeff	__i == _NCPUWORDS;				\
66176730Sjeff})
67176730Sjeff
68176730Sjeff#define	CPU_OR(d, s) do {				\
69176730Sjeff	__size_t __i;					\
70176730Sjeff	for (__i = 0; __i < _NCPUWORDS; __i++)		\
71176730Sjeff		(d)->__bits[__i] |= (s)->__bits[__i];	\
72176730Sjeff} while (0)
73176730Sjeff
74176730Sjeff#define	CPU_AND(d, s) do {				\
75176730Sjeff	__size_t __i;					\
76176730Sjeff	for (__i = 0; __i < _NCPUWORDS; __i++)		\
77176730Sjeff		(d)->__bits[__i] &= (s)->__bits[__i];	\
78176730Sjeff} while (0)
79176730Sjeff
80176730Sjeff#define	CPU_NAND(d, s) do {				\
81176730Sjeff	__size_t __i;					\
82176730Sjeff	for (__i = 0; __i < _NCPUWORDS; __i++)		\
83176730Sjeff		(d)->__bits[__i] &= ~(s)->__bits[__i];	\
84176730Sjeff} while (0)
85176730Sjeff
86176730Sjeff/*
87176730Sjeff * Valid cpulevel_t values.
88176730Sjeff */
89176730Sjeff#define	CPU_LEVEL_ROOT		1	/* All system cpus. */
90176730Sjeff#define	CPU_LEVEL_CPUSET	2	/* Available cpus for which. */
91176730Sjeff#define	CPU_LEVEL_WHICH		3	/* Actual mask/id for which. */
92176730Sjeff
93176730Sjeff/*
94176730Sjeff * Valid cpuwhich_t values.
95176730Sjeff */
96176730Sjeff#define	CPU_WHICH_TID		1	/* Specifies a thread id. */
97176730Sjeff#define	CPU_WHICH_PID		2	/* Specifies a process id. */
98176730Sjeff#define	CPU_WHICH_CPUSET	3	/* Specifies a set id. */
99176730Sjeff
100176730Sjeff/*
101176730Sjeff * Reserved cpuset identifiers.
102176730Sjeff */
103176730Sjeff#define	CPUSET_INVALID	-1
104176730Sjeff#define	CPUSET_DEFAULT	0
105176730Sjeff
106176730Sjeff#ifdef _KERNEL
107176730SjeffLIST_HEAD(setlist, cpuset);
108176730Sjeff
109176730Sjeff/*
110176730Sjeff * cpusets encapsulate cpu binding information for one or more threads.
111176730Sjeff *
112176730Sjeff * 	a - Accessed with atomics.
113176730Sjeff *	s - Set at creation, never modified.  Only a ref required to read.
114176730Sjeff *	c - Locked internally by a cpuset lock.
115176730Sjeff *
116176730Sjeff * The bitmask is only modified while holding the cpuset lock.  It may be
117176730Sjeff * read while only a reference is held but the consumer must be prepared
118176730Sjeff * to deal with inconsistent results.
119176730Sjeff */
120176730Sjeffstruct cpuset {
121176730Sjeff	cpuset_t		cs_mask;	/* bitmask of valid cpus. */
122176730Sjeff	volatile u_int		cs_ref;		/* (a) Reference count. */
123176730Sjeff	int			cs_flags;	/* (s) Flags from below. */
124176730Sjeff	cpusetid_t		cs_id;		/* (s) Id or INVALID. */
125176730Sjeff	struct cpuset		*cs_parent;	/* (s) Pointer to our parent. */
126176730Sjeff	LIST_ENTRY(cpuset)	cs_link;	/* (c) All identified sets. */
127176730Sjeff	LIST_ENTRY(cpuset)	cs_siblings;	/* (c) Sibling set link. */
128176730Sjeff	struct setlist		cs_children;	/* (c) List of children. */
129176730Sjeff};
130176730Sjeff
131176730Sjeff#define CPU_SET_ROOT    0x0001  /* Set is a root set. */
132176730Sjeff#define CPU_SET_RDONLY  0x0002  /* No modification allowed. */
133176730Sjeff
134176730Sjeffstruct cpuset *cpuset_thread0(void);
135176730Sjeffstruct cpuset *cpuset_ref(struct cpuset *);
136176730Sjeffvoid cpuset_rel(struct cpuset *);
137176730Sjeff#else
138176730Sjeff__BEGIN_DECLS
139176730Sjeffint	cpuset(cpusetid_t *);
140176730Sjeffint	cpuset_setid(cpuwhich_t, id_t, cpusetid_t);
141176730Sjeffint	cpuset_getid(cpulevel_t, cpuwhich_t, id_t, cpusetid_t *);
142176730Sjeffint	cpuset_getaffinity(cpulevel_t, cpuwhich_t, id_t, int, cpuset_t *);
143176730Sjeffint	cpuset_setaffinity(cpulevel_t, cpuwhich_t, id_t, int, cpuset_t *);
144176730Sjeff__END_DECLS
145176730Sjeff#endif
146176730Sjeff#endif /* !_SYS_CPUSET_H_ */
147