xref: /kvm-unit-tests/lib/cpumask.h (revision dfc1fec2fbde04ad607e1aed560cf7059350c70f)
1*dfc1fec2SAndrew Jones /* SPDX-License-Identifier: GPL-2.0-only */
2f20e2561SAndrew Jones /*
3f20e2561SAndrew Jones  * Simple cpumask implementation
4f20e2561SAndrew Jones  *
5f20e2561SAndrew Jones  * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com>
6f20e2561SAndrew Jones  */
7*dfc1fec2SAndrew Jones #ifndef _CPUMASK_H_
8*dfc1fec2SAndrew Jones #define _CPUMASK_H_
9f20e2561SAndrew Jones #include <asm/setup.h>
106ed97c50SPeter Feiner #include <bitops.h>
11f20e2561SAndrew Jones 
12f20e2561SAndrew Jones #define CPUMASK_NR_LONGS ((NR_CPUS + BITS_PER_LONG - 1) / BITS_PER_LONG)
13f20e2561SAndrew Jones 
14f20e2561SAndrew Jones typedef struct cpumask {
15f20e2561SAndrew Jones 	unsigned long bits[CPUMASK_NR_LONGS];
16f20e2561SAndrew Jones } cpumask_t;
17f20e2561SAndrew Jones 
18f20e2561SAndrew Jones #define cpumask_bits(maskp) ((maskp)->bits)
19f20e2561SAndrew Jones 
20f20e2561SAndrew Jones static inline void cpumask_set_cpu(int cpu, cpumask_t *mask)
21f20e2561SAndrew Jones {
22adae1302SNikos Nikoleris 	assert(cpu >= 0 && cpu < nr_cpus);
23f20e2561SAndrew Jones 	set_bit(cpu, cpumask_bits(mask));
24f20e2561SAndrew Jones }
25f20e2561SAndrew Jones 
26f20e2561SAndrew Jones static inline void cpumask_clear_cpu(int cpu, cpumask_t *mask)
27f20e2561SAndrew Jones {
28adae1302SNikos Nikoleris 	assert(cpu >= 0 && cpu < nr_cpus);
29f20e2561SAndrew Jones 	clear_bit(cpu, cpumask_bits(mask));
30f20e2561SAndrew Jones }
31f20e2561SAndrew Jones 
32f20e2561SAndrew Jones static inline int cpumask_test_cpu(int cpu, const cpumask_t *mask)
33f20e2561SAndrew Jones {
34adae1302SNikos Nikoleris 	assert(cpu >= 0 && cpu < nr_cpus);
35f20e2561SAndrew Jones 	return test_bit(cpu, cpumask_bits(mask));
36f20e2561SAndrew Jones }
37f20e2561SAndrew Jones 
38f20e2561SAndrew Jones static inline int cpumask_test_and_set_cpu(int cpu, cpumask_t *mask)
39f20e2561SAndrew Jones {
40adae1302SNikos Nikoleris 	assert(cpu >= 0 && cpu < nr_cpus);
41f20e2561SAndrew Jones 	return test_and_set_bit(cpu, cpumask_bits(mask));
42f20e2561SAndrew Jones }
43f20e2561SAndrew Jones 
44f20e2561SAndrew Jones static inline int cpumask_test_and_clear_cpu(int cpu, cpumask_t *mask)
45f20e2561SAndrew Jones {
46adae1302SNikos Nikoleris 	assert(cpu >= 0 && cpu < nr_cpus);
47f20e2561SAndrew Jones 	return test_and_clear_bit(cpu, cpumask_bits(mask));
48f20e2561SAndrew Jones }
49f20e2561SAndrew Jones 
50f20e2561SAndrew Jones static inline void cpumask_setall(cpumask_t *mask)
51f20e2561SAndrew Jones {
52f20e2561SAndrew Jones 	int i;
53f20e2561SAndrew Jones 	for (i = 0; i < nr_cpus; i += BITS_PER_LONG)
54f20e2561SAndrew Jones 		cpumask_bits(mask)[BIT_WORD(i)] = ~0UL;
55f20e2561SAndrew Jones 	i -= BITS_PER_LONG;
56f20e2561SAndrew Jones 	if ((nr_cpus - i) < BITS_PER_LONG)
57f20e2561SAndrew Jones 		cpumask_bits(mask)[BIT_WORD(i)] = BIT_MASK(nr_cpus - i) - 1;
58f20e2561SAndrew Jones }
59f20e2561SAndrew Jones 
60f20e2561SAndrew Jones static inline void cpumask_clear(cpumask_t *mask)
61f20e2561SAndrew Jones {
62f20e2561SAndrew Jones 	int i;
63f20e2561SAndrew Jones 	for (i = 0; i < nr_cpus; i += BITS_PER_LONG)
64f20e2561SAndrew Jones 		cpumask_bits(mask)[BIT_WORD(i)] = 0UL;
65f20e2561SAndrew Jones }
66f20e2561SAndrew Jones 
67f20e2561SAndrew Jones static inline bool cpumask_empty(const cpumask_t *mask)
68f20e2561SAndrew Jones {
69f20e2561SAndrew Jones 	int i;
70f20e2561SAndrew Jones 	for (i = 0; i < nr_cpus; i += BITS_PER_LONG) {
71f20e2561SAndrew Jones 		if (i < NR_CPUS) { /* silence crazy compiler warning */
72f20e2561SAndrew Jones 			if (cpumask_bits(mask)[BIT_WORD(i)] != 0UL)
73f20e2561SAndrew Jones 				return false;
74f20e2561SAndrew Jones 		}
75f20e2561SAndrew Jones 	}
76f20e2561SAndrew Jones 	return true;
77f20e2561SAndrew Jones }
78f20e2561SAndrew Jones 
79f20e2561SAndrew Jones static inline bool cpumask_full(const cpumask_t *mask)
80f20e2561SAndrew Jones {
81f20e2561SAndrew Jones 	int i;
82f20e2561SAndrew Jones 	for (i = 0; i < nr_cpus; i += BITS_PER_LONG) {
83f20e2561SAndrew Jones 		if (cpumask_bits(mask)[BIT_WORD(i)] != ~0UL) {
84f20e2561SAndrew Jones 			if ((nr_cpus - i) >= BITS_PER_LONG)
85f20e2561SAndrew Jones 				return false;
86f20e2561SAndrew Jones 			if (cpumask_bits(mask)[BIT_WORD(i)]
87f20e2561SAndrew Jones 					!= BIT_MASK(nr_cpus - i) - 1)
88f20e2561SAndrew Jones 				return false;
89f20e2561SAndrew Jones 		}
90f20e2561SAndrew Jones 	}
91f20e2561SAndrew Jones 	return true;
92f20e2561SAndrew Jones }
93f20e2561SAndrew Jones 
94f20e2561SAndrew Jones static inline int cpumask_weight(const cpumask_t *mask)
95f20e2561SAndrew Jones {
96f20e2561SAndrew Jones 	int w = 0, i;
97f20e2561SAndrew Jones 
98f20e2561SAndrew Jones 	for (i = 0; i < nr_cpus; ++i)
99f20e2561SAndrew Jones 		if (cpumask_test_cpu(i, mask))
100f20e2561SAndrew Jones 			++w;
101f20e2561SAndrew Jones 	return w;
102f20e2561SAndrew Jones }
103f20e2561SAndrew Jones 
104f20e2561SAndrew Jones static inline void cpumask_copy(cpumask_t *dst, const cpumask_t *src)
105f20e2561SAndrew Jones {
106f20e2561SAndrew Jones 	memcpy(cpumask_bits(dst), cpumask_bits(src),
107f20e2561SAndrew Jones 			CPUMASK_NR_LONGS * sizeof(long));
108f20e2561SAndrew Jones }
109f20e2561SAndrew Jones 
110f20e2561SAndrew Jones static inline int cpumask_next(int cpu, const cpumask_t *mask)
111f20e2561SAndrew Jones {
112fdab948bSNikos Nikoleris 	while (++cpu < nr_cpus && !cpumask_test_cpu(cpu, mask))
113f20e2561SAndrew Jones 		;
114f20e2561SAndrew Jones 	return cpu;
115f20e2561SAndrew Jones }
116f20e2561SAndrew Jones 
117f20e2561SAndrew Jones #define for_each_cpu(cpu, mask)					\
118f20e2561SAndrew Jones 	for ((cpu) = cpumask_next(-1, mask);			\
119f20e2561SAndrew Jones 			(cpu) < nr_cpus; 			\
120f20e2561SAndrew Jones 			(cpu) = cpumask_next(cpu, mask))
121f20e2561SAndrew Jones 
122*dfc1fec2SAndrew Jones #endif /* _CPUMASK_H_ */
123