Introduce CPU thread function annotation and enforcement

This commit is contained in:
Aaron Culliney 2018-03-25 15:54:23 -07:00
parent 51d2efba03
commit eb13718c5e
10 changed files with 49 additions and 32 deletions

View File

@ -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();

View File

@ -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;
}

View File

@ -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();

View File

@ -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);
/*

View File

@ -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

View File

@ -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()) {

View File

@ -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);

View File

@ -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
*/

View File

@ -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 :
//

View File

@ -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();
}