mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-06-17 12:29:31 +00:00
Introduce CPU thread function annotation and enforcement
This commit is contained in:
parent
51d2efba03
commit
eb13718c5e
|
@ -1848,7 +1848,7 @@ static void MB_DSUninit()
|
|||
void MB_Initialize()
|
||||
{
|
||||
#if 1 // APPLE2IX
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
memset(SSI263Voice, 0x0, sizeof(AudioBuffer_s *) * 64);
|
||||
#endif
|
||||
LOG("MB_Initialize: g_bDisableDirectSound=%d, g_bDisableDirectSoundMockingboard=%d\n", g_bDisableDirectSound, g_bDisableDirectSoundMockingboard);
|
||||
|
@ -1901,11 +1901,11 @@ void MB_Initialize()
|
|||
#if 1 // APPLE2IX
|
||||
// HACK functions for "soft" destroying backend audio resource (but keeping current state)
|
||||
void MB_SoftDestroy(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
MB_DSUninit();
|
||||
}
|
||||
void MB_SoftInitialize(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
MB_DSInit();
|
||||
}
|
||||
#endif
|
||||
|
@ -1928,7 +1928,7 @@ void MB_Reinitialize()
|
|||
void MB_Destroy()
|
||||
{
|
||||
#if 1 // APPLE2IX
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
#endif
|
||||
MB_DSUninit();
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ static AudioBackend_s *currentBackend = NULL;
|
|||
|
||||
long audio_createSoundBuffer(INOUT AudioBuffer_s **audioBuffer) {
|
||||
// CPU thread owns audio lifecycle (see note above)
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
|
||||
if (!audio_isAvailable) {
|
||||
*audioBuffer = NULL;
|
||||
|
@ -69,7 +69,7 @@ long audio_createSoundBuffer(INOUT AudioBuffer_s **audioBuffer) {
|
|||
|
||||
void audio_destroySoundBuffer(INOUT AudioBuffer_s **audioBuffer) {
|
||||
// CPU thread owns audio lifecycle (see note above)
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
if (audioContext) {
|
||||
audioContext->DestroySoundBuffer(audioContext, audioBuffer);
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ void audio_destroySoundBuffer(INOUT AudioBuffer_s **audioBuffer) {
|
|||
|
||||
bool audio_init(void) {
|
||||
// CPU thread owns audio lifecycle (see note above)
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
if (audio_isAvailable) {
|
||||
return true;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ bool audio_init(void) {
|
|||
|
||||
void audio_shutdown(void) {
|
||||
// CPU thread owns audio lifecycle (see note above)
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
if (!audio_isAvailable) {
|
||||
return;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ void audio_pause(void) {
|
|||
#if TARGET_OS_MAC || TARGET_OS_PHONE
|
||||
# warning FIXME TODO : this assert is firing on iOS port ... but the assert is valid ... fix soon
|
||||
#else
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
#endif
|
||||
if (!audio_isAvailable) {
|
||||
return;
|
||||
|
@ -125,7 +125,7 @@ void audio_pause(void) {
|
|||
|
||||
void audio_resume(void) {
|
||||
// CPU thread owns audio lifecycle (see note above)
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
if (!audio_isAvailable) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -369,7 +369,7 @@ static unsigned long _submit_samples_buffer(const unsigned long num_channel_samp
|
|||
// speaker public API functions
|
||||
|
||||
void speaker_destroy(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
speaker_isAvailable = false;
|
||||
audio_destroySoundBuffer(&speakerBuffer);
|
||||
FREE(samples_buffer);
|
||||
|
@ -377,7 +377,7 @@ void speaker_destroy(void) {
|
|||
}
|
||||
|
||||
void speaker_init(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
|
||||
long err = 0;
|
||||
speaker_isAvailable = false;
|
||||
|
@ -443,7 +443,7 @@ void speaker_flush(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
|
||||
if (is_fullspeed) {
|
||||
cycles_quiet_time = cycles_count_total;
|
||||
|
@ -512,7 +512,7 @@ double speaker_cyclesPerSample(void) {
|
|||
|
||||
GLUE_C_READ(speaker_toggle)
|
||||
{
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
|
||||
timing_checkpoint_cycles();
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
// between speaker and mockingboard
|
||||
#define SPKR_DATA_INIT (SHRT_MAX>>3) // 0x0FFF
|
||||
|
||||
void speaker_init(void);
|
||||
void speaker_destroy(void);
|
||||
void speaker_init(void) CALL_ON_CPU_THREAD;
|
||||
void speaker_destroy(void) CALL_ON_CPU_THREAD;
|
||||
void speaker_reset(void);
|
||||
void speaker_flush(void);
|
||||
void speaker_flush(void) CALL_ON_CPU_THREAD;
|
||||
bool speaker_isActive(void);
|
||||
|
||||
/*
|
||||
|
|
12
src/common.h
12
src/common.h
|
@ -26,6 +26,18 @@
|
|||
#define PUBLIC
|
||||
#define READONLY
|
||||
|
||||
#define CALL_ON_UI_THREAD
|
||||
#define ASSERT_ON_UI_THREAD() \
|
||||
assert(video_isRenderThread())
|
||||
#define ASSERT_NOT_ON_UI_THREAD() \
|
||||
assert(!video_isRenderThread())
|
||||
|
||||
#define CALL_ON_CPU_THREAD
|
||||
#define ASSERT_ON_CPU_THREAD() \
|
||||
assert(timing_isCPUThread())
|
||||
#define ASSERT_NOT_ON_CPU_THREAD() \
|
||||
assert(!timing_isCPUThread())
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
|
|
@ -1185,11 +1185,7 @@ static int begin_cpu_stepping() {
|
|||
------------------------------------------------------------------------- */
|
||||
bool c_debugger_should_break() {
|
||||
|
||||
if (pthread_self() != cpu_thread_id) {
|
||||
// OOPS ...
|
||||
LOG("should only call this from cpu thread, bailing...");
|
||||
assert(false);
|
||||
}
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
|
||||
bool break_stepping = false;
|
||||
if (at_haltpt()) {
|
||||
|
|
18
src/timing.c
18
src/timing.c
|
@ -140,7 +140,7 @@ static
|
|||
#endif
|
||||
void reinitialize(void) {
|
||||
#if !TESTING
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
#endif
|
||||
|
||||
cycles_count_total = 0;
|
||||
|
@ -178,7 +178,7 @@ void timing_toggleCPUSpeed(void) {
|
|||
|
||||
static void timing_reinitializeAudio(void) {
|
||||
SPINLOCK_ACQUIRE(&_pause_spinLock);
|
||||
assert(pthread_self() != cpu_thread_id);
|
||||
ASSERT_NOT_ON_CPU_THREAD();
|
||||
#if !TESTING
|
||||
assert(cpu_isPaused());
|
||||
#endif
|
||||
|
@ -189,7 +189,7 @@ static void timing_reinitializeAudio(void) {
|
|||
}
|
||||
|
||||
void cpu_pause(void) {
|
||||
assert(pthread_self() != cpu_thread_id);
|
||||
ASSERT_NOT_ON_CPU_THREAD();
|
||||
|
||||
SPINLOCK_ACQUIRE(&_pause_spinLock);
|
||||
do {
|
||||
|
@ -209,7 +209,7 @@ void cpu_pause(void) {
|
|||
}
|
||||
|
||||
void cpu_resume(void) {
|
||||
assert(pthread_self() != cpu_thread_id);
|
||||
ASSERT_NOT_ON_CPU_THREAD();
|
||||
|
||||
SPINLOCK_ACQUIRE(&_pause_spinLock);
|
||||
do {
|
||||
|
@ -242,7 +242,7 @@ bool timing_shouldAutoAdjustSpeed(void) {
|
|||
static void *cpu_thread(void *dummyptr) {
|
||||
|
||||
#ifndef NDEBUG // Spamsung Galaxy Y running Gingerbread triggers this, wTf?!
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
#endif
|
||||
|
||||
LOG("cpu_thread : initialized...");
|
||||
|
@ -514,6 +514,10 @@ cpu_runloop:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool timing_isCPUThread(void) {
|
||||
return pthread_self() == cpu_thread_id;
|
||||
}
|
||||
|
||||
void timing_startCPU(void) {
|
||||
cpu_shutting_down = false;
|
||||
int err = TEMP_FAILURE_RETRY(pthread_create(&cpu_thread_id, NULL, (void *)&cpu_thread, (void *)NULL));
|
||||
|
@ -533,7 +537,7 @@ void timing_stopCPU(void) {
|
|||
}
|
||||
|
||||
unsigned int CpuGetCyclesThisVideoFrame(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
|
||||
timing_checkpoint_cycles();
|
||||
return g_dwCyclesThisFrame + cycles_checkpoint_count;
|
||||
|
@ -541,7 +545,7 @@ unsigned int CpuGetCyclesThisVideoFrame(void) {
|
|||
|
||||
// Called when an IO-reg is accessed & accurate global cycle count info is needed
|
||||
void timing_checkpoint_cycles(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_ON_CPU_THREAD();
|
||||
|
||||
const int32_t d = run_args.cpu65_cycle_count - cycles_checkpoint_count;
|
||||
assert(d >= 0);
|
||||
|
|
|
@ -68,6 +68,11 @@ extern READONLY pthread_t cpu_thread_id;
|
|||
struct timespec timespec_diff(struct timespec start, struct timespec end, bool *negative);
|
||||
struct timespec timespec_add(struct timespec start, unsigned long nsecs);
|
||||
|
||||
/*
|
||||
* True if current thread is the CPU thread.
|
||||
*/
|
||||
bool timing_isCPUThread(void);
|
||||
|
||||
/*
|
||||
* start CPU thread
|
||||
*/
|
||||
|
|
|
@ -129,7 +129,7 @@ static inline void _touch_sourceBegin(volatile int *source) {
|
|||
}
|
||||
|
||||
static void touchkpad_keyboardReadCallback(void) {
|
||||
assert(pthread_self() == cpu_thread_id);
|
||||
ASSERT_CALL_ON_CPU_THREAD();
|
||||
|
||||
// HACK FIXME TODO :
|
||||
//
|
||||
|
|
|
@ -28,7 +28,7 @@ static pthread_t render_thread_id = 0;
|
|||
void video_init(void) {
|
||||
video_initialized = true;
|
||||
|
||||
assert(pthread_self() != cpu_thread_id);
|
||||
ASSERT_NOT_ON_CPU_THREAD();
|
||||
LOG("(re)setting render_thread_id : %lu -> %lu", (unsigned long)render_thread_id, (unsigned long)pthread_self());
|
||||
render_thread_id = pthread_self();
|
||||
|
||||
|
@ -58,7 +58,7 @@ void video_shutdown(void) {
|
|||
}
|
||||
|
||||
void video_render(void) {
|
||||
assert(pthread_self() == render_thread_id);
|
||||
ASSERT_ON_UI_THREAD();
|
||||
currentBackend->render();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user