Moving threads to XHostThread and making shutdown not crash.

This commit is contained in:
Ben Vanik
2015-05-19 22:20:49 -07:00
parent 7a82ad839a
commit f88bf33b4f
22 changed files with 175 additions and 138 deletions

View File

@@ -14,8 +14,8 @@
#include "xenia/base/math.h"
#include "xenia/cpu/processor.h"
#include "xenia/cpu/thread_state.h"
#include "xenia/kernel/objects/xthread.h"
#include "xenia/emulator.h"
#include "xenia/kernel/objects/xthread.h"
#include "xenia/profiling.h"
// As with normal Microsoft, there are like twelve different ways to access
@@ -48,7 +48,6 @@ namespace xe {
namespace apu {
using namespace xe::cpu;
using namespace xe::kernel;
// Size of a hardware XMA context.
const uint32_t kXmaContextSize = 64;
@@ -56,7 +55,7 @@ const uint32_t kXmaContextSize = 64;
const uint32_t kXmaContextCount = 320;
AudioSystem::AudioSystem(Emulator* emulator)
: emulator_(emulator), memory_(emulator->memory()), running_(false) {
: emulator_(emulator), memory_(emulator->memory()), worker_running_(false) {
memset(clients_, 0, sizeof(clients_));
for (size_t i = 0; i < maximum_client_count_; ++i) {
unused_clients_.push(i);
@@ -91,22 +90,18 @@ X_STATUS AudioSystem::Setup() {
}
registers_.next_context = 1;
// Setup our worker thread
std::function<int()> thread_fn = [this]() {
this->ThreadStart();
worker_running_ = true;
worker_thread_ = new kernel::XHostThread(emulator()->kernel_state(),
128 * 1024, 0, [this]() {
this->WorkerThreadMain();
return 0;
};
running_ = true;
thread_ = std::make_unique<XHostThread>(emulator()->kernel_state(),
128 * 1024, 0, thread_fn);
thread_->Create();
});
worker_thread_->Create();
return X_STATUS_SUCCESS;
}
void AudioSystem::ThreadStart() {
void AudioSystem::WorkerThreadMain() {
xe::threading::set_name("Audio Worker");
// Initialize driver and ringbuffer.
@@ -115,7 +110,7 @@ void AudioSystem::ThreadStart() {
auto processor = emulator_->processor();
// Main run loop.
while (running_) {
while (worker_running_) {
auto result =
WaitForMultipleObjectsEx(DWORD(xe::countof(client_wait_handles_)),
client_wait_handles_, FALSE, INFINITE, FALSE);
@@ -135,8 +130,8 @@ void AudioSystem::ThreadStart() {
lock_.unlock();
if (client_callback) {
uint64_t args[] = {client_callback_arg};
processor->Execute(thread_->thread_state(), client_callback, args,
xe::countof(args));
processor->Execute(worker_thread_->thread_state(), client_callback,
args, xe::countof(args));
}
pumped++;
index++;
@@ -145,7 +140,7 @@ void AudioSystem::ThreadStart() {
WAIT_OBJECT_0);
}
if (!running_) {
if (!worker_running_) {
break;
}
@@ -154,7 +149,7 @@ void AudioSystem::ThreadStart() {
Sleep(500);
}
}
running_ = false;
worker_running_ = false;
// TODO(benvanik): call module API to kill?
}
@@ -162,9 +157,10 @@ void AudioSystem::ThreadStart() {
void AudioSystem::Initialize() {}
void AudioSystem::Shutdown() {
running_ = false;
ResetEvent(client_wait_handles_[maximum_client_count_]);
thread_->Wait(0, 0, 0, NULL);
worker_running_ = false;
SetEvent(client_wait_handles_[maximum_client_count_]);
worker_thread_->Wait(0, 0, 0, nullptr);
worker_thread_->Release();
memory()->SystemHeapFree(registers_.xma_context_array_ptr);
}

View File

@@ -13,15 +13,17 @@
#include <atomic>
#include <mutex>
#include <queue>
#include <thread>
#include "xenia/emulator.h"
#include "xenia/xbox.h"
namespace xe {
namespace kernel {
class XHostThread;
} // namespace kernel
} // namespace xe
namespace kernel { class XHostThread; }
namespace xe {
namespace apu {
class AudioDriver;
@@ -59,7 +61,7 @@ class AudioSystem {
virtual void Initialize();
private:
void ThreadStart();
void WorkerThreadMain();
static uint64_t MMIOReadRegisterThunk(AudioSystem* as, uint32_t addr) {
return as->ReadRegister(addr);
@@ -76,8 +78,8 @@ class AudioSystem {
Memory* memory_;
cpu::Processor* processor_;
std::unique_ptr<kernel::XHostThread> thread_;
std::atomic<bool> running_;
std::atomic<bool> worker_running_;
kernel::XHostThread* worker_thread_;
std::mutex lock_;