rpcsx/rpcs3/Emu/Memory/vm_var.h
Nekotekina 5e14310071 noexcept usage fixed
thread_t renamed to named_thread_t
2015-08-24 21:22:48 +03:00

124 lines
2.4 KiB
C++

#pragma once
class CPUThread;
namespace vm
{
template<typename T> class page_alloc_t
{
u32 m_addr;
void dealloc()
{
if (m_addr)
{
vm::dealloc_verbose_nothrow(m_addr);
}
}
public:
page_alloc_t()
: m_addr(0)
{
}
page_alloc_t(vm::memory_location_t location, u32 count = 1)
: m_addr(vm::alloc(sizeof32(T) * count, location, std::max<u32>(alignof32(T), 4096)))
{
}
page_alloc_t(const page_alloc_t&) = delete;
page_alloc_t(page_alloc_t&& other)
: m_addr(other.m_addr)
{
other.m_addr = 0;
}
~page_alloc_t()
{
this->dealloc();
}
page_alloc_t& operator =(const page_alloc_t&) = delete;
page_alloc_t& operator =(page_alloc_t&& other)
{
std::swap(m_addr, other.m_addr);
return *this;
}
u32 get_addr() const
{
return m_addr;
}
};
template<typename T> class stack_alloc_t
{
u32 m_addr;
u32 m_old_pos; // TODO: use the stack to save it?
CPUThread& m_thread;
public:
stack_alloc_t() = delete;
stack_alloc_t(CPUThread& thread, u32 count = 1)
: m_addr(vm::stack_push(thread, sizeof32(T) * count, alignof32(T), m_old_pos))
, m_thread(thread)
{
}
~stack_alloc_t() noexcept(false) // allow exceptions
{
if (!std::uncaught_exception()) // don't call during stack unwinding (it's pointless anyway)
{
vm::stack_pop(m_thread, m_addr, m_old_pos);
}
}
stack_alloc_t(const stack_alloc_t&) = delete;
stack_alloc_t(stack_alloc_t&&) = delete;
stack_alloc_t& operator =(const stack_alloc_t&) = delete;
stack_alloc_t& operator =(stack_alloc_t&&) = delete;
u32 get_addr() const
{
return m_addr;
}
};
template<typename T, template<typename> class A> class _var_base final : public _ptr_base<T>, private A<T>
{
using _ptr_base<T>::m_addr;
using allocation = A<T>;
public:
template<typename... Args, typename = std::enable_if_t<std::is_constructible<A<T>, Args...>::value>> _var_base(Args&&... args)
: allocation(std::forward<Args>(args)...)
{
m_addr = allocation::get_addr();
}
};
template<typename T, template<typename> class A = vm::stack_alloc_t> using varl = _var_base<to_le_t<T>, A>;
template<typename T, template<typename> class A = vm::stack_alloc_t> using varb = _var_base<to_be_t<T>, A>;
namespace ps3
{
template<typename T, template<typename> class A = vm::stack_alloc_t> using var = varb<T, A>;
}
namespace psv
{
template<typename T, template<typename> class A = vm::stack_alloc_t> using var = varl<T, A>;
}
}