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