Skip to content

Commit

Permalink
Protect potential multithreaded code path with mutex
Browse files Browse the repository at this point in the history
Note that the semaphore part is going to change again, so this is a temporary solution
  • Loading branch information
wwylele committed Dec 21, 2018
1 parent 69f7b9a commit e6ea0ea
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/apbp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Apbp::Impl {
u16 semaphore = 0;
u16 semaphore_mask = 0;
bool semaphore_master_signal = false;
mutable std::recursive_mutex semaphore_mutex;
std::function<void()> semaphore_handler;

void Reset() {
Expand Down Expand Up @@ -88,6 +89,7 @@ void Apbp::SetDataHandler(unsigned channel, std::function<void()> handler) {
}

void Apbp::SetSemaphore(u16 bits) {
std::lock_guard lock(impl->semaphore_mutex);
impl->semaphore |= bits;
bool new_signal = (impl->semaphore & ~impl->semaphore_mask) != 0;
if (new_signal && impl->semaphore_handler) {
Expand All @@ -97,27 +99,33 @@ void Apbp::SetSemaphore(u16 bits) {
}

void Apbp::ClearSemaphore(u16 bits) {
std::lock_guard lock(impl->semaphore_mutex);
impl->semaphore &= ~bits;
impl->semaphore_master_signal = (impl->semaphore & ~impl->semaphore_mask) != 0;
}

u16 Apbp::GetSemaphore() const {
std::lock_guard lock(impl->semaphore_mutex);
return impl->semaphore;
}

void Apbp::MaskSemaphore(u16 bits) {
std::lock_guard lock(impl->semaphore_mutex);
impl->semaphore_mask = bits;
}

u16 Apbp::GetSemaphoreMask() const {
std::lock_guard lock(impl->semaphore_mutex);
return impl->semaphore_mask;
}

void Apbp::SetSemaphoreHandler(std::function<void()> handler) {
std::lock_guard lock(impl->semaphore_mutex);
impl->semaphore_handler = std::move(handler);
}

bool Apbp::IsSemaphoreSignaled() const {
std::lock_guard lock(impl->semaphore_mutex);
return impl->semaphore_master_signal;
}
} // namespace Teakra
9 changes: 9 additions & 0 deletions src/icu.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <bitset>
#include <functional>
#include <mutex>
#include <utility>
#include "common_types.h"

Expand All @@ -12,15 +13,18 @@ class ICU {
public:
using IrqBits = std::bitset<16>;
u16 GetRequest() const {
std::lock_guard lock(mutex);
return (u16)request.to_ulong();
}
void Acknowledge(u16 irq_bits) {
std::lock_guard lock(mutex);
request &= ~IrqBits(irq_bits);
}
u16 GetAcknowledge() {
return 0;
}
void Trigger(u16 irq_bits) {
std::lock_guard lock(mutex);
IrqBits bits(irq_bits);
request |= bits;
for (u32 irq = 0; irq < 16; ++irq) {
Expand All @@ -43,15 +47,19 @@ class ICU {
Trigger(1 << irq);
}
void SetEnable(u32 interrupt_index, u16 irq_bits) {
std::lock_guard lock(mutex);
enabled[interrupt_index] = IrqBits(irq_bits);
}
void SetEnableVectored(u16 irq_bits) {
std::lock_guard lock(mutex);
vectored_enabled = IrqBits(irq_bits);
}
u16 GetEnable(u32 interrupt_index) const {
std::lock_guard lock(mutex);
return (u16)enabled[interrupt_index].to_ulong();
}
u16 GetEnableVectored() const {
std::lock_guard lock(mutex);
return (u16)vectored_enabled.to_ulong();
}

Expand All @@ -74,6 +82,7 @@ class ICU {
IrqBits request;
std::array<IrqBits, 3> enabled;
IrqBits vectored_enabled;
mutable std::mutex mutex;
};

} // namespace Teakra

0 comments on commit e6ea0ea

Please sign in to comment.