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