Home | History | Annotate | Download | only in cpuset_lib
      1 /*
      2  * bitmask user library implementation.
      3  *
      4  * Copyright (c) 2004-2006 Silicon Graphics, Inc. All rights reserved.
      5  *
      6  * Paul Jackson <pj (at) sgi.com>
      7  */
      8 
      9 /*
     10  *  This program is free software; you can redistribute it and/or modify
     11  *  it under the terms of the GNU Lesser General Public License as published by
     12  *  the Free Software Foundation; either version 2.1 of the License, or
     13  *  (at your option) any later version.
     14  *
     15  *  This program is distributed in the hope that it will be useful,
     16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  *  GNU Lesser General Public License for more details.
     19  *
     20  *  You should have received a copy of the GNU Lesser General Public License
     21  *  along with this program; if not, write to the Free Software
     22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     23  */
     24 
     25 #include <stdio.h>
     26 #include <string.h>
     27 #include <stdlib.h>
     28 #include <stdint.h>
     29 
     30 #include "bitmask.h"
     31 #include "tst_minmax.h"
     32 
     33 struct bitmask {
     34 	unsigned int size;
     35 	unsigned long *maskp;
     36 };
     37 
     38 /* How many bits in an unsigned long */
     39 #define bitsperlong (8 * sizeof(unsigned long))
     40 
     41 /* howmany(a,b) : how many elements of size b needed to hold all of a */
     42 #define howmany(x,y) (((x)+((y)-1))/(y))
     43 
     44 /* How many longs in mask of n bits */
     45 #define longsperbits(n) howmany(n, bitsperlong)
     46 
     47 /*
     48  * The routines _getbit() and _setbit() are the only
     49  * routines that actually understand the layout of bmp->maskp[].
     50  *
     51  * On little endian architectures, this could simply be an array of
     52  * bytes.  But the kernel layout of bitmasks _is_ visible to userspace
     53  * via the sched_(set/get)affinity calls in Linux 2.6, and on big
     54  * endian architectures, it is painfully obvious that this is an
     55  * array of unsigned longs.
     56  */
     57 
     58 /* Return the value (0 or 1) of bit n in bitmask bmp */
     59 static unsigned int _getbit(const struct bitmask *bmp, unsigned int n)
     60 {
     61 	if (n < bmp->size)
     62 		return (bmp->maskp[n / bitsperlong] >> (n % bitsperlong)) & 1;
     63 	else
     64 		return 0;
     65 }
     66 
     67 /* Set bit n in bitmask bmp to value v (0 or 1) */
     68 static void _setbit(struct bitmask *bmp, unsigned int n, unsigned int v)
     69 {
     70 	if (n < bmp->size) {
     71 		if (v)
     72 			bmp->maskp[n / bitsperlong] |= 1UL << (n % bitsperlong);
     73 		else
     74 			bmp->maskp[n / bitsperlong] &=
     75 			    ~(1UL << (n % bitsperlong));
     76 	}
     77 }
     78 
     79 /*
     80  * Allocate and free `struct bitmask *`
     81  */
     82 
     83 /* Allocate a new `struct bitmask` with a size of n bits */
     84 struct bitmask *bitmask_alloc(unsigned int n)
     85 {
     86 	struct bitmask *bmp;
     87 
     88 	bmp = malloc(sizeof(*bmp));
     89 	if (bmp == 0)
     90 		return 0;
     91 	bmp->size = n;
     92 	bmp->maskp = calloc(longsperbits(n), sizeof(unsigned long));
     93 	if (bmp->maskp == 0) {
     94 		free(bmp);
     95 		return 0;
     96 	}
     97 	return bmp;
     98 }
     99 
    100 /* Free `struct bitmask` */
    101 void bitmask_free(struct bitmask *bmp)
    102 {
    103 	if (bmp == 0)
    104 		return;
    105 	free(bmp->maskp);
    106 	bmp->maskp = (unsigned long *)0xdeadcdef;	/* double free tripwire */
    107 	free(bmp);
    108 }
    109 
    110 /*
    111  * Display and parse ascii string representations.
    112  */
    113 
    114 #define HEXCHUNKSZ 32		/* hex binary format shows 32 bits per chunk */
    115 #define HEXCHARSZ 8		/* hex ascii format has up to 8 chars per chunk */
    116 
    117 /*
    118  * Write hex word representation of bmp to buf, 32 bits per
    119  * comma-separated, zero-filled hex word.  Do not write more
    120  * than buflen chars to buf.
    121  *
    122  * Return number of chars that would have been written
    123  * if buf were large enough.
    124  */
    125 
    126 int bitmask_displayhex(char *buf, int buflen, const struct bitmask *bmp)
    127 {
    128 	int chunk;
    129 	int cnt = 0;
    130 	const char *sep = "";
    131 
    132 	if (buflen < 1)
    133 		return 0;
    134 	buf[0] = 0;
    135 
    136 	for (chunk = howmany(bmp->size, HEXCHUNKSZ) - 1; chunk >= 0; chunk--) {
    137 		uint32_t val = 0;
    138 		int bit;
    139 
    140 		for (bit = HEXCHUNKSZ - 1; bit >= 0; bit--)
    141 			val = val << 1 | _getbit(bmp, chunk * HEXCHUNKSZ + bit);
    142 		cnt += snprintf(buf + cnt, MAX(buflen - cnt, 0), "%s%0*x",
    143 				sep, HEXCHARSZ, val);
    144 		sep = ",";
    145 	}
    146 	return cnt;
    147 }
    148 
    149 /*
    150  * emit(buf, buflen, rbot, rtop, len)
    151  *
    152  * Helper routine for bitmask_displaylist().  Write decimal number
    153  * or range to buf+len, suppressing output past buf+buflen, with optional
    154  * comma-prefix.  Return len of what would be written to buf, if it
    155  * all fit.
    156  */
    157 
    158 static inline int emit(char *buf, int buflen, int rbot, int rtop, int len)
    159 {
    160 	if (len > 0)
    161 		len += snprintf(buf + len, MAX(buflen - len, 0), ",");
    162 	if (rbot == rtop)
    163 		len += snprintf(buf + len, MAX(buflen - len, 0), "%d", rbot);
    164 	else
    165 		len +=
    166 		    snprintf(buf + len, MAX(buflen - len, 0), "%d-%d", rbot,
    167 			     rtop);
    168 	return len;
    169 }
    170 
    171 /*
    172  * Write decimal list representation of bmp to buf.
    173  *
    174  * Output format is a comma-separated list of decimal numbers and
    175  * ranges.  Consecutively set bits are shown as two hyphen-separated
    176  * decimal numbers, the smallest and largest bit numbers set in
    177  * the range.  Output format is compatible with the format
    178  * accepted as input by bitmap_parselist().
    179  *
    180  * The return value is the number of characters which would be
    181  * generated for the given input, excluding the trailing '\0', as
    182  * per ISO C99.
    183  */
    184 
    185 int bitmask_displaylist(char *buf, int buflen, const struct bitmask *bmp)
    186 {
    187 	int len = 0;
    188 	/* current bit is 'cur', most recently seen range is [rbot, rtop] */
    189 	unsigned int cur, rbot, rtop;
    190 
    191 	if (buflen > 0)
    192 		*buf = 0;
    193 	rbot = cur = bitmask_first(bmp);
    194 	while (cur < bmp->size) {
    195 		rtop = cur;
    196 		cur = bitmask_next(bmp, cur + 1);
    197 		if (cur >= bmp->size || cur > rtop + 1) {
    198 			len = emit(buf, buflen, rbot, rtop, len);
    199 			rbot = cur;
    200 		}
    201 	}
    202 	return len;
    203 }
    204 
    205 static const char *nexttoken(const char *q, int sep)
    206 {
    207 	if (q)
    208 		q = strchr(q, sep);
    209 	if (q)
    210 		q++;
    211 	return q;
    212 }
    213 
    214 /*
    215  * Parse hex word representation in buf to bmp.
    216  *
    217  * Returns -1 on error, leaving unspecified results in bmp.
    218  */
    219 
    220 int bitmask_parsehex(const char *buf, struct bitmask *bmp)
    221 {
    222 	const char *p, *q;
    223 	int nchunks = 0, chunk;
    224 	unsigned int size = 0;
    225 
    226 	bitmask_clearall(bmp);
    227 	size = longsperbits(bmp->size) * 8 * sizeof(unsigned long);
    228 
    229 	q = buf;
    230 	while (p = q, q = nexttoken(q, ','), p)
    231 		nchunks++;
    232 
    233 	chunk = nchunks - 1;
    234 	q = buf;
    235 	while (p = q, q = nexttoken(q, ','), p) {
    236 		uint32_t val;
    237 		int bit;
    238 		char *endptr;
    239 		int nchars_read, nchars_unread;
    240 
    241 		val = strtoul(p, &endptr, 16);
    242 
    243 		/* We should have consumed 1 to 8 (HEXCHARSZ) chars */
    244 		nchars_read = endptr - p;
    245 		if (nchars_read < 1 || nchars_read > HEXCHARSZ)
    246 			goto err;
    247 
    248 		/* We should have consumed up to next comma */
    249 		nchars_unread = q - endptr;
    250 		if (q != NULL && nchars_unread != 1)
    251 			goto err;
    252 
    253 		for (bit = HEXCHUNKSZ - 1; bit >= 0; bit--) {
    254 			unsigned int n = chunk * HEXCHUNKSZ + bit;
    255 			if (n >= size)
    256 				goto err;
    257 			_setbit(bmp, n, (val >> bit) & 1);
    258 		}
    259 		chunk--;
    260 	}
    261 	return 0;
    262 err:
    263 	bitmask_clearall(bmp);
    264 	return -1;
    265 }
    266 
    267 /*
    268  * When parsing bitmask lists, only allow numbers, separated by one
    269  * of the allowed next characters.
    270  *
    271  * The parameter 'sret' is the return from a sscanf "%u%c".  It is
    272  * -1 if the sscanf input string was empty.  It is 0 if the first
    273  * character in the sscanf input string was not a decimal number.
    274  * It is 1 if the unsigned number matching the "%u" was the end of the
    275  * input string.  It is 2 if one or more additional characters followed
    276  * the matched unsigned number.  If it is 2, then 'nextc' is the first
    277  * character following the number.  The parameter 'ok_next_chars'
    278  * is the nul-terminated list of allowed next characters.
    279  *
    280  * The mask term just scanned was ok if and only if either the numbers
    281  * matching the %u were all of the input or if the next character in
    282  * the input past the numbers was one of the allowed next characters.
    283  */
    284 static int scan_was_ok(int sret, char nextc, const char *ok_next_chars)
    285 {
    286 	return sret == 1 || (sret == 2 && strchr(ok_next_chars, nextc) != NULL);
    287 }
    288 
    289 /*
    290  * Parses a comma-separated list of numbers and ranges of numbers,
    291  * with optional ':%u' strides modifying ranges, into provided bitmask.
    292  * Some examples of input lists and their equivalent simple list:
    293  *	Input		Equivalent to
    294  *	0-3		0,1,2,3
    295  *	0-7:2		0,2,4,6
    296  *	1,3,5-7		1,3,5,6,7
    297  *	0-3:2,8-15:4	0,2,8,12
    298  */
    299 int bitmask_parselist(const char *buf, struct bitmask *bmp)
    300 {
    301 	const char *p, *q;
    302 
    303 	bitmask_clearall(bmp);
    304 
    305 	q = buf;
    306 	while (p = q, q = nexttoken(q, ','), p) {
    307 		unsigned int a;	/* begin of range */
    308 		unsigned int b;	/* end of range */
    309 		unsigned int s;	/* stride */
    310 		const char *c1, *c2;	/* next tokens after '-' or ',' */
    311 		char nextc;	/* char after sscanf %u match */
    312 		int sret;	/* sscanf return (number of matches) */
    313 
    314 		sret = sscanf(p, "%u%c", &a, &nextc);
    315 		if (!scan_was_ok(sret, nextc, ",-"))
    316 			goto err;
    317 		b = a;
    318 		s = 1;
    319 		c1 = nexttoken(p, '-');
    320 		c2 = nexttoken(p, ',');
    321 		if (c1 != NULL && (c2 == NULL || c1 < c2)) {
    322 			sret = sscanf(c1, "%u%c", &b, &nextc);
    323 			if (!scan_was_ok(sret, nextc, ",:"))
    324 				goto err;
    325 			c1 = nexttoken(c1, ':');
    326 			if (c1 != NULL && (c2 == NULL || c1 < c2)) {
    327 				sret = sscanf(c1, "%u%c", &s, &nextc);
    328 				if (!scan_was_ok(sret, nextc, ","))
    329 					goto err;
    330 			}
    331 		}
    332 		if (!(a <= b))
    333 			goto err;
    334 		if (b >= bmp->size)
    335 			goto err;
    336 		while (a <= b) {
    337 			_setbit(bmp, a, 1);
    338 			a += s;
    339 		}
    340 	}
    341 	return 0;
    342 err:
    343 	bitmask_clearall(bmp);
    344 	return -1;
    345 }
    346 
    347 /*
    348  * Basic assignment operations
    349  */
    350 
    351 /* Copy bmp2 to bmp1 */
    352 struct bitmask *bitmask_copy(struct bitmask *bmp1, const struct bitmask *bmp2)
    353 {
    354 	unsigned int i;
    355 	for (i = 0; i < bmp1->size; i++)
    356 		_setbit(bmp1, i, _getbit(bmp2, i));
    357 	return bmp1;
    358 }
    359 
    360 /* Set all bits in bitmask: bmp = ~0 */
    361 struct bitmask *bitmask_setall(struct bitmask *bmp)
    362 {
    363 	unsigned int i;
    364 	for (i = 0; i < bmp->size; i++)
    365 		_setbit(bmp, i, 1);
    366 	return bmp;
    367 }
    368 
    369 /* Clear all bits in bitmask: bmp = 0 */
    370 struct bitmask *bitmask_clearall(struct bitmask *bmp)
    371 {
    372 	unsigned int i;
    373 	for (i = 0; i < bmp->size; i++)
    374 		_setbit(bmp, i, 0);
    375 	return bmp;
    376 }
    377 
    378 /*
    379  * Interface to kernel sched_setaffinity system call
    380  */
    381 
    382 /* Length in bytes of mask - use as second argument to sched_setaffinity */
    383 unsigned int bitmask_nbytes(struct bitmask *bmp)
    384 {
    385 	return longsperbits(bmp->size) * sizeof(unsigned long);
    386 }
    387 
    388 /* Direct pointer to bit mask - use as third argument to sched_setaffinty */
    389 unsigned long *bitmask_mask(struct bitmask *bmp)
    390 {
    391 	return bmp->maskp;
    392 }
    393 
    394 /*
    395  * Unary numeric queries
    396  */
    397 
    398 /* Size in bits of entire bitmask */
    399 unsigned int bitmask_nbits(const struct bitmask *bmp)
    400 {
    401 	return bmp->size;
    402 }
    403 
    404 /* Hamming Weight: number of set bits */
    405 unsigned int bitmask_weight(const struct bitmask *bmp)
    406 {
    407 	unsigned int i;
    408 	unsigned int w = 0;
    409 	for (i = 0; i < bmp->size; i++)
    410 		if (_getbit(bmp, i))
    411 			w++;
    412 	return w;
    413 }
    414 
    415 /*
    416  * Unary Boolean queries
    417  */
    418 
    419 /* True if specified bit i is set */
    420 int bitmask_isbitset(const struct bitmask *bmp, unsigned int i)
    421 {
    422 	return _getbit(bmp, i);
    423 }
    424 
    425 /* True if specified bit i is clear */
    426 int bitmask_isbitclear(const struct bitmask *bmp, unsigned int i)
    427 {
    428 	return !_getbit(bmp, i);
    429 }
    430 
    431 /* True if all bits are set */
    432 int bitmask_isallset(const struct bitmask *bmp)
    433 {
    434 	unsigned int i;
    435 	for (i = 0; i < bmp->size; i++)
    436 		if (!_getbit(bmp, i))
    437 			return 0;
    438 	return 1;
    439 }
    440 
    441 /* True if all bits are clear */
    442 int bitmask_isallclear(const struct bitmask *bmp)
    443 {
    444 	unsigned int i;
    445 	for (i = 0; i < bmp->size; i++)
    446 		if (_getbit(bmp, i))
    447 			return 0;
    448 	return 1;
    449 }
    450 
    451 /*
    452  * Single bit operations
    453  */
    454 
    455 /* Set a single bit i in bitmask */
    456 struct bitmask *bitmask_setbit(struct bitmask *bmp, unsigned int i)
    457 {
    458 	_setbit(bmp, i, 1);
    459 	return bmp;
    460 }
    461 
    462 /* Clear a single bit i in bitmask */
    463 struct bitmask *bitmask_clearbit(struct bitmask *bmp, unsigned int i)
    464 {
    465 	_setbit(bmp, i, 0);
    466 	return bmp;
    467 }
    468 
    469 /*
    470  * Binary Boolean operations: bmp1 op? bmp2
    471  */
    472 
    473 /* True if two bitmasks are equal */
    474 int bitmask_equal(const struct bitmask *bmp1, const struct bitmask *bmp2)
    475 {
    476 	unsigned int i;
    477 	for (i = 0; i < bmp1->size || i < bmp2->size; i++)
    478 		if (_getbit(bmp1, i) != _getbit(bmp2, i))
    479 			return 0;
    480 	return 1;
    481 }
    482 
    483 /* True if first bitmask is subset of second */
    484 int bitmask_subset(const struct bitmask *bmp1, const struct bitmask *bmp2)
    485 {
    486 	unsigned int i;
    487 	for (i = 0; i < bmp1->size; i++)
    488 		if (_getbit(bmp1, i) > _getbit(bmp2, i))
    489 			return 0;
    490 	return 1;
    491 }
    492 
    493 /* True if two bitmasks don't overlap */
    494 int bitmask_disjoint(const struct bitmask *bmp1, const struct bitmask *bmp2)
    495 {
    496 	unsigned int i;
    497 	for (i = 0; i < bmp1->size; i++)
    498 		if (_getbit(bmp1, i) & _getbit(bmp2, i))
    499 			return 0;
    500 	return 1;
    501 }
    502 
    503 /* True if two bitmasks do overlap */
    504 int bitmask_intersects(const struct bitmask *bmp1, const struct bitmask *bmp2)
    505 {
    506 	unsigned int i;
    507 	for (i = 0; i < bmp1->size; i++)
    508 		if (_getbit(bmp1, i) & _getbit(bmp2, i))
    509 			return 1;
    510 	return 0;
    511 }
    512 
    513 /*
    514  * Range operations
    515  */
    516 
    517 /* Set bits of bitmask in specified range [i, j) */
    518 struct bitmask *bitmask_setrange(struct bitmask *bmp,
    519 				 unsigned int i, unsigned int j)
    520 {
    521 	unsigned int n;
    522 	for (n = i; n < j; n++)
    523 		_setbit(bmp, n, 1);
    524 	return bmp;
    525 }
    526 
    527 /* Clear bits of bitmask in specified range */
    528 struct bitmask *bitmask_clearrange(struct bitmask *bmp,
    529 				   unsigned int i, unsigned int j)
    530 {
    531 	unsigned int n;
    532 	for (n = i; n < j; n++)
    533 		_setbit(bmp, n, 0);
    534 	return bmp;
    535 }
    536 
    537 /* Clear all but specified range */
    538 struct bitmask *bitmask_keeprange(struct bitmask *bmp,
    539 				  unsigned int i, unsigned int j)
    540 {
    541 	bitmask_clearrange(bmp, 0, i);
    542 	bitmask_clearrange(bmp, j, bmp->size);
    543 	return bmp;
    544 }
    545 
    546 /*
    547  * Unary operations: bmp1 = op(struct bitmask *bmp2)
    548  */
    549 
    550 /* Complement: bmp1 = ~bmp2 */
    551 struct bitmask *bitmask_complement(struct bitmask *bmp1,
    552 				   const struct bitmask *bmp2)
    553 {
    554 	unsigned int i;
    555 	for (i = 0; i < bmp1->size; i++)
    556 		_setbit(bmp1, i, !_getbit(bmp2, i));
    557 	return bmp1;
    558 }
    559 
    560 /* Right shift: bmp1 = bmp2 >> n */
    561 struct bitmask *bitmask_shiftright(struct bitmask *bmp1,
    562 				   const struct bitmask *bmp2, unsigned int n)
    563 {
    564 	unsigned int i;
    565 	for (i = 0; i < bmp1->size; i++)
    566 		_setbit(bmp1, i, _getbit(bmp2, i + n));
    567 	return bmp1;
    568 }
    569 
    570 /* Left shift: bmp1 = bmp2 << n */
    571 struct bitmask *bitmask_shiftleft(struct bitmask *bmp1,
    572 				  const struct bitmask *bmp2, unsigned int n)
    573 {
    574 	int i;
    575 	for (i = bmp1->size - 1; i >= 0; i--)
    576 		_setbit(bmp1, i, _getbit(bmp2, i - n));
    577 	return bmp1;
    578 }
    579 
    580 /*
    581  * Binary operations: bmp1 = bmp2 op bmp3
    582  */
    583 
    584 /* Logical `and` of two bitmasks: bmp1 = bmp2 & bmp3 */
    585 struct bitmask *bitmask_and(struct bitmask *bmp1, const struct bitmask *bmp2,
    586 			    const struct bitmask *bmp3)
    587 {
    588 	unsigned int i;
    589 	for (i = 0; i < bmp1->size; i++)
    590 		_setbit(bmp1, i, _getbit(bmp2, i) & _getbit(bmp3, i));
    591 	return bmp1;
    592 }
    593 
    594 /* Logical `andnot` of two bitmasks: bmp1 = bmp2 & ~bmp3 */
    595 struct bitmask *bitmask_andnot(struct bitmask *bmp1, const struct bitmask *bmp2,
    596 			       const struct bitmask *bmp3)
    597 {
    598 	unsigned int i;
    599 	for (i = 0; i < bmp1->size; i++)
    600 		_setbit(bmp1, i, _getbit(bmp2, i) & ~_getbit(bmp3, i));
    601 	return bmp1;
    602 }
    603 
    604 /* Logical `or` of two bitmasks: bmp1 = bmp2 | bmp3 */
    605 struct bitmask *bitmask_or(struct bitmask *bmp1, const struct bitmask *bmp2,
    606 			   const struct bitmask *bmp3)
    607 {
    608 	unsigned int i;
    609 	for (i = 0; i < bmp1->size; i++)
    610 		_setbit(bmp1, i, _getbit(bmp2, i) | _getbit(bmp3, i));
    611 	return bmp1;
    612 }
    613 
    614 /* Logical `eor` of two bitmasks: bmp1 = bmp2 ^ bmp3 */
    615 struct bitmask *bitmask_eor(struct bitmask *bmp1, const struct bitmask *bmp2,
    616 			    const struct bitmask *bmp3)
    617 {
    618 	unsigned int i;
    619 	for (i = 0; i < bmp1->size; i++)
    620 		_setbit(bmp1, i, _getbit(bmp2, i) ^ _getbit(bmp3, i));
    621 	return bmp1;
    622 }
    623 
    624 /*
    625  * Iteration operators
    626  */
    627 
    628 /* Number of lowest set bit (min) */
    629 unsigned int bitmask_first(const struct bitmask *bmp)
    630 {
    631 	return bitmask_next(bmp, 0);
    632 }
    633 
    634 /* Number of next set bit at or above given bit i */
    635 unsigned int bitmask_next(const struct bitmask *bmp, unsigned int i)
    636 {
    637 	unsigned int n;
    638 	for (n = i; n < bmp->size; n++)
    639 		if (_getbit(bmp, n))
    640 			break;
    641 	return n;
    642 }
    643 
    644 /* Absolute position of nth set bit */
    645 unsigned int bitmask_rel_to_abs_pos(const struct bitmask *bmp, unsigned int n)
    646 {
    647 	unsigned int i;
    648 	for (i = 0; i < bmp->size; i++)
    649 		if (_getbit(bmp, i))
    650 			if (n-- == 0)
    651 				break;
    652 	return i;
    653 }
    654 
    655 /* Relative position amongst set bits of bit n */
    656 unsigned int bitmask_abs_to_rel_pos(const struct bitmask *bmp, unsigned int n)
    657 {
    658 	unsigned int i;
    659 	unsigned int w = 0;
    660 
    661 	if (!_getbit(bmp, n))
    662 		return bmp->size;
    663 	/* Add in number bits set before bit n */
    664 	for (i = 0; i < n; i++)
    665 		if (_getbit(bmp, i))
    666 			w++;
    667 	return w;
    668 }
    669 
    670 /* Number of highest set bit (max) */
    671 unsigned int bitmask_last(const struct bitmask *bmp)
    672 {
    673 	unsigned int i;
    674 	unsigned int m = bmp->size;
    675 	for (i = 0; i < bmp->size; i++)
    676 		if (_getbit(bmp, i))
    677 			m = i;
    678 	return m;
    679 }
    680