Issuing audio driver callbacks from their own thread.

This commit is contained in:
Ben Vanik 2014-01-12 02:07:17 -08:00
parent 4688d5e600
commit 127595b48a
3 changed files with 18 additions and 2 deletions

View File

@ -11,6 +11,7 @@
#include <xenia/emulator.h>
#include <xenia/cpu/processor.h>
#include <xenia/cpu/xenon_thread_state.h>
#include <xenia/apu/audio_driver.h>
@ -44,6 +45,14 @@ X_STATUS AudioSystem::Setup() {
callbacks.write = (RegisterWriteCallback)WriteRegisterThunk;
emulator_->processor()->AddRegisterAccessCallbacks(callbacks);
// Setup worker thread state. This lets us make calls into guest code.
thread_state_ = new XenonThreadState(
emulator_->processor()->runtime(), 0, 16 * 1024, 0);
thread_state_->set_name("Audio Worker");
thread_block_ = (uint32_t)memory_->HeapAlloc(
0, 2048, alloy::MEMORY_FLAG_ZERO);
thread_state_->context()->r[13] = thread_block_;
// Create worker thread.
// This will initialize the audio system.
// Init needs to happen there so that any thread-local stuff
@ -82,8 +91,8 @@ void AudioSystem::ThreadStart() {
auto clients = clients_;
xe_mutex_unlock(lock_);
for (auto it = clients.begin(); it != clients.end(); ++it) {
processor->ExecuteInterrupt(
0, it->callback, it->wrapped_callback_arg, 0);
processor->Execute(
thread_state_, it->callback, it->wrapped_callback_arg, 0);
}
//worker_->Pump();
Sleep(1000);
@ -110,6 +119,9 @@ void AudioSystem::Shutdown() {
xe_thread_join(thread_);
xe_thread_release(thread_);
delete thread_state_;
memory()->HeapFree(thread_block_, 0);
xe_run_loop_release(run_loop_);
}

View File

@ -16,6 +16,7 @@
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS2(xe, cpu, Processor);
XEDECLARECLASS2(xe, cpu, XenonThreadState);
namespace xe {
@ -72,6 +73,8 @@ protected:
xe_run_loop_ref run_loop_;
xe_thread_ref thread_;
cpu::XenonThreadState* thread_state_;
uint32_t thread_block_;
bool running_;
xe_mutex_t* lock_;

View File

@ -133,6 +133,7 @@ int Processor::Setup() {
interrupt_thread_lock_ = xe_mutex_alloc(10000);
interrupt_thread_state_ = new XenonThreadState(
runtime_, 0, 16 * 1024, 0);
interrupt_thread_state_->set_name("Interrupt");
interrupt_thread_block_ = memory_->HeapAlloc(
0, 2048, MEMORY_FLAG_ZERO);
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;