Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

cpumask: add missing files.

This is an addition to commit 9038767.

Signed-off-by: Kir Kolyshkin <kir@openvz.org>
  • Loading branch information...
commit 023c90e5f79c5f6b916406d7976778b0da9711f1 1 parent 4a9cf54
Vladimir Davydov authored kolyshkin committed
Showing with 285 additions and 0 deletions.
  1. +83 −0 include/bitmap.h
  2. +202 −0 src/lib/bitmap.c
View
83 include/bitmap.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010-2011, Parallels, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _BITMAP_H_
+#define _BITMAP_H_
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef DIV_ROUND_UP
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+#endif
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define BITS_PER_BYTE 8
+#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
+
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
+
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+
+static inline unsigned long *alloc_bitmap(int nmaskbits)
+{
+ return malloc(BITS_TO_LONGS(nmaskbits) * sizeof(long));
+}
+
+static inline void bitmap_zero(unsigned long *maskp, int nmaskbits)
+{
+ memset(maskp, 0, BITS_TO_LONGS(nmaskbits) * sizeof(long));
+}
+
+static inline void bitmap_set_all(unsigned long *maskp, int nmaskbits)
+{
+ memset(maskp, -1, BITS_TO_LONGS(nmaskbits) * sizeof(long));
+}
+
+static inline int bitmap_test_bit(int nr, const unsigned long *maskp)
+{
+ return (maskp[BIT_WORD(nr)] & BIT_MASK(nr)) != 0;
+}
+
+static inline void bitmap_set_bit(int nr, unsigned long *maskp)
+{
+ maskp[BIT_WORD(nr)] |= BIT_MASK(nr);
+}
+
+static inline void bitmap_clear_bit(int nr, unsigned long *maskp)
+{
+ maskp[BIT_WORD(nr)] &= ~BIT_MASK(nr);
+}
+
+int bitmap_find_first_bit(const unsigned long *maskp, int nmaskbits);
+int bitmap_find_next_bit(const unsigned long *maskp, int nmaskbits, int offset);
+int bitmap_find_first_zero_bit(const unsigned long *maskp, int nmaskbits);
+int bitmap_find_next_zero_bit(const unsigned long *maskp,
+ int nmaskbits, int offset);
+
+int bitmap_parse(const char *str, unsigned long *maskp, int nmaskbits);
+int bitmap_snprintf(char *buf, unsigned int buflen,
+ const unsigned long *maskp, int nmaskbits);
+
+#endif /* _BITMAP_H_ */
View
202 src/lib/bitmap.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2010-2011, Parallels, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "bitmap.h"
+
+int bitmap_find_first_bit(const unsigned long *maskp, int nmaskbits)
+{
+ int i, n;
+ int nmasklongs = BITS_TO_LONGS(nmaskbits);
+
+ for (i = 0; i < nmasklongs; i++) {
+ if (maskp[i] != 0)
+ break;
+ }
+ if (i == nmasklongs)
+ return nmaskbits;
+ i *= BITS_PER_LONG;
+ n = i + BITS_PER_LONG;
+ n = MIN(n, nmaskbits);
+ do {
+ if (bitmap_test_bit(i, maskp))
+ break;
+ } while (++i < n);
+ return i;
+}
+
+int bitmap_find_next_bit(const unsigned long *maskp, int nmaskbits, int offset)
+{
+ int n;
+
+ if (offset % BITS_PER_LONG != 0) {
+ n = (BIT_WORD(offset) + 1) * BITS_PER_LONG;
+ n = MIN(n, nmaskbits);
+ while (offset < n) {
+ if (bitmap_test_bit(offset, maskp))
+ return offset;
+ offset++;
+ }
+ }
+ if (offset >= nmaskbits)
+ return nmaskbits;
+ return offset + bitmap_find_first_bit(
+ maskp + BIT_WORD(offset), nmaskbits - offset);
+}
+
+int bitmap_find_first_zero_bit(const unsigned long *maskp, int nmaskbits)
+{
+ int i, n;
+ int nmasklongs = BITS_TO_LONGS(nmaskbits);
+
+ for (i = 0; i < nmasklongs; i++) {
+ if (~maskp[i] != 0)
+ break;
+ }
+ if (i == nmasklongs)
+ return nmaskbits;
+ i *= BITS_PER_LONG;
+ n = i + BITS_PER_LONG;
+ n = MIN(n, nmaskbits);
+ do {
+ if (!bitmap_test_bit(i, maskp))
+ break;
+ } while (++i < n);
+ return i;
+}
+
+int bitmap_find_next_zero_bit(const unsigned long *maskp,
+ int nmaskbits, int offset)
+{
+ int n;
+
+ if (offset % BITS_PER_LONG != 0) {
+ n = (BIT_WORD(offset) + 1) * BITS_PER_LONG;
+ n = MIN(n, nmaskbits);
+ while (offset < n) {
+ if (!bitmap_test_bit(offset, maskp))
+ return offset;
+ offset++;
+ }
+ }
+ if (offset >= nmaskbits)
+ return nmaskbits;
+ return offset + bitmap_find_first_zero_bit(
+ maskp + BIT_WORD(offset), nmaskbits - offset);
+}
+
+static inline int parse_range(const char *str, int *a, int *b, char **endptr)
+{
+ if (!isdigit(*str))
+ return -1;
+ *a = *b = strtol(str, endptr, 10);
+ if (**endptr == '-') {
+ str = *endptr + 1;
+ if (!isdigit(*str))
+ return -1;
+ *b = strtol(str, endptr, 10);
+ if (*a > *b)
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * bitmap_parse - parse bitmap stored as a comma-separated list of decimal
+ * numbers and ranges in the string @str and write it to the bitmap @maskp
+ * containing at most @nmaskbits.
+ * A range of bits is shown as two hyphen-separated decimal numbers with
+ * the first number being the smallest and the second one being the largest
+ * bit numbers set in the range.
+ *
+ * Returns 0 on success. On invalid input strings, -1 is returned,
+ * and @errno is set appropriately.
+ * Errors:
+ * %EINVAL: invalid character in string or
+ * second number in range smaller than first
+ * %ERANGE: bit number specified too large for mask
+ */
+int bitmap_parse(const char *str, unsigned long *maskp, int nmaskbits)
+{
+ int a, b;
+ char *endptr;
+
+ bitmap_zero(maskp, nmaskbits);
+ do {
+ if (parse_range(str, &a, &b, &endptr) != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (b >= nmaskbits) {
+ errno = ERANGE;
+ return -1;
+ }
+ for (; a <= b; a++)
+ bitmap_set_bit(a, maskp);
+ if (*endptr == ',')
+ endptr++;
+ str = endptr;
+ } while (*str != '\0');
+ return 0;
+}
+
+static inline int print_range(char *buf, unsigned int buflen, int a, int b)
+{
+ if (a == b)
+ return snprintf(buf, buflen, "%d", a);
+ return snprintf(buf, buflen, "%d-%d", a, b);
+}
+
+/**
+ * bitmap_snprintf - convert bitmap to string.
+ * @buf: buffer to store string
+ * @buflen: size of @buf, in bytes
+ * @maskp: bitmap to convert
+ * @nmaskbits: size of bitmap, in bits
+ *
+ * For description of output format, see bitmap_parse().
+ *
+ * Returns the number of characters printed, excluding the trailing '\0'.
+ * If the output was truncated due to the limit on the size of @buf than
+ * the return value is the number of characters which would have been written
+ * to the final string if enough space had been available.
+ */
+int bitmap_snprintf(char *buf, unsigned int buflen,
+ const unsigned long *maskp, int nmaskbits)
+{
+ int a, b;
+ unsigned int len = 0;
+
+ if (buflen > 0)
+ buf[0] = '\0';
+ a = bitmap_find_first_bit(maskp, nmaskbits);
+ while (a < nmaskbits) {
+ b = bitmap_find_next_zero_bit(maskp, nmaskbits, a + 1) - 1;
+ if (len > 0)
+ len += snprintf(buf + len,
+ buflen > len ? buflen - len : 0, ",");
+ len += print_range(buf + len,
+ buflen > len ? buflen - len : 0, a, b);
+ a = bitmap_find_next_bit(maskp, nmaskbits, b + 1);
+ }
+ return len;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.