summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2020-11-27 14:13:18 -0800
committerGravatar bunnei2020-12-06 00:03:24 -0800
commit8dbfa4e1a4af2cda4500304ba8fe1a1b09bbb814 (patch)
tree98331155b0fbe7c5fcdabde69d4b0419b84cda65 /src
parenthle: kernel: Port KAffinityMask from Mesosphere. (diff)
downloadyuzu-8dbfa4e1a4af2cda4500304ba8fe1a1b09bbb814.tar.gz
yuzu-8dbfa4e1a4af2cda4500304ba8fe1a1b09bbb814.tar.xz
yuzu-8dbfa4e1a4af2cda4500304ba8fe1a1b09bbb814.zip
common: Port BitSet from Mesosphere.
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/bit_set.h100
2 files changed, 101 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 56c7e21f5..fc2ed9999 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -104,6 +104,7 @@ add_library(common STATIC
104 detached_tasks.h 104 detached_tasks.h
105 bit_cast.h 105 bit_cast.h
106 bit_field.h 106 bit_field.h
107 bit_set.h
107 bit_util.h 108 bit_util.h
108 cityhash.cpp 109 cityhash.cpp
109 cityhash.h 110 cityhash.h
diff --git a/src/common/bit_set.h b/src/common/bit_set.h
new file mode 100644
index 000000000..4f966de40
--- /dev/null
+++ b/src/common/bit_set.h
@@ -0,0 +1,100 @@
1/*
2 * Copyright (c) 2018-2020 Atmosphère-NX
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include "common/alignment.h"
20#include "common/bit_util.h"
21#include "common/common_types.h"
22
23namespace Common {
24
25namespace impl {
26
27#define BITSIZEOF(x) (sizeof(x) * CHAR_BIT)
28
29template <typename Storage, size_t N>
30class BitSet {
31private:
32 static_assert(std::is_integral<Storage>::value);
33 static_assert(std::is_unsigned<Storage>::value);
34 static_assert(sizeof(Storage) <= sizeof(u64));
35
36 static constexpr size_t FlagsPerWord = BITSIZEOF(Storage);
37 static constexpr size_t NumWords = AlignUp(N, FlagsPerWord) / FlagsPerWord;
38
39 static constexpr auto CountLeadingZeroImpl(Storage word) {
40 return CountLeadingZeroes64(static_cast<unsigned long long>(word)) -
41 (BITSIZEOF(unsigned long long) - FlagsPerWord);
42 }
43
44 static constexpr Storage GetBitMask(size_t bit) {
45 return Storage(1) << (FlagsPerWord - 1 - bit);
46 }
47
48private:
49 Storage words[NumWords];
50
51public:
52 constexpr BitSet() : words() { /* ... */
53 }
54
55 constexpr void SetBit(size_t i) {
56 this->words[i / FlagsPerWord] |= GetBitMask(i % FlagsPerWord);
57 }
58
59 constexpr void ClearBit(size_t i) {
60 this->words[i / FlagsPerWord] &= ~GetBitMask(i % FlagsPerWord);
61 }
62
63 constexpr size_t CountLeadingZero() const {
64 for (size_t i = 0; i < NumWords; i++) {
65 if (this->words[i]) {
66 return FlagsPerWord * i + CountLeadingZeroImpl(this->words[i]);
67 }
68 }
69 return FlagsPerWord * NumWords;
70 }
71
72 constexpr size_t GetNextSet(size_t n) const {
73 for (size_t i = (n + 1) / FlagsPerWord; i < NumWords; i++) {
74 Storage word = this->words[i];
75 if (!IsAligned(n + 1, FlagsPerWord)) {
76 word &= GetBitMask(n % FlagsPerWord) - 1;
77 }
78 if (word) {
79 return FlagsPerWord * i + CountLeadingZeroImpl(word);
80 }
81 }
82 return FlagsPerWord * NumWords;
83 }
84};
85
86} // namespace impl
87
88template <size_t N>
89using BitSet8 = impl::BitSet<u8, N>;
90
91template <size_t N>
92using BitSet16 = impl::BitSet<u16, N>;
93
94template <size_t N>
95using BitSet32 = impl::BitSet<u32, N>;
96
97template <size_t N>
98using BitSet64 = impl::BitSet<u64, N>;
99
100} // namespace Common