• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Mask inlines
3  *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
4  *
5  *
6  *   This library is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU Lesser General Public License as
8  *   published by the Free Software Foundation; either version 2.1 of
9  *   the License, or (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU Lesser General Public License for more details.
15  *
16  *   You should have received a copy of the GNU Lesser General Public
17  *   License along with this library; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21 
22 #include <strings.h>
23 #include <sys/types.h>
24 
25 #define MASK_INLINE static inline
26 
27 #define MASK_MAX SND_MASK_MAX
28 #define MASK_SIZE (MASK_MAX / 32)
29 
30 #define MASK_OFS(i)	((i) >> 5)
31 #define MASK_BIT(i)	(1U << ((i) & 31))
32 
ld2(uint32_t v)33 MASK_INLINE unsigned int ld2(uint32_t v)
34 {
35         unsigned r = 0;
36 
37         if (v >= 0x10000) {
38                 v >>= 16;
39                 r += 16;
40         }
41         if (v >= 0x100) {
42                 v >>= 8;
43                 r += 8;
44         }
45         if (v >= 0x10) {
46                 v >>= 4;
47                 r += 4;
48         }
49         if (v >= 4) {
50                 v >>= 2;
51                 r += 2;
52         }
53         if (v >= 2)
54                 r++;
55         return r;
56 }
57 
hweight32(uint32_t v)58 MASK_INLINE unsigned int hweight32(uint32_t v)
59 {
60         v = (v & 0x55555555) + ((v >> 1) & 0x55555555);
61         v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
62         v = (v & 0x0F0F0F0F) + ((v >> 4) & 0x0F0F0F0F);
63         v = (v & 0x00FF00FF) + ((v >> 8) & 0x00FF00FF);
64         return (v & 0x0000FFFF) + ((v >> 16) & 0x0000FFFF);
65 }
66 
snd_mask_sizeof(void)67 MASK_INLINE size_t snd_mask_sizeof(void)
68 {
69 	return sizeof(snd_mask_t);
70 }
71 
snd_mask_none(snd_mask_t * mask)72 MASK_INLINE void snd_mask_none(snd_mask_t *mask)
73 {
74 	memset(mask, 0, sizeof(*mask));
75 }
76 
snd_mask_any(snd_mask_t * mask)77 MASK_INLINE void snd_mask_any(snd_mask_t *mask)
78 {
79 	memset(mask, 0xff, MASK_SIZE * sizeof(uint32_t));
80 }
81 
snd_mask_empty(const snd_mask_t * mask)82 MASK_INLINE int snd_mask_empty(const snd_mask_t *mask)
83 {
84 	int i;
85 	for (i = 0; i < MASK_SIZE; i++)
86 		if (mask->bits[i])
87 			return 0;
88 	return 1;
89 }
90 
snd_mask_full(const snd_mask_t * mask)91 MASK_INLINE int snd_mask_full(const snd_mask_t *mask)
92 {
93 	int i;
94 	for (i = 0; i < MASK_SIZE; i++)
95 		if (mask->bits[i] != 0xffffffff)
96 			return 0;
97 	return 1;
98 }
99 
snd_mask_count(const snd_mask_t * mask)100 MASK_INLINE unsigned int snd_mask_count(const snd_mask_t *mask)
101 {
102 	int i, w = 0;
103 	for (i = 0; i < MASK_SIZE; i++)
104 		w += hweight32(mask->bits[i]);
105 	return w;
106 }
107 
snd_mask_min(const snd_mask_t * mask)108 MASK_INLINE unsigned int snd_mask_min(const snd_mask_t *mask)
109 {
110 	int i;
111 	assert(!snd_mask_empty(mask));
112 	for (i = 0; i < MASK_SIZE; i++) {
113 		if (mask->bits[i])
114 			return ffs(mask->bits[i]) - 1 + (i << 5);
115 	}
116 	return 0;
117 }
118 
snd_mask_max(const snd_mask_t * mask)119 MASK_INLINE unsigned int snd_mask_max(const snd_mask_t *mask)
120 {
121 	int i;
122 	assert(!snd_mask_empty(mask));
123 	for (i = MASK_SIZE - 1; i >= 0; i--) {
124 		if (mask->bits[i])
125 			return ld2(mask->bits[i]) + (i << 5);
126 	}
127 	return 0;
128 }
129 
snd_mask_set(snd_mask_t * mask,unsigned int val)130 MASK_INLINE void snd_mask_set(snd_mask_t *mask, unsigned int val)
131 {
132 	assert(val <= SND_MASK_MAX);
133 	mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
134 }
135 
snd_mask_reset(snd_mask_t * mask,unsigned int val)136 MASK_INLINE void snd_mask_reset(snd_mask_t *mask, unsigned int val)
137 {
138 	assert(val <= SND_MASK_MAX);
139 	mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
140 }
141 
snd_mask_set_range(snd_mask_t * mask,unsigned int from,unsigned int to)142 MASK_INLINE void snd_mask_set_range(snd_mask_t *mask, unsigned int from, unsigned int to)
143 {
144 	unsigned int i;
145 	assert(to <= SND_MASK_MAX && from <= to);
146 	for (i = from; i <= to; i++)
147 		mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
148 }
149 
snd_mask_reset_range(snd_mask_t * mask,unsigned int from,unsigned int to)150 MASK_INLINE void snd_mask_reset_range(snd_mask_t *mask, unsigned int from, unsigned int to)
151 {
152 	unsigned int i;
153 	assert(to <= SND_MASK_MAX && from <= to);
154 	for (i = from; i <= to; i++)
155 		mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
156 }
157 
snd_mask_leave(snd_mask_t * mask,unsigned int val)158 MASK_INLINE void snd_mask_leave(snd_mask_t *mask, unsigned int val)
159 {
160 	unsigned int v;
161 	assert(val <= SND_MASK_MAX);
162 	v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
163 	snd_mask_none(mask);
164 	mask->bits[MASK_OFS(val)] = v;
165 }
166 
snd_mask_intersect(snd_mask_t * mask,const snd_mask_t * v)167 MASK_INLINE void snd_mask_intersect(snd_mask_t *mask, const snd_mask_t *v)
168 {
169 	int i;
170 	for (i = 0; i < MASK_SIZE; i++)
171 		mask->bits[i] &= v->bits[i];
172 }
173 
snd_mask_union(snd_mask_t * mask,const snd_mask_t * v)174 MASK_INLINE void snd_mask_union(snd_mask_t *mask, const snd_mask_t *v)
175 {
176 	int i;
177 	for (i = 0; i < MASK_SIZE; i++)
178 		mask->bits[i] |= v->bits[i];
179 }
180 
snd_mask_eq(const snd_mask_t * mask,const snd_mask_t * v)181 MASK_INLINE int snd_mask_eq(const snd_mask_t *mask, const snd_mask_t *v)
182 {
183 	return ! memcmp(mask, v, MASK_SIZE * 4);
184 }
185 
snd_mask_copy(snd_mask_t * mask,const snd_mask_t * v)186 MASK_INLINE void snd_mask_copy(snd_mask_t *mask, const snd_mask_t *v)
187 {
188 	*mask = *v;
189 }
190 
snd_mask_test(const snd_mask_t * mask,unsigned int val)191 MASK_INLINE int snd_mask_test(const snd_mask_t *mask, unsigned int val)
192 {
193 	assert(val <= SND_MASK_MAX);
194 	return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
195 }
196 
snd_mask_single(const snd_mask_t * mask)197 MASK_INLINE int snd_mask_single(const snd_mask_t *mask)
198 {
199 	int i, c = 0;
200 	assert(!snd_mask_empty(mask));
201 	for (i = 0; i < MASK_SIZE; i++) {
202 		if (! mask->bits[i])
203 			continue;
204 		if (mask->bits[i] & (mask->bits[i] - 1))
205 			return 0;
206 		if (c)
207 			return 0;
208 		c++;
209 	}
210 	return 1;
211 }
212 
snd_mask_refine(snd_mask_t * mask,const snd_mask_t * v)213 MASK_INLINE int snd_mask_refine(snd_mask_t *mask, const snd_mask_t *v)
214 {
215 	snd_mask_t old;
216 	if (snd_mask_empty(mask))
217 		return -ENOENT;
218 	snd_mask_copy(&old, mask);
219 	snd_mask_intersect(mask, v);
220 	if (snd_mask_empty(mask))
221 		return -EINVAL;
222 	return !snd_mask_eq(mask, &old);
223 }
224 
snd_mask_refine_first(snd_mask_t * mask)225 MASK_INLINE int snd_mask_refine_first(snd_mask_t *mask)
226 {
227 	if (snd_mask_empty(mask))
228 		return -ENOENT;
229 	if (snd_mask_single(mask))
230 		return 0;
231 	snd_mask_leave(mask, snd_mask_min(mask));
232 	return 1;
233 }
234 
snd_mask_refine_last(snd_mask_t * mask)235 MASK_INLINE int snd_mask_refine_last(snd_mask_t *mask)
236 {
237 	if (snd_mask_empty(mask))
238 		return -ENOENT;
239 	if (snd_mask_single(mask))
240 		return 0;
241 	snd_mask_leave(mask, snd_mask_max(mask));
242 	return 1;
243 }
244 
snd_mask_refine_min(snd_mask_t * mask,unsigned int val)245 MASK_INLINE int snd_mask_refine_min(snd_mask_t *mask, unsigned int val)
246 {
247 	if (snd_mask_empty(mask))
248 		return -ENOENT;
249 	if (snd_mask_min(mask) >= val)
250 		return 0;
251 	snd_mask_reset_range(mask, 0, val - 1);
252 	if (snd_mask_empty(mask))
253 		return -EINVAL;
254 	return 1;
255 }
256 
snd_mask_refine_max(snd_mask_t * mask,unsigned int val)257 MASK_INLINE int snd_mask_refine_max(snd_mask_t *mask, unsigned int val)
258 {
259 	if (snd_mask_empty(mask))
260 		return -ENOENT;
261 	if (snd_mask_max(mask) <= val)
262 		return 0;
263 	snd_mask_reset_range(mask, val + 1, SND_MASK_MAX);
264 	if (snd_mask_empty(mask))
265 		return -EINVAL;
266 	return 1;
267 }
268 
snd_mask_refine_set(snd_mask_t * mask,unsigned int val)269 MASK_INLINE int snd_mask_refine_set(snd_mask_t *mask, unsigned int val)
270 {
271 	int changed;
272 	if (snd_mask_empty(mask))
273 		return -ENOENT;
274 	changed = !snd_mask_single(mask);
275 	snd_mask_leave(mask, val);
276 	if (snd_mask_empty(mask))
277 		return -EINVAL;
278 	return changed;
279 }
280 
snd_mask_value(const snd_mask_t * mask)281 MASK_INLINE int snd_mask_value(const snd_mask_t *mask)
282 {
283 	assert(!snd_mask_empty(mask));
284 	return snd_mask_min(mask);
285 }
286 
snd_mask_always_eq(const snd_mask_t * m1,const snd_mask_t * m2)287 MASK_INLINE int snd_mask_always_eq(const snd_mask_t *m1, const snd_mask_t *m2)
288 {
289 	return snd_mask_single(m1) && snd_mask_single(m2) &&
290 		snd_mask_value(m1) == snd_mask_value(m2);
291 }
292 
snd_mask_never_eq(const snd_mask_t * m1,const snd_mask_t * m2)293 MASK_INLINE int snd_mask_never_eq(const snd_mask_t *m1, const snd_mask_t *m2)
294 {
295 	int i;
296 	for (i = 0; i < MASK_SIZE; i++)
297 		if (m1->bits[i] & m2->bits[i])
298 			return 0;
299 	return 1;
300 }
301