noexcept usage fixed

thread_t renamed to named_thread_t
This commit is contained in:
Nekotekina 2015-08-19 14:04:58 +03:00
parent 168cd9bb7a
commit 5e14310071
26 changed files with 82 additions and 96 deletions

View File

@ -64,7 +64,7 @@ namespace fs
struct file final
{
using handle_type = intptr_t;
using handle_type = std::intptr_t;
static const handle_type null = -1;

View File

@ -2,11 +2,6 @@
#include <emmintrin.h>
// temporarily (until noexcept is available); use `noexcept(true)` instead of `noexcept` if necessary
#if defined(_MSC_VER) && _MSC_VER <= 1800
#define noexcept _NOEXCEPT_OP
#endif
#if defined(_MSC_VER) && _MSC_VER <= 1800
#define thread_local __declspec(thread)
#elif __APPLE__

View File

@ -48,7 +48,7 @@ sleep_queue_entry_t::sleep_queue_entry_t(CPUThread& cpu, sleep_queue_t& queue, c
cpu.sleep();
}
sleep_queue_entry_t::~sleep_queue_entry_t() noexcept(false)
sleep_queue_entry_t::~sleep_queue_entry_t()
{
remove_entry();
m_thread.awake();

View File

@ -24,7 +24,7 @@ public:
sleep_queue_entry_t(CPUThread& cpu, sleep_queue_t& queue, const defer_sleep_t&);
// removes specified thread from the sleep queue if added
~sleep_queue_entry_t() noexcept(false);
~sleep_queue_entry_t();
// add thread to the sleep queue
inline void enter()

View File

@ -1199,20 +1199,21 @@ std::string thread_ctrl_t::get_name() const
return name();
}
thread_t::thread_t(std::function<std::string()> name, std::function<void()> func)
named_thread_t::named_thread_t(std::function<std::string()> name, std::function<void()> func)
{
start(std::move(name), func);
}
thread_t::~thread_t() //noexcept(false)
named_thread_t::~named_thread_t()
{
if (m_thread)
{
throw EXCEPTION("Neither joined nor detached");
std::printf("Fatal: thread '%s' is neither joined nor detached\n", this->get_name().c_str());
std::terminate();
}
}
std::string thread_t::get_name() const
std::string named_thread_t::get_name() const
{
if (!m_thread)
{
@ -1229,7 +1230,7 @@ std::string thread_t::get_name() const
std::atomic<u32> g_thread_count{ 0 };
void thread_t::start(std::function<std::string()> name, std::function<void()> func)
void named_thread_t::start(std::function<std::string()> name, std::function<void()> func)
{
if (m_thread)
{
@ -1302,7 +1303,7 @@ void thread_t::start(std::function<std::string()> name, std::function<void()> fu
}, m_thread, std::move(func));
}
void thread_t::detach()
void named_thread_t::detach()
{
if (!m_thread)
{
@ -1324,7 +1325,7 @@ void thread_t::detach()
ctrl->m_thread.detach();
}
void thread_t::join()
void named_thread_t::join()
{
if (!m_thread)
{
@ -1349,7 +1350,7 @@ void thread_t::join()
ctrl->m_thread.join();
}
bool thread_t::is_current() const
bool named_thread_t::is_current() const
{
if (!m_thread)
{

View File

@ -5,7 +5,7 @@ const class thread_ctrl_t* get_current_thread_ctrl();
// named thread control class
class thread_ctrl_t final
{
friend class thread_t;
friend class named_thread_t;
// thread handler
std::thread m_thread;
@ -23,7 +23,7 @@ public:
std::string get_name() const;
};
class thread_t
class named_thread_t
{
// pointer to managed resource (shared with actual thread)
std::shared_ptr<thread_ctrl_t> m_thread;
@ -37,17 +37,17 @@ public:
public:
// initialize in empty state
thread_t() = default;
named_thread_t() = default;
// create named thread
thread_t(std::function<std::string()> name, std::function<void()> func);
named_thread_t(std::function<std::string()> name, std::function<void()> func);
// destructor, joins automatically (questionable, don't rely on this functionality in derived destructors)
virtual ~thread_t() /*noexcept(false) compile error on osx*/;
// destructor, will terminate if thread is neither joined nor detached
virtual ~named_thread_t();
thread_t(const thread_t&) = delete;
named_thread_t(const named_thread_t&) = delete;
thread_t& operator =(const thread_t&) = delete;
named_thread_t& operator =(const named_thread_t&) = delete;
public:
// get thread name
@ -72,11 +72,11 @@ public:
const thread_ctrl_t* get_thread_ctrl() const { return m_thread.get(); }
};
class autojoin_thread_t final : private thread_t
class autojoin_thread_t final : private named_thread_t
{
public:
using thread_t::mutex;
using thread_t::cv;
using named_thread_t::mutex;
using named_thread_t::cv;
public:
autojoin_thread_t() = delete;
@ -91,7 +91,7 @@ public:
join();
}
using thread_t::is_current;
using named_thread_t::is_current;
};
extern const std::function<bool()> SQUEUE_ALWAYS_EXIT;

View File

@ -141,7 +141,7 @@ void ARMv7Thread::close_stack()
{
if (stack_addr)
{
vm::dealloc(stack_addr, vm::main);
vm::dealloc_verbose_nothrow(stack_addr, vm::main);
stack_addr = 0;
}
}

View File

@ -71,11 +71,6 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function<
CPUThread::~CPUThread()
{
if (joinable())
{
throw EXCEPTION("Thread not joined");
}
SendDbgCommand(DID_REMOVE_THREAD, this);
}

View File

@ -36,14 +36,14 @@ class CPUThreadExit {};
class CPUDecoder;
class CPUThread : public thread_t, public std::enable_shared_from_this<CPUThread>
class CPUThread : public named_thread_t, public std::enable_shared_from_this<CPUThread>
{
using thread_t::start;
using named_thread_t::start;
protected:
using thread_t::detach;
using thread_t::join;
using thread_t::joinable;
using named_thread_t::detach;
using named_thread_t::join;
using named_thread_t::joinable;
atomic_t<u64> m_state; // thread state flags

View File

@ -1003,7 +1003,7 @@ namespace ppu_recompiler_llvm {
* It then builds them asynchroneously and update the executable mapping
* using atomic based locks to avoid undefined behavior.
**/
class RecompilationEngine final : protected thread_t {
class RecompilationEngine final : protected named_thread_t {
friend class CPUHybridDecoderRecompiler;
public:
virtual ~RecompilationEngine() override;

View File

@ -139,7 +139,7 @@ void PPUThread::close_stack()
{
if (stack_addr)
{
vm::dealloc(stack_addr, vm::stack);
vm::dealloc_verbose_nothrow(stack_addr, vm::stack);
stack_addr = 0;
}
}

View File

@ -21,10 +21,8 @@ RawSPUThread::~RawSPUThread()
{
join();
if (!vm::dealloc(offset))
{
throw EXCEPTION("Failed to deallocate RawSPU local storage");
}
// Deallocate Local Storage
vm::dealloc_verbose_nothrow(offset);
}
bool RawSPUThread::read_reg(const u32 addr, u32& value)

View File

@ -106,14 +106,8 @@ SPUThread::~SPUThread()
{
join();
if (!vm::dealloc(offset, vm::main))
{
throw EXCEPTION("Failed to deallocate SPU local storage");
}
}
else if (joinable())
{
throw EXCEPTION("Thread not joined");
// Deallocate Local Storage
vm::dealloc_verbose_nothrow(offset, vm::main);
}
}

View File

@ -154,7 +154,7 @@ namespace vm
std::mutex g_waiter_list_mutex;
waiter_t* _add_waiter(thread_t& thread, u32 addr, u32 size)
waiter_t* _add_waiter(named_thread_t& thread, u32 addr, u32 size)
{
std::lock_guard<std::mutex> lock(g_waiter_list_mutex);
@ -248,7 +248,7 @@ namespace vm
return true;
}
waiter_lock_t::waiter_lock_t(thread_t& thread, u32 addr, u32 size)
waiter_lock_t::waiter_lock_t(named_thread_t& thread, u32 addr, u32 size)
: m_waiter(_add_waiter(thread, addr, size))
, m_lock(thread.mutex, std::adopt_lock) // must be locked in _add_waiter
{
@ -346,7 +346,7 @@ namespace vm
void start()
{
// start notification thread
thread_t(COPY_EXPR("vm::start thread"), []()
named_thread_t(COPY_EXPR("vm::start thread"), []()
{
while (!Emu.IsStopped())
{
@ -766,6 +766,23 @@ namespace vm
return block->dealloc(addr);
}
void dealloc_verbose_nothrow(u32 addr, memory_location_t location) noexcept
{
const auto block = get(location, addr);
if (!block)
{
LOG_ERROR(MEMORY, "%s(): invalid memory location (%d, addr=0x%x)\n", __func__, location, addr);
return;
}
if (!block->dealloc(addr))
{
LOG_ERROR(MEMORY, "%s(): deallocation failed (addr=0x%x)\n", __func__, addr);
return;
}
}
bool block_t::try_alloc(u32 addr, u32 size)
{
// check if memory area is already mapped

View File

@ -4,7 +4,7 @@
const class thread_ctrl_t* get_current_thread_ctrl();
class thread_t;
class named_thread_t;
namespace vm
{
@ -38,13 +38,13 @@ namespace vm
{
u32 addr = 0;
u32 mask = ~0;
thread_t* thread = nullptr;
named_thread_t* thread = nullptr;
std::function<bool()> pred;
waiter_t() = default;
waiter_t* reset(u32 addr, u32 size, thread_t& thread)
waiter_t* reset(u32 addr, u32 size, named_thread_t& thread)
{
this->addr = addr;
this->mask = ~(size - 1);
@ -70,7 +70,7 @@ namespace vm
public:
waiter_lock_t() = delete;
waiter_lock_t(thread_t& thread, u32 addr, u32 size);
waiter_lock_t(named_thread_t& thread, u32 addr, u32 size);
waiter_t* operator ->() const
{
@ -83,7 +83,7 @@ namespace vm
};
// wait until pred() returns true, addr must be aligned to size which must be a power of 2, pred() may be called by any thread
template<typename F, typename... Args> auto wait_op(thread_t& thread, u32 addr, u32 size, F pred, Args&&... args) -> decltype(static_cast<void>(pred(args...)))
template<typename F, typename... Args> auto wait_op(named_thread_t& thread, u32 addr, u32 size, F pred, Args&&... args) -> decltype(static_cast<void>(pred(args...)))
{
// return immediately if condition passed (optimistic case)
if (pred(args...)) return;
@ -149,6 +149,9 @@ namespace vm
// Unmap memory at specified address (in optionally specified memory location)
bool dealloc(u32 addr, memory_location_t location = any);
// dealloc() with no return value and no exceptions
void dealloc_verbose_nothrow(u32 addr, memory_location_t location = any) noexcept;
// Object that handles memory allocations inside specific constant bounds ("location"), currently non-virtual
class block_t final
{

View File

@ -10,12 +10,9 @@ namespace vm
void dealloc()
{
if (m_addr && !vm::dealloc(m_addr))
if (m_addr)
{
if (!std::uncaught_exception()) // don't throw during stack unwinding
{
throw EXCEPTION("Deallocation failed (addr=0x%x)", m_addr);
}
vm::dealloc_verbose_nothrow(m_addr);
}
}
@ -26,7 +23,7 @@ namespace vm
}
page_alloc_t(vm::memory_location_t location, u32 count = 1)
: m_addr(alloc(sizeof32(T) * count, location, std::max<u32>(alignof32(T), 4096)))
: m_addr(vm::alloc(sizeof32(T) * count, location, std::max<u32>(alignof32(T), 4096)))
{
}
@ -38,7 +35,7 @@ namespace vm
other.m_addr = 0;
}
~page_alloc_t() noexcept(false) // allow exceptions
~page_alloc_t()
{
this->dealloc();
}
@ -61,7 +58,7 @@ namespace vm
template<typename T> class stack_alloc_t
{
u32 m_addr;
u32 m_old_pos;
u32 m_old_pos; // TODO: use the stack to save it?
CPUThread& m_thread;
@ -69,9 +66,9 @@ namespace vm
stack_alloc_t() = delete;
stack_alloc_t(CPUThread& thread, u32 count = 1)
: m_thread(thread)
: m_addr(vm::stack_push(thread, sizeof32(T) * count, alignof32(T), m_old_pos))
, m_thread(thread)
{
m_addr = vm::stack_push(thread, sizeof32(T) * count, alignof32(T), m_old_pos);
}
~stack_alloc_t() noexcept(false) // allow exceptions

View File

@ -794,11 +794,6 @@ GLGSRender::GLGSRender()
GLGSRender::~GLGSRender()
{
if (joinable())
{
throw EXCEPTION("Thread not joined");
}
m_frame->Close();
m_frame->DeleteContext(m_context);
}

View File

@ -5,10 +5,6 @@ struct GSRender : public RSXThread
{
virtual ~GSRender() override
{
if (joinable())
{
throw EXCEPTION("Thread not joined");
}
}
virtual void Close()=0;

View File

@ -11,10 +11,6 @@ public:
virtual ~NullGSRender() override
{
if (joinable())
{
throw EXCEPTION("Thread not joined");
}
}
private:

View File

@ -90,7 +90,7 @@ struct RSXTransformConstant
}
};
class RSXThread : protected thread_t
class RSXThread : protected named_thread_t
{
public:
static const uint m_textures_count = 16;
@ -551,10 +551,6 @@ protected:
virtual ~RSXThread() override
{
if (joinable())
{
throw EXCEPTION("Thread not joined");
}
}
void Reset()

View File

@ -124,7 +124,7 @@ struct AudioPortConfig
struct AudioConfig final // custom structure
{
atomic_t<AudioState> state;
thread_t thread;
named_thread_t thread;
AudioPortConfig ports[AUDIO_PORT_COUNT];
u32 buffer; // 1 MB memory for audio ports

View File

@ -928,7 +928,7 @@ s32 cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, fs_aio_cb_t func)
const s32 xid = (*id = ++g_fs_aio_id);
thread_t(WRAP_EXPR("FS AIO Read Thread"), [=]{ fsAio(aio, false, xid, func); }).detach();
named_thread_t(WRAP_EXPR("FS AIO Read Thread"), [=]{ fsAio(aio, false, xid, func); }).detach();
return CELL_OK;
}
@ -941,7 +941,7 @@ s32 cellFsAioWrite(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, fs_aio_cb_t func)
const s32 xid = (*id = ++g_fs_aio_id);
thread_t(WRAP_EXPR("FS AIO Write Thread"), [=]{ fsAio(aio, true, xid, func); }).detach();
named_thread_t(WRAP_EXPR("FS AIO Write Thread"), [=]{ fsAio(aio, true, xid, func); }).detach();
return CELL_OK;
}

View File

@ -146,7 +146,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
}
thread_t(WRAP_EXPR("MsgDialog Thread"), [=]()
named_thread_t(WRAP_EXPR("MsgDialog Thread"), [=]()
{
while (g_msg_dialog->state == msgDialogOpen || (s64)(get_system_time() - g_msg_dialog->wait_until) < 0)
{

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Utilities/Log.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
@ -30,7 +31,7 @@ u32 ppu_get_tls(u32 thread)
{
g_tls_size = Emu.GetTLSMemsz() + TLS_SYS;
g_tls_start = vm::alloc(g_tls_size * TLS_MAX, vm::main); // memory for up to TLS_MAX threads
sysPrxForUser.Notice("Thread Local Storage initialized (g_tls_start=0x%x, user_size=0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x",
LOG_NOTICE(MEMORY, "Thread Local Storage initialized (g_tls_start=0x%x, user_size=0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x",
g_tls_start, Emu.GetTLSMemsz(), Emu.GetTLSAddr(), Emu.GetTLSFilesz());
}
@ -73,6 +74,8 @@ void ppu_free_tls(u32 thread)
return;
}
}
LOG_ERROR(MEMORY, "TLS deallocation failed (thread=0x%x)", thread);
}
s64 sys_time_get_system_time()

View File

@ -184,7 +184,7 @@ struct lv2_file_t
u64 st_trans_rate;
bool st_copyless;
thread_t st_thread;
named_thread_t st_thread;
u32 st_buffer;
u64 st_read_size;

View File

@ -31,7 +31,7 @@ struct lv2_timer_t final
std::atomic<u32> state; // timer state
thread_t thread; // timer thread
named_thread_t thread; // timer thread
lv2_timer_t();
~lv2_timer_t();