diff options
author | Richard Braun <rbraun@sceen.net> | 2014-05-05 21:49:58 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2014-05-05 21:49:58 +0200 |
commit | d8580cf84d3040956bdf8d799b02ad060b144ed9 (patch) | |
tree | d6c32f02a56a99617f5b98a99165076cc3dcc4f3 | |
parent | a67386802e26cd9ea613bf5bdf385f5b3d3645ea (diff) |
kern/bitmap: add cmp/and/or/xor operations
-rw-r--r-- | kern/bitmap.c | 37 | ||||
-rw-r--r-- | kern/bitmap.h | 35 |
2 files changed, 71 insertions, 1 deletions
diff --git a/kern/bitmap.c b/kern/bitmap.c index c2a4cbf8..af19805f 100644 --- a/kern/bitmap.c +++ b/kern/bitmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Richard Braun. + * Copyright (c) 2013-2014 Richard Braun. * * 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 @@ -18,6 +18,41 @@ #include <kern/bitmap.h> #include <kern/bitmap_i.h> #include <kern/limits.h> +#include <kern/string.h> + +int +bitmap_cmp(const unsigned long *a, const unsigned long *b, int nr_bits) +{ + unsigned long last_a, last_b, mask; + int n, rv; + + n = BITMAP_LONGS(nr_bits) - 1; + + if (n != 0) { + rv = memcmp(a, b, n * sizeof(unsigned long)); + + if (rv != 0) + return rv; + + nr_bits -= n * LONG_BIT; + } + + last_a = a[n]; + last_b = b[n]; + + if (nr_bits != LONG_BIT) { + mask = (1UL << nr_bits) - 1; + last_a &= mask; + last_b &= mask; + } + + if (last_a == last_b) + return 0; + else if (last_a < last_b) + return -1; + else + return 1; +} static inline unsigned long bitmap_find_next_compute_complement(unsigned long word, int nr_bits) diff --git a/kern/bitmap.h b/kern/bitmap.h index 28e51c35..8c5980a1 100644 --- a/kern/bitmap.h +++ b/kern/bitmap.h @@ -31,6 +31,8 @@ #define BITMAP_DECLARE(name, nr_bits) unsigned long name[BITMAP_LONGS(nr_bits)] +int bitmap_cmp(const unsigned long *a, const unsigned long *b, int nr_bits); + static inline void bitmap_zero(unsigned long *bm, int nr_bits) { @@ -103,6 +105,39 @@ bitmap_test(const unsigned long *bm, int bit) return ((*bm & bitmap_mask(bit)) != 0); } +static inline void +bitmap_and(unsigned long *a, const unsigned long *b, int nr_bits) +{ + int i, n; + + n = BITMAP_LONGS(nr_bits); + + for (i = 0; i < n; i++) + a[i] &= b[i]; +} + +static inline void +bitmap_or(unsigned long *a, const unsigned long *b, int nr_bits) +{ + int i, n; + + n = BITMAP_LONGS(nr_bits); + + for (i = 0; i < n; i++) + a[i] |= b[i]; +} + +static inline void +bitmap_xor(unsigned long *a, const unsigned long *b, int nr_bits) +{ + int i, n; + + n = BITMAP_LONGS(nr_bits); + + for (i = 0; i < n; i++) + a[i] ^= b[i]; +} + static inline int bitmap_find_next(const unsigned long *bm, int nr_bits, int bit) { |