AudioSystem - switch to a free flag for free clients rather than a queue.
This commit is contained in:
parent
6997970d52
commit
4eff2d8420
|
@ -40,9 +40,7 @@ AudioSystem::AudioSystem(cpu::Processor* processor)
|
||||||
processor_(processor),
|
processor_(processor),
|
||||||
worker_running_(false) {
|
worker_running_(false) {
|
||||||
std::memset(clients_, 0, sizeof(clients_));
|
std::memset(clients_, 0, sizeof(clients_));
|
||||||
for (size_t i = 0; i < kMaximumClientCount; ++i) {
|
|
||||||
unused_clients_.push(i);
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < kMaximumClientCount; ++i) {
|
for (size_t i = 0; i < kMaximumClientCount; ++i) {
|
||||||
client_semaphores_[i] =
|
client_semaphores_[i] =
|
||||||
xe::threading::Semaphore::Create(0, kMaximumQueuedFrames);
|
xe::threading::Semaphore::Create(0, kMaximumQueuedFrames);
|
||||||
|
@ -131,6 +129,17 @@ void AudioSystem::WorkerThreadMain() {
|
||||||
// TODO(benvanik): call module API to kill?
|
// TODO(benvanik): call module API to kill?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AudioSystem::FindFreeClient() {
|
||||||
|
for (int i = 0; i < kMaximumClientCount; i++) {
|
||||||
|
auto& client = clients_[i];
|
||||||
|
if (!client.in_use) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void AudioSystem::Initialize() {}
|
void AudioSystem::Initialize() {}
|
||||||
|
|
||||||
void AudioSystem::Shutdown() {
|
void AudioSystem::Shutdown() {
|
||||||
|
@ -142,10 +151,10 @@ void AudioSystem::Shutdown() {
|
||||||
|
|
||||||
X_STATUS AudioSystem::RegisterClient(uint32_t callback, uint32_t callback_arg,
|
X_STATUS AudioSystem::RegisterClient(uint32_t callback, uint32_t callback_arg,
|
||||||
size_t* out_index) {
|
size_t* out_index) {
|
||||||
assert_true(unused_clients_.size());
|
|
||||||
auto global_lock = global_critical_region_.Acquire();
|
auto global_lock = global_critical_region_.Acquire();
|
||||||
|
|
||||||
auto index = unused_clients_.front();
|
auto index = FindFreeClient();
|
||||||
|
assert_true(index >= 0);
|
||||||
|
|
||||||
auto client_semaphore = client_semaphores_[index].get();
|
auto client_semaphore = client_semaphores_[index].get();
|
||||||
auto ret = client_semaphore->Release(kMaximumQueuedFrames, nullptr);
|
auto ret = client_semaphore->Release(kMaximumQueuedFrames, nullptr);
|
||||||
|
@ -158,12 +167,10 @@ X_STATUS AudioSystem::RegisterClient(uint32_t callback, uint32_t callback_arg,
|
||||||
}
|
}
|
||||||
assert_not_null(driver);
|
assert_not_null(driver);
|
||||||
|
|
||||||
unused_clients_.pop();
|
|
||||||
|
|
||||||
uint32_t ptr = memory()->SystemHeapAlloc(0x4);
|
uint32_t ptr = memory()->SystemHeapAlloc(0x4);
|
||||||
xe::store_and_swap<uint32_t>(memory()->TranslateVirtual(ptr), callback_arg);
|
xe::store_and_swap<uint32_t>(memory()->TranslateVirtual(ptr), callback_arg);
|
||||||
|
|
||||||
clients_[index] = {driver, callback, callback_arg, ptr};
|
clients_[index] = {driver, callback, callback_arg, ptr, true};
|
||||||
|
|
||||||
if (out_index) {
|
if (out_index) {
|
||||||
*out_index = index;
|
*out_index = index;
|
||||||
|
@ -188,7 +195,6 @@ void AudioSystem::UnregisterClient(size_t index) {
|
||||||
assert_true(index < kMaximumClientCount);
|
assert_true(index < kMaximumClientCount);
|
||||||
DestroyDriver(clients_[index].driver);
|
DestroyDriver(clients_[index].driver);
|
||||||
clients_[index] = {0};
|
clients_[index] = {0};
|
||||||
unused_clients_.push(index);
|
|
||||||
|
|
||||||
// Drain the semaphore of its count.
|
// Drain the semaphore of its count.
|
||||||
auto client_semaphore = client_semaphores_[index].get();
|
auto client_semaphore = client_semaphores_[index].get();
|
||||||
|
|
|
@ -72,14 +72,16 @@ class AudioSystem {
|
||||||
uint32_t callback;
|
uint32_t callback;
|
||||||
uint32_t callback_arg;
|
uint32_t callback_arg;
|
||||||
uint32_t wrapped_callback_arg;
|
uint32_t wrapped_callback_arg;
|
||||||
|
bool in_use;
|
||||||
} clients_[kMaximumClientCount];
|
} clients_[kMaximumClientCount];
|
||||||
|
|
||||||
|
int FindFreeClient();
|
||||||
|
|
||||||
std::unique_ptr<xe::threading::Semaphore>
|
std::unique_ptr<xe::threading::Semaphore>
|
||||||
client_semaphores_[kMaximumClientCount];
|
client_semaphores_[kMaximumClientCount];
|
||||||
// Event is always there in case we have no clients.
|
// Event is always there in case we have no clients.
|
||||||
std::unique_ptr<xe::threading::Event> shutdown_event_;
|
std::unique_ptr<xe::threading::Event> shutdown_event_;
|
||||||
xe::threading::WaitHandle* wait_handles_[kMaximumClientCount + 1];
|
xe::threading::WaitHandle* wait_handles_[kMaximumClientCount + 1];
|
||||||
std::queue<size_t> unused_clients_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace apu
|
} // namespace apu
|
||||||
|
|
Loading…
Reference in New Issue