From 149c82a8ec8b1faed2ae722852042ba9d603b552 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Thu, 3 Oct 2013 04:27:49 +0200 Subject: [PATCH] kernel/util: Add bitmap implementation --- headers/private/kernel/util/BitUtils.h | 18 ++++++ headers/private/kernel/util/Bitmap.h | 81 ++++++++++++++++++++++++++ src/system/kernel/util/Bitmap.cpp | 68 +++++++++++++++++++++ src/system/kernel/util/Jamfile | 1 + 4 files changed, 168 insertions(+) create mode 100644 headers/private/kernel/util/Bitmap.h create mode 100644 src/system/kernel/util/Bitmap.cpp diff --git a/headers/private/kernel/util/BitUtils.h b/headers/private/kernel/util/BitUtils.h index 60cbcb0a0a..1a0e08dc61 100644 --- a/headers/private/kernel/util/BitUtils.h +++ b/headers/private/kernel/util/BitUtils.h @@ -38,5 +38,23 @@ countSetBits(uint32 v) } +static inline uint32 +log2(uint32 v) +{ + static const int MultiplyDeBruijnBitPosition[32] = { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; + + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + + return MultiplyDeBruijnBitPosition[(uint32)(v * 0x07C4ACDDU) >> 27]; +} + + #endif // KERNEL_UTIL_RANDOM_H diff --git a/headers/private/kernel/util/Bitmap.h b/headers/private/kernel/util/Bitmap.h new file mode 100644 index 0000000000..b47854cc61 --- /dev/null +++ b/headers/private/kernel/util/Bitmap.h @@ -0,0 +1,81 @@ +/* + * Copyright 2013 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ +#ifndef KERNEL_UTIL_BITMAP_H +#define KERNEL_UTIL_BITMAP_H + + +#include +#include + + +class Bitmap { +public: + Bitmap(int bitCount); + ~Bitmap(); + + inline status_t GetInitStatus(); + + inline bool Get(int index) const; + inline void Set(int index); + inline void Clear(int index); + + int GetHighestSet() const; + +private: + status_t fInitStatus; + + int fElementsCount; + int fSize; + addr_t* fBits; + + static const int kBitsPerElement; +}; + + +status_t +Bitmap::GetInitStatus() +{ + return fInitStatus; +} + + +bool +Bitmap::Get(int index) const +{ + ASSERT(index < fSize); + + const int kArrayElement = index / kBitsPerElement; + const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement); + return fBits[kArrayElement] & kBitMask; +} + + +void +Bitmap::Set(int index) +{ + ASSERT(index < fSize); + + const int kArrayElement = index / kBitsPerElement; + const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement); + fBits[kArrayElement] |= kBitMask; +} + + +void +Bitmap::Clear(int index) +{ + ASSERT(index < fSize); + + const int kArrayElement = index / kBitsPerElement; + const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement); + fBits[kArrayElement] &= ~addr_t(kBitMask); +} + + +#endif // KERNEL_UTIL_BITMAP_H + diff --git a/src/system/kernel/util/Bitmap.cpp b/src/system/kernel/util/Bitmap.cpp new file mode 100644 index 0000000000..588e996006 --- /dev/null +++ b/src/system/kernel/util/Bitmap.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2013 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ + + +#include + +#include + +#include + +#include + + +const int Bitmap::kBitsPerElement = sizeof(addr_t) * 8; + + +Bitmap::Bitmap(int bitCount) + : + fInitStatus(B_OK), + fElementsCount(0), + fSize(bitCount) +{ + int count = fSize + kBitsPerElement - 1; + count /= kBitsPerElement; + + fBits = new(std::nothrow) addr_t[count]; + if (fBits == NULL) { + fSize = 0; + fInitStatus = B_NO_MEMORY; + } + + fElementsCount = count; + memset(fBits, 0, sizeof(addr_t) * count); +} + + +Bitmap::~Bitmap() +{ + delete[] fBits; +} + + +int +Bitmap::GetHighestSet() const +{ + int i = fElementsCount - 1; + while (i >= 0 && fBits[i] == 0) + i--; + + if (i < 0) + return -1; + + STATIC_ASSERT(sizeof(addr_t) == sizeof(uint64) + || sizeof(addr_t) == sizeof(uint32)); + if (sizeof(addr_t) == sizeof(uint32)) + return log2(fBits[i]) + i * kBitsPerElement; + + uint32 v = fBits[i] >> 32; + if (v != 0) + return log2(v) + sizeof(uint32) * 8 + i * kBitsPerElement; + return log2(fBits[i]) + i * kBitsPerElement; +} + diff --git a/src/system/kernel/util/Jamfile b/src/system/kernel/util/Jamfile index a8f49b9d2a..6b89e4121c 100644 --- a/src/system/kernel/util/Jamfile +++ b/src/system/kernel/util/Jamfile @@ -4,6 +4,7 @@ UsePrivateHeaders [ FDirName kernel util ] ; KernelMergeObject kernel_util.o : AVLTreeBase.cpp + Bitmap.cpp hostname.cpp inet_addr.c inet_ntop.c