[kernel] Move page mapping into vm_space

vm_space no longer relies on page_manager to map pages during a page
fault. Other changes that come with this commit:

- C++ standard has been changed to C++17
- enum bitfield operators became constexpr
- enum bifrield operators can take a mix of ints and enum arguments
- added page table flags enum instead of relying on ints
- remove page_table::unmap_table and page_table::unmap_pages
This commit is contained in:
2020-09-20 10:52:57 -07:00
parent deb2fa0a09
commit 1b392a0551
7 changed files with 107 additions and 143 deletions

View File

@@ -8,104 +8,130 @@ struct is_enum_bitfield { static constexpr bool value = false; };
#define IS_BITFIELD(name) \
template<> struct ::is_enum_bitfield<name> {static constexpr bool value=true;}
template <typename E>
struct enum_or_int {
static constexpr bool value =
std::disjunction< is_enum_bitfield<E>, std::is_integral<E> >::value;
};
template <typename E, typename F>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type
struct both_enum_or_int {
static constexpr bool value =
std::conjunction< enum_or_int<E>, enum_or_int<F> >::value;
};
template <typename E>
struct integral { using type = typename std::underlying_type<E>::type; };
template <> struct integral<char> { using type = char; };
template <> struct integral<unsigned char> { using type = unsigned char; };
template <> struct integral<short> { using type = short; };
template <> struct integral<unsigned short> { using type = unsigned short; };
template <> struct integral<int> { using type = int; };
template <> struct integral<unsigned int> { using type = unsigned int; };
template <> struct integral<long> { using type = long; };
template <> struct integral<unsigned long> { using type = unsigned long; };
template <> struct integral<long long> { using type = long long; };
template <> struct integral<unsigned long long> { using type = unsigned long long; };
template <typename E, typename F>
constexpr typename std::enable_if<both_enum_or_int<E, F>::value,E>::type
operator & (E lhs, F rhs)
{
return static_cast<E> (
static_cast<typename std::underlying_type<E>::type>(lhs) &
static_cast<typename std::underlying_type<E>::type>(rhs));
static_cast<typename integral<E>::type>(lhs) &
static_cast<typename integral<F>::type>(rhs));
}
template <typename E, typename F>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type
constexpr typename std::enable_if<both_enum_or_int<E, F>::value,E>::type
operator | (E lhs, F rhs)
{
return static_cast<E> (
static_cast<typename std::underlying_type<E>::type>(lhs) |
static_cast<typename std::underlying_type<E>::type>(rhs));
static_cast<typename integral<E>::type>(lhs) |
static_cast<typename integral<F>::type>(rhs));
}
template <typename E, typename F>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type
constexpr typename std::enable_if<both_enum_or_int<E, F>::value,E>::type
operator ^ (E lhs, F rhs)
{
return static_cast<E> (
static_cast<typename std::underlying_type<E>::type>(lhs) ^
static_cast<typename std::underlying_type<E>::type>(rhs));
static_cast<typename integral<E>::type>(lhs) ^
static_cast<typename integral<F>::type>(rhs));
}
template <typename E>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type
constexpr typename std::enable_if<is_enum_bitfield<E>::value,E>::type
operator ~ (E rhs)
{
return static_cast<E>(~static_cast<typename std::underlying_type<E>::type>(rhs));
}
template <typename E, typename F>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type&
constexpr typename std::enable_if<both_enum_or_int<E, F>::value,E>::type&
operator |= (E &lhs, F rhs)
{
lhs = static_cast<E>(
static_cast<typename std::underlying_type<E>::type>(lhs) |
static_cast<typename std::underlying_type<E>::type>(rhs));
static_cast<typename integral<E>::type>(lhs) |
static_cast<typename integral<F>::type>(rhs));
return lhs;
}
template <typename E, typename F>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type&
constexpr typename std::enable_if<both_enum_or_int<E, F>::value,E>::type&
operator &= (E &lhs, F rhs)
{
lhs = static_cast<E>(
static_cast<typename std::underlying_type<E>::type>(lhs) &
static_cast<typename std::underlying_type<E>::type>(rhs));
static_cast<typename integral<E>::type>(lhs) &
static_cast<typename integral<F>::type>(rhs));
return lhs;
}
template <typename E, typename F>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type&
constexpr typename std::enable_if<both_enum_or_int<E, F>::value,E>::type&
operator ^= (E &lhs, F rhs)
{
lhs = static_cast<E>(
static_cast<typename std::underlying_type<E>::type>(lhs) ^
static_cast<typename std::underlying_type<E>::type>(rhs));
static_cast<typename integral<E>::type>(lhs) ^
static_cast<typename integral<F>::type>(rhs));
return lhs;
}
template <typename E, typename F>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type&
constexpr typename std::enable_if<both_enum_or_int<E, F>::value,E>::type&
operator -= (E &lhs, F rhs)
{
lhs = static_cast<E>(
static_cast<typename std::underlying_type<E>::type>(lhs) &
~static_cast<typename std::underlying_type<E>::type>(rhs));
static_cast<typename integral<E>::type>(lhs) &
~static_cast<typename integral<F>::type>(rhs));
return lhs;
}
template <typename E, typename F>
typename std::enable_if<is_enum_bitfield<E>::value,E>::type&
constexpr typename std::enable_if<both_enum_or_int<E, F>::value,E>::type&
operator += (E &lhs, F rhs)
{
lhs = static_cast<E>(
static_cast<typename std::underlying_type<E>::type>(lhs) |
static_cast<typename std::underlying_type<E>::type>(rhs));
static_cast<typename integral<E>::type>(lhs) |
static_cast<typename integral<F>::type>(rhs));
return lhs;
}
template <typename E>
typename std::enable_if<is_enum_bitfield<E>::value,bool>::type
constexpr typename std::enable_if<is_enum_bitfield<E>::value,bool>::type
operator ! (E rhs)
{
return static_cast<typename std::underlying_type<E>::type>(rhs) == 0;
}
template <typename E>
typename std::enable_if<is_enum_bitfield<E>::value,bool>::type
constexpr typename std::enable_if<is_enum_bitfield<E>::value,bool>::type
bitfield_has(E set, E flag)
{
return (set & flag) == flag;
@@ -113,7 +139,7 @@ bitfield_has(E set, E flag)
// Overload the logical-and operator to be 'bitwise-and, bool-cast'
template <typename E>
typename std::enable_if<is_enum_bitfield<E>::value,bool>::type
constexpr typename std::enable_if<is_enum_bitfield<E>::value,bool>::type
operator && (E set, E flag)
{
return (set & flag) == flag;