summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/bit_field.h12
-rw-r--r--src/common/bit_util.h39
-rw-r--r--src/common/common_types.h7
-rw-r--r--src/common/multi_level_queue.h337
-rw-r--r--src/common/page_table.cpp2
-rw-r--r--src/common/page_table.h6
-rw-r--r--src/common/swap.h174
-rw-r--r--src/common/thread_queue_list.h6
-rw-r--r--src/common/uint128.cpp4
-rw-r--r--src/common/uint128.h5
11 files changed, 547 insertions, 46 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 43ae8a9e7..850ce8006 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -98,6 +98,7 @@ add_library(common STATIC
microprofile.h
microprofileui.h
misc.cpp
+ multi_level_queue.h
page_table.cpp
page_table.h
param_package.cpp
diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index 7433c39ba..902e668e3 100644
--- a/src/common/bit_field.h
+++ b/src/common/bit_field.h
@@ -34,6 +34,7 @@
#include <limits>
#include <type_traits>
#include "common/common_funcs.h"
+#include "common/swap.h"
/*
* Abstract bitfield class
@@ -108,7 +109,7 @@
* symptoms.
*/
#pragma pack(1)
-template <std::size_t Position, std::size_t Bits, typename T>
+template <std::size_t Position, std::size_t Bits, typename T, typename EndianTag = LETag>
struct BitField {
private:
// UnderlyingType is T for non-enum types and the underlying type of T if
@@ -121,6 +122,8 @@ private:
// We store the value as the unsigned type to avoid undefined behaviour on value shifting
using StorageType = std::make_unsigned_t<UnderlyingType>;
+ using StorageTypeWithEndian = typename AddEndian<StorageType, EndianTag>::type;
+
public:
/// Constants to allow limited introspection of fields if needed
static constexpr std::size_t position = Position;
@@ -170,7 +173,7 @@ public:
}
constexpr FORCE_INLINE void Assign(const T& value) {
- storage = (storage & ~mask) | FormatValue(value);
+ storage = (static_cast<StorageType>(storage) & ~mask) | FormatValue(value);
}
constexpr T Value() const {
@@ -182,7 +185,7 @@ public:
}
private:
- StorageType storage;
+ StorageTypeWithEndian storage;
static_assert(bits + position <= 8 * sizeof(T), "Bitfield out of range");
@@ -193,3 +196,6 @@ private:
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable in a BitField");
};
#pragma pack()
+
+template <std::size_t Position, std::size_t Bits, typename T>
+using BitFieldBE = BitField<Position, Bits, T, BETag>;
diff --git a/src/common/bit_util.h b/src/common/bit_util.h
index 1eea17ba1..a4f9ed4aa 100644
--- a/src/common/bit_util.h
+++ b/src/common/bit_util.h
@@ -58,4 +58,43 @@ inline u64 CountLeadingZeroes64(u64 value) {
return __builtin_clzll(value);
}
#endif
+
+#ifdef _MSC_VER
+inline u32 CountTrailingZeroes32(u32 value) {
+ unsigned long trailing_zero = 0;
+
+ if (_BitScanForward(&trailing_zero, value) != 0) {
+ return trailing_zero;
+ }
+
+ return 32;
+}
+
+inline u64 CountTrailingZeroes64(u64 value) {
+ unsigned long trailing_zero = 0;
+
+ if (_BitScanForward64(&trailing_zero, value) != 0) {
+ return trailing_zero;
+ }
+
+ return 64;
+}
+#else
+inline u32 CountTrailingZeroes32(u32 value) {
+ if (value == 0) {
+ return 32;
+ }
+
+ return __builtin_ctz(value);
+}
+
+inline u64 CountTrailingZeroes64(u64 value) {
+ if (value == 0) {
+ return 64;
+ }
+
+ return __builtin_ctzll(value);
+}
+#endif
+
} // namespace Common
diff --git a/src/common/common_types.h b/src/common/common_types.h
index 6b1766dca..4cec89fbd 100644
--- a/src/common/common_types.h
+++ b/src/common/common_types.h
@@ -40,10 +40,9 @@ using s64 = std::int64_t; ///< 64-bit signed int
using f32 = float; ///< 32-bit floating point
using f64 = double; ///< 64-bit floating point
-// TODO: It would be nice to eventually replace these with strong types that prevent accidental
-// conversion between each other.
-using VAddr = u64; ///< Represents a pointer in the userspace virtual address space.
-using PAddr = u64; ///< Represents a pointer in the ARM11 physical address space.
+using VAddr = u64; ///< Represents a pointer in the userspace virtual address space.
+using PAddr = u64; ///< Represents a pointer in the ARM11 physical address space.
+using GPUVAddr = u64; ///< Represents a pointer in the GPU virtual address space.
using u128 = std::array<std::uint64_t, 2>;
static_assert(sizeof(u128) == 16, "u128 must be 128 bits wide");
diff --git a/src/common/multi_level_queue.h b/src/common/multi_level_queue.h
new file mode 100644
index 000000000..2b61b91e0
--- /dev/null
+++ b/src/common/multi_level_queue.h
@@ -0,0 +1,337 @@
+// Copyright 2019 TuxSH
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <iterator>
+#include <list>
+#include <utility>
+
+#include "common/bit_util.h"
+#include "common/common_types.h"
+
+namespace Common {
+
+/**
+ * A MultiLevelQueue is a type of priority queue which has the following characteristics:
+ * - iteratable through each of its elements.
+ * - back can be obtained.
+ * - O(1) add, lookup (both front and back)
+ * - discrete priorities and a max of 64 priorities (limited domain)
+ * This type of priority queue is normaly used for managing threads within an scheduler
+ */
+template <typename T, std::size_t Depth>
+class MultiLevelQueue {
+public:
+ using value_type = T;
+ using reference = value_type&;
+ using const_reference = const value_type&;
+ using pointer = value_type*;
+ using const_pointer = const value_type*;
+
+ using difference_type = typename std::pointer_traits<pointer>::difference_type;
+ using size_type = std::size_t;
+
+ template <bool is_constant>
+ class iterator_impl {
+ public:
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = T;
+ using pointer = std::conditional_t<is_constant, T*, const T*>;
+ using reference = std::conditional_t<is_constant, const T&, T&>;
+ using difference_type = typename std::pointer_traits<pointer>::difference_type;
+
+ friend bool operator==(const iterator_impl& lhs, const iterator_impl& rhs) {
+ if (lhs.IsEnd() && rhs.IsEnd())
+ return true;
+ return std::tie(lhs.current_priority, lhs.it) == std::tie(rhs.current_priority, rhs.it);
+ }
+
+ friend bool operator!=(const iterator_impl& lhs, const iterator_impl& rhs) {
+ return !operator==(lhs, rhs);
+ }
+
+ reference operator*() const {
+ return *it;
+ }
+
+ pointer operator->() const {
+ return it.operator->();
+ }
+
+ iterator_impl& operator++() {
+ if (IsEnd()) {
+ return *this;
+ }
+
+ ++it;
+
+ if (it == GetEndItForPrio()) {
+ u64 prios = mlq.used_priorities;
+ prios &= ~((1ULL << (current_priority + 1)) - 1);
+ if (prios == 0) {
+ current_priority = mlq.depth();
+ } else {
+ current_priority = CountTrailingZeroes64(prios);
+ it = GetBeginItForPrio();
+ }
+ }
+ return *this;
+ }
+
+ iterator_impl& operator--() {
+ if (IsEnd()) {
+ if (mlq.used_priorities != 0) {
+ current_priority = 63 - CountLeadingZeroes64(mlq.used_priorities);
+ it = GetEndItForPrio();
+ --it;
+ }
+ } else if (it == GetBeginItForPrio()) {
+ u64 prios = mlq.used_priorities;
+ prios &= (1ULL << current_priority) - 1;
+ if (prios != 0) {
+ current_priority = CountTrailingZeroes64(prios);
+ it = GetEndItForPrio();
+ --it;
+ }
+ } else {
+ --it;
+ }
+ return *this;
+ }
+
+ iterator_impl operator++(int) {
+ const iterator_impl v{*this};
+ ++(*this);
+ return v;
+ }
+
+ iterator_impl operator--(int) {
+ const iterator_impl v{*this};
+ --(*this);
+ return v;
+ }
+
+ // allow implicit const->non-const
+ iterator_impl(const iterator_impl<false>& other)
+ : mlq(other.mlq), it(other.it), current_priority(other.current_priority) {}
+
+ iterator_impl(const iterator_impl<true>& other)
+ : mlq(other.mlq), it(other.it), current_priority(other.current_priority) {}
+
+ iterator_impl& operator=(const iterator_impl<false>& other) {
+ mlq = other.mlq;
+ it = other.it;
+ current_priority = other.current_priority;
+ return *this;
+ }
+
+ friend class iterator_impl<true>;
+ iterator_impl() = default;
+
+ private:
+ friend class MultiLevelQueue;
+ using container_ref =
+ std::conditional_t<is_constant, const MultiLevelQueue&, MultiLevelQueue&>;
+ using list_iterator = std::conditional_t<is_constant, typename std::list<T>::const_iterator,
+ typename std::list<T>::iterator>;
+
+ explicit iterator_impl(container_ref mlq, list_iterator it, u32 current_priority)
+ : mlq(mlq), it(it), current_priority(current_priority) {}
+ explicit iterator_impl(container_ref mlq, u32 current_priority)
+ : mlq(mlq), it(), current_priority(current_priority) {}
+
+ bool IsEnd() const {
+ return current_priority == mlq.depth();
+ }
+
+ list_iterator GetBeginItForPrio() const {
+ return mlq.levels[current_priority].begin();
+ }
+
+ list_iterator GetEndItForPrio() const {
+ return mlq.levels[current_priority].end();
+ }
+
+ container_ref mlq;
+ list_iterator it;
+ u32 current_priority;
+ };
+
+ using iterator = iterator_impl<false>;
+ using const_iterator = iterator_impl<true>;
+
+ void add(const T& element, u32 priority, bool send_back = true) {
+ if (send_back)
+ levels[priority].push_back(element);
+ else
+ levels[priority].push_front(element);
+ used_priorities |= 1ULL << priority;
+ }
+
+ void remove(const T& element, u32 priority) {
+ auto it = ListIterateTo(levels[priority], element);
+ if (it == levels[priority].end())
+ return;
+ levels[priority].erase(it);
+ if (levels[priority].empty()) {
+ used_priorities &= ~(1ULL << priority);
+ }
+ }
+
+ void adjust(const T& element, u32 old_priority, u32 new_priority, bool adjust_front = false) {
+ remove(element, old_priority);
+ add(element, new_priority, !adjust_front);
+ }
+ void adjust(const_iterator it, u32 old_priority, u32 new_priority, bool adjust_front = false) {
+ adjust(*it, old_priority, new_priority, adjust_front);
+ }
+
+ void transfer_to_front(const T& element, u32 priority, MultiLevelQueue& other) {
+ ListSplice(other.levels[priority], other.levels[priority].begin(), levels[priority],
+ ListIterateTo(levels[priority], element));
+
+ other.used_priorities |= 1ULL << priority;
+
+ if (levels[priority].empty()) {
+ used_priorities &= ~(1ULL << priority);
+ }
+ }
+
+ void transfer_to_front(const_iterator it, u32 priority, MultiLevelQueue& other) {
+ transfer_to_front(*it, priority, other);
+ }
+
+ void transfer_to_back(const T& element, u32 priority, MultiLevelQueue& other) {
+ ListSplice(other.levels[priority], other.levels[priority].end(), levels[priority],
+ ListIterateTo(levels[priority], element));
+
+ other.used_priorities |= 1ULL << priority;
+
+ if (levels[priority].empty()) {
+ used_priorities &= ~(1ULL << priority);
+ }
+ }
+
+ void transfer_to_back(const_iterator it, u32 priority, MultiLevelQueue& other) {
+ transfer_to_back(*it, priority, other);
+ }
+
+ void yield(u32 priority, std::size_t n = 1) {
+ ListShiftForward(levels[priority], n);
+ }
+
+ std::size_t depth() const {
+ return Depth;
+ }
+
+ std::size_t size(u32 priority) const {
+ return levels[priority].size();
+ }
+
+ std::size_t size() const {
+ u64 priorities = used_priorities;
+ std::size_t size = 0;
+ while (priorities != 0) {
+ const u64 current_priority = CountTrailingZeroes64(priorities);
+ size += levels[current_priority].size();
+ priorities &= ~(1ULL << current_priority);
+ }
+ return size;
+ }
+
+ bool empty() const {
+ return used_priorities == 0;
+ }
+
+ bool empty(u32 priority) const {
+ return (used_priorities & (1ULL << priority)) == 0;
+ }
+
+ u32 highest_priority_set(u32 max_priority = 0) const {
+ const u64 priorities =
+ max_priority == 0 ? used_priorities : (used_priorities & ~((1ULL << max_priority) - 1));
+ return priorities == 0 ? Depth : static_cast<u32>(CountTrailingZeroes64(priorities));
+ }
+
+ u32 lowest_priority_set(u32 min_priority = Depth - 1) const {
+ const u64 priorities = min_priority >= Depth - 1
+ ? used_priorities
+ : (used_priorities & ((1ULL << (min_priority + 1)) - 1));
+ return priorities == 0 ? Depth : 63 - CountLeadingZeroes64(priorities);
+ }
+
+ const_iterator cbegin(u32 max_prio = 0) const {
+ const u32 priority = highest_priority_set(max_prio);
+ return priority == Depth ? cend()
+ : const_iterator{*this, levels[priority].cbegin(), priority};
+ }
+ const_iterator begin(u32 max_prio = 0) const {
+ return cbegin(max_prio);
+ }
+ iterator begin(u32 max_prio = 0) {
+ const u32 priority = highest_priority_set(max_prio);
+ return priority == Depth ? end() : iterator{*this, levels[priority].begin(), priority};
+ }
+
+ const_iterator cend(u32 min_prio = Depth - 1) const {
+ return min_prio == Depth - 1 ? const_iterator{*this, Depth} : cbegin(min_prio + 1);
+ }
+ const_iterator end(u32 min_prio = Depth - 1) const {
+ return cend(min_prio);
+ }
+ iterator end(u32 min_prio = Depth - 1) {
+ return min_prio == Depth - 1 ? iterator{*this, Depth} : begin(min_prio + 1);
+ }
+
+ T& front(u32 max_priority = 0) {
+ const u32 priority = highest_priority_set(max_priority);
+ return levels[priority == Depth ? 0 : priority].front();
+ }
+ const T& front(u32 max_priority = 0) const {
+ const u32 priority = highest_priority_set(max_priority);
+ return levels[priority == Depth ? 0 : priority].front();
+ }
+
+ T back(u32 min_priority = Depth - 1) {
+ const u32 priority = lowest_priority_set(min_priority); // intended
+ return levels[priority == Depth ? 63 : priority].back();
+ }
+ const T& back(u32 min_priority = Depth - 1) const {
+ const u32 priority = lowest_priority_set(min_priority); // intended
+ return levels[priority == Depth ? 63 : priority].back();
+ }
+
+private:
+ using const_list_iterator = typename std::list<T>::const_iterator;
+
+ static void ListShiftForward(std::list<T>& list, const std::size_t shift = 1) {
+ if (shift >= list.size()) {
+ return;
+ }
+
+ const auto begin_range = list.begin();
+ const auto end_range = std::next(begin_range, shift);
+ list.splice(list.end(), list, begin_range, end_range);
+ }
+
+ static void ListSplice(std::list<T>& in_list, const_list_iterator position,
+ std::list<T>& out_list, const_list_iterator element) {
+ in_list.splice(position, out_list, element);
+ }
+
+ static const_list_iterator ListIterateTo(const std::list<T>& list, const T& element) {
+ auto it = list.cbegin();
+ while (it != list.cend() && *it != element) {
+ ++it;
+ }
+ return it;
+ }
+
+ std::array<std::list<T>, Depth> levels;
+ u64 used_priorities = 0;
+};
+
+} // namespace Common
diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp
index 8eba1c3f1..69b7abc54 100644
--- a/src/common/page_table.cpp
+++ b/src/common/page_table.cpp
@@ -16,6 +16,7 @@ void PageTable::Resize(std::size_t address_space_width_in_bits) {
pointers.resize(num_page_table_entries);
attributes.resize(num_page_table_entries);
+ backing_addr.resize(num_page_table_entries);
// The default is a 39-bit address space, which causes an initial 1GB allocation size. If the
// vector size is subsequently decreased (via resize), the vector might not automatically
@@ -24,6 +25,7 @@ void PageTable::Resize(std::size_t address_space_width_in_bits) {
pointers.shrink_to_fit();
attributes.shrink_to_fit();
+ backing_addr.shrink_to_fit();
}
} // namespace Common
diff --git a/src/common/page_table.h b/src/common/page_table.h
index 8339f2890..8b8ff0bb8 100644
--- a/src/common/page_table.h
+++ b/src/common/page_table.h
@@ -21,6 +21,8 @@ enum class PageType : u8 {
RasterizerCachedMemory,
/// Page is mapped to a I/O region. Writing and reading to this page is handled by functions.
Special,
+ /// Page is allocated for use.
+ Allocated,
};
struct SpecialRegion {
@@ -66,7 +68,7 @@ struct PageTable {
* Contains MMIO handlers that back memory regions whose entries in the `attribute` vector is
* of type `Special`.
*/
- boost::icl::interval_map<VAddr, std::set<SpecialRegion>> special_regions;
+ boost::icl::interval_map<u64, std::set<SpecialRegion>> special_regions;
/**
* Vector of fine grained page attributes. If it is set to any value other than `Memory`, then
@@ -74,6 +76,8 @@ struct PageTable {
*/
std::vector<PageType> attributes;
+ std::vector<u64> backing_addr;
+
const std::size_t page_size_in_bits{};
};
diff --git a/src/common/swap.h b/src/common/swap.h
index 0e219747f..b3eab1324 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -17,6 +17,8 @@
#pragma once
+#include <type_traits>
+
#if defined(_MSC_VER)
#include <cstdlib>
#elif defined(__linux__)
@@ -170,7 +172,7 @@ struct swap_struct_t {
using swapped_t = swap_struct_t;
protected:
- T value = T();
+ T value;
static T swap(T v) {
return F::swap(v);
@@ -605,52 +607,154 @@ struct swap_double_t {
}
};
-#if COMMON_LITTLE_ENDIAN
-using u16_le = u16;
-using u32_le = u32;
-using u64_le = u64;
+template <typename T>
+struct swap_enum_t {
+ static_assert(std::is_enum_v<T>);
+ using base = std::underlying_type_t<T>;
+
+public:
+ swap_enum_t() = default;
+ swap_enum_t(const T& v) : value(swap(v)) {}
+
+ swap_enum_t& operator=(const T& v) {
+ value = swap(v);
+ return *this;
+ }
+
+ operator T() const {
+ return swap(value);
+ }
+
+ explicit operator base() const {
+ return static_cast<base>(swap(value));
+ }
-using s16_le = s16;
-using s32_le = s32;
-using s64_le = s64;
+protected:
+ T value{};
+ // clang-format off
+ using swap_t = std::conditional_t<
+ std::is_same_v<base, u16>, swap_16_t<u16>, std::conditional_t<
+ std::is_same_v<base, s16>, swap_16_t<s16>, std::conditional_t<
+ std::is_same_v<base, u32>, swap_32_t<u32>, std::conditional_t<
+ std::is_same_v<base, s32>, swap_32_t<s32>, std::conditional_t<
+ std::is_same_v<base, u64>, swap_64_t<u64>, std::conditional_t<
+ std::is_same_v<base, s64>, swap_64_t<s64>, void>>>>>>;
+ // clang-format on
+ static T swap(T x) {
+ return static_cast<T>(swap_t::swap(static_cast<base>(x)));
+ }
+};
-using float_le = float;
-using double_le = double;
+struct SwapTag {}; // Use the different endianness from the system
+struct KeepTag {}; // Use the same endianness as the system
-using u64_be = swap_struct_t<u64, swap_64_t<u64>>;
-using s64_be = swap_struct_t<s64, swap_64_t<s64>>;
+template <typename T, typename Tag>
+struct AddEndian;
-using u32_be = swap_struct_t<u32, swap_32_t<u32>>;
-using s32_be = swap_struct_t<s32, swap_32_t<s32>>;
+// KeepTag specializations
-using u16_be = swap_struct_t<u16, swap_16_t<u16>>;
-using s16_be = swap_struct_t<s16, swap_16_t<s16>>;
+template <typename T>
+struct AddEndian<T, KeepTag> {
+ using type = T;
+};
-using float_be = swap_struct_t<float, swap_float_t<float>>;
-using double_be = swap_struct_t<double, swap_double_t<double>>;
-#else
+// SwapTag specializations
+
+template <>
+struct AddEndian<u8, SwapTag> {
+ using type = u8;
+};
+
+template <>
+struct AddEndian<u16, SwapTag> {
+ using type = swap_struct_t<u16, swap_16_t<u16>>;
+};
+
+template <>
+struct AddEndian<u32, SwapTag> {
+ using type = swap_struct_t<u32, swap_32_t<u32>>;
+};
-using u64_le = swap_struct_t<u64, swap_64_t<u64>>;
-using s64_le = swap_struct_t<s64, swap_64_t<s64>>;
+template <>
+struct AddEndian<u64, SwapTag> {
+ using type = swap_struct_t<u64, swap_64_t<u64>>;
+};
+
+template <>
+struct AddEndian<s8, SwapTag> {
+ using type = s8;
+};
-using u32_le = swap_struct_t<u32, swap_32_t<u32>>;
-using s32_le = swap_struct_t<s32, swap_32_t<s32>>;
+template <>
+struct AddEndian<s16, SwapTag> {
+ using type = swap_struct_t<s16, swap_16_t<s16>>;
+};
-using u16_le = swap_struct_t<u16, swap_16_t<u16>>;
-using s16_le = swap_struct_t<s16, swap_16_t<s16>>;
+template <>
+struct AddEndian<s32, SwapTag> {
+ using type = swap_struct_t<s32, swap_32_t<s32>>;
+};
+
+template <>
+struct AddEndian<s64, SwapTag> {
+ using type = swap_struct_t<s64, swap_64_t<s64>>;
+};
+
+template <>
+struct AddEndian<float, SwapTag> {
+ using type = swap_struct_t<float, swap_float_t<float>>;
+};
+
+template <>
+struct AddEndian<double, SwapTag> {
+ using type = swap_struct_t<double, swap_double_t<double>>;
+};
+
+template <typename T>
+struct AddEndian<T, SwapTag> {
+ static_assert(std::is_enum_v<T>);
+ using type = swap_enum_t<T>;
+};
-using float_le = swap_struct_t<float, swap_float_t<float>>;
-using double_le = swap_struct_t<double, swap_double_t<double>>;
+// Alias LETag/BETag as KeepTag/SwapTag depending on the system
+#if COMMON_LITTLE_ENDIAN
-using u16_be = u16;
-using u32_be = u32;
-using u64_be = u64;
+using LETag = KeepTag;
+using BETag = SwapTag;
-using s16_be = s16;
-using s32_be = s32;
-using s64_be = s64;
+#else
-using float_be = float;
-using double_be = double;
+using BETag = KeepTag;
+using LETag = SwapTag;
#endif
+
+// Aliases for LE types
+using u16_le = AddEndian<u16, LETag>::type;
+using u32_le = AddEndian<u32, LETag>::type;
+using u64_le = AddEndian<u64, LETag>::type;
+
+using s16_le = AddEndian<s16, LETag>::type;
+using s32_le = AddEndian<s32, LETag>::type;
+using s64_le = AddEndian<s64, LETag>::type;
+
+template <typename T>
+using enum_le = std::enable_if_t<std::is_enum_v<T>, typename AddEndian<T, LETag>::type>;
+
+using float_le = AddEndian<float, LETag>::type;
+using double_le = AddEndian<double, LETag>::type;
+
+// Aliases for BE types
+using u16_be = AddEndian<u16, BETag>::type;
+using u32_be = AddEndian<u32, BETag>::type;
+using u64_be = AddEndian<u64, BETag>::type;
+
+using s16_be = AddEndian<s16, BETag>::type;
+using s32_be = AddEndian<s32, BETag>::type;
+using s64_be = AddEndian<s64, BETag>::type;
+
+template <typename T>
+using enum_be = std::enable_if_t<std::is_enum_v<T>, typename AddEndian<T, BETag>::type>;
+
+using float_be = AddEndian<float, BETag>::type;
+using double_be = AddEndian<double, BETag>::type;
diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h
index e7594db68..791f99a8c 100644
--- a/src/common/thread_queue_list.h
+++ b/src/common/thread_queue_list.h
@@ -6,7 +6,6 @@
#include <array>
#include <deque>
-#include <boost/range/algorithm_ext/erase.hpp>
namespace Common {
@@ -111,8 +110,9 @@ struct ThreadQueueList {
}
void remove(Priority priority, const T& thread_id) {
- Queue* cur = &queues[priority];
- boost::remove_erase(cur->data, thread_id);
+ Queue* const cur = &queues[priority];
+ const auto iter = std::remove(cur->data.begin(), cur->data.end(), thread_id);
+ cur->data.erase(iter, cur->data.end());
}
void rotate(Priority priority) {
diff --git a/src/common/uint128.cpp b/src/common/uint128.cpp
index 2238a52c5..32bf56730 100644
--- a/src/common/uint128.cpp
+++ b/src/common/uint128.cpp
@@ -1,3 +1,7 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
#ifdef _MSC_VER
#include <intrin.h>
diff --git a/src/common/uint128.h b/src/common/uint128.h
index 52e6b46eb..a3be2a2cb 100644
--- a/src/common/uint128.h
+++ b/src/common/uint128.h
@@ -1,3 +1,8 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
#include <utility>
#include "common/common_types.h"