Cocoa Port:
- Reverse locking mechanics for the core emulation loop's producer/consumer threads. (Instead of the producer telling consumers to lock, now consumers check if the producer is locked.) - Add additional error check for the execution state within the core emulation loop. - Reduce spin lock time when setting the GPU state flags. - Improve thread safety when changing the execution state.
This commit is contained in:
parent
0fdb9308c1
commit
7ae952f366
|
@ -465,6 +465,8 @@ static BOOL isCoreStarted = NO;
|
|||
|
||||
- (void) setCoreState:(NSInteger)coreState
|
||||
{
|
||||
pthread_mutex_lock(&threadParam.mutexThreadExecute);
|
||||
|
||||
if (threadParam.state == CORESTATE_PAUSE)
|
||||
{
|
||||
prevCoreState = CORESTATE_PAUSE;
|
||||
|
@ -474,7 +476,6 @@ static BOOL isCoreStarted = NO;
|
|||
prevCoreState = CORESTATE_EXECUTE;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&threadParam.mutexThreadExecute);
|
||||
threadParam.state = coreState;
|
||||
pthread_cond_signal(&threadParam.condThreadExecute);
|
||||
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
|
||||
|
@ -618,6 +619,7 @@ static BOOL isCoreStarted = NO;
|
|||
|
||||
- (void) addOutput:(CocoaDSOutput *)theOutput
|
||||
{
|
||||
theOutput.mutexProducer = self.mutexCoreExecute;
|
||||
[self.cdsOutputList addObject:theOutput];
|
||||
}
|
||||
|
||||
|
@ -673,16 +675,20 @@ void* RunCoreThread(void *arg)
|
|||
// We'll just jump directly to ending the input processing.
|
||||
NDS_endProcessingInput();
|
||||
|
||||
for(CocoaDSOutput *cdsOutput in cdsOutputList)
|
||||
{
|
||||
pthread_mutex_lock(cdsOutput.mutexOutputFrame);
|
||||
}
|
||||
|
||||
// Execute the frame and increment the frame counter.
|
||||
pthread_mutex_lock(param->mutexCoreExecute);
|
||||
NDS_exec<false>();
|
||||
pthread_mutex_unlock(param->mutexCoreExecute);
|
||||
|
||||
// Check if an internal execution error occurred that halted the emulation.
|
||||
if (!execute)
|
||||
{
|
||||
pthread_mutex_unlock(¶m->mutexThreadExecute);
|
||||
// TODO: Message the core that emulation halted.
|
||||
NSLog(@"The emulator halted during execution. Was it an internal error that caused this?");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param->framesToSkip == 0)
|
||||
{
|
||||
param->frameCount++;
|
||||
|
@ -692,12 +698,10 @@ void* RunCoreThread(void *arg)
|
|||
{
|
||||
if (param->framesToSkip > 0 && [cdsOutput isMemberOfClass:[CocoaDSDisplay class]])
|
||||
{
|
||||
pthread_mutex_unlock(cdsOutput.mutexOutputFrame);
|
||||
continue;
|
||||
}
|
||||
|
||||
[cdsOutput doCoreEmuFrame];
|
||||
pthread_mutex_unlock(cdsOutput.mutexOutputFrame);
|
||||
}
|
||||
|
||||
// Determine the number of frames to skip based on how much time "debt"
|
||||
|
|
|
@ -30,14 +30,16 @@
|
|||
NSData *frameData;
|
||||
NSMutableDictionary *property;
|
||||
|
||||
pthread_mutex_t *mutexOutputFrame;
|
||||
pthread_mutex_t *mutexProducer;
|
||||
pthread_mutex_t *mutexConsume;
|
||||
}
|
||||
|
||||
@property (assign) BOOL isStateChanged;
|
||||
@property (assign) NSUInteger frameCount;
|
||||
@property (retain) NSData *frameData;
|
||||
@property (readonly) NSMutableDictionary *property;
|
||||
@property (readonly) pthread_mutex_t *mutexOutputFrame;
|
||||
@property (assign) pthread_mutex_t *mutexProducer;
|
||||
@property (readonly) pthread_mutex_t *mutexConsume;
|
||||
|
||||
- (void) doCoreEmuFrame;
|
||||
- (void) handleEmuFrameProcessed:(NSData *)theData;
|
||||
|
|
|
@ -45,7 +45,8 @@ GPU3DInterface *core3DList[] = {
|
|||
@synthesize frameCount;
|
||||
@synthesize frameData;
|
||||
@synthesize property;
|
||||
@synthesize mutexOutputFrame;
|
||||
@synthesize mutexProducer;
|
||||
@synthesize mutexConsume;
|
||||
|
||||
- (id)init
|
||||
{
|
||||
|
@ -62,8 +63,8 @@ GPU3DInterface *core3DList[] = {
|
|||
property = [[NSMutableDictionary alloc] init];
|
||||
[property setValue:[NSDate date] forKey:@"outputTime"];
|
||||
|
||||
mutexOutputFrame = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(mutexOutputFrame, NULL);
|
||||
mutexConsume = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(mutexConsume, NULL);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -85,9 +86,9 @@ GPU3DInterface *core3DList[] = {
|
|||
self.frameData = nil;
|
||||
[property release];
|
||||
|
||||
pthread_mutex_destroy(mutexOutputFrame);
|
||||
free(mutexOutputFrame);
|
||||
mutexOutputFrame = nil;
|
||||
pthread_mutex_destroy(mutexConsume);
|
||||
free(mutexConsume);
|
||||
mutexConsume = NULL;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -199,7 +200,7 @@ GPU3DInterface *core3DList[] = {
|
|||
[property setValue:[NSNumber numberWithInteger:methodID] forKey:@"audioOutputEngine"];
|
||||
OSSpinLockUnlock(&spinlockAudioOutputEngine);
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
|
||||
NSInteger result = -1;
|
||||
|
||||
|
@ -213,7 +214,7 @@ GPU3DInterface *core3DList[] = {
|
|||
SPU_ChangeSoundCore(SNDCORE_DUMMY, 0);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
|
||||
// Force the volume back to it's original setting.
|
||||
[self setVolume:[self volume]];
|
||||
|
@ -234,9 +235,9 @@ GPU3DInterface *core3DList[] = {
|
|||
[property setValue:[NSNumber numberWithBool:state] forKey:@"spuAdvancedLogic"];
|
||||
OSSpinLockUnlock(&spinlockSpuAdvancedLogic);
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.spu_advanced = state;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (BOOL) spuAdvancedLogic
|
||||
|
@ -254,9 +255,9 @@ GPU3DInterface *core3DList[] = {
|
|||
[property setValue:[NSNumber numberWithInteger:modeID] forKey:@"spuInterpolationMode"];
|
||||
OSSpinLockUnlock(&spinlockSpuInterpolationMode);
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.spuInterpolationMode = (SPUInterpolationMode)modeID;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (NSInteger) spuInterpolationMode
|
||||
|
@ -276,9 +277,9 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
NSInteger methodID = [self spuSyncMethod];
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
SPU_SetSynchMode(modeID, methodID);
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (NSInteger) spuSyncMode
|
||||
|
@ -298,9 +299,9 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
NSInteger modeID = [self spuSyncMode];
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
SPU_SetSynchMode(modeID, methodID);
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (NSInteger) spuSyncMethod
|
||||
|
@ -554,8 +555,10 @@ GPU3DInterface *core3DList[] = {
|
|||
- (void) setGpuStateFlags:(UInt32)flags
|
||||
{
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
|
||||
gpuStateFlags = flags;
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
|
||||
if (flags & GPUSTATE_MAIN_GPU_MASK)
|
||||
{
|
||||
|
@ -689,7 +692,7 @@ GPU3DInterface *core3DList[] = {
|
|||
[property setValue:[NSNumber numberWithBool:NO] forKey:@"gpuStateSubOBJ"];
|
||||
}
|
||||
|
||||
OSSpinLockUnlock(&spinlockGpuState);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (UInt32) gpuStateFlags
|
||||
|
@ -771,9 +774,9 @@ GPU3DInterface *core3DList[] = {
|
|||
[property setValue:[NSNumber numberWithInteger:methodID] forKey:@"render3DRenderingEngine"];
|
||||
OSSpinLockUnlock(&spinlockRender3DRenderingEngine);
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
NDS_3D_ChangeCore(methodID);
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (NSInteger) render3DRenderingEngine
|
||||
|
@ -797,9 +800,9 @@ GPU3DInterface *core3DList[] = {
|
|||
cState = true;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.GFX3D_HighResolutionInterpolateColor = cState;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DHighPrecisionColorInterpolation
|
||||
|
@ -823,9 +826,9 @@ GPU3DInterface *core3DList[] = {
|
|||
cState = true;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.GFX3D_EdgeMark = cState;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DEdgeMarking
|
||||
|
@ -849,9 +852,9 @@ GPU3DInterface *core3DList[] = {
|
|||
cState = true;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.GFX3D_Fog = cState;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DFog
|
||||
|
@ -875,9 +878,9 @@ GPU3DInterface *core3DList[] = {
|
|||
cState = true;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.GFX3D_Texture = cState;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DTextures
|
||||
|
@ -895,9 +898,9 @@ GPU3DInterface *core3DList[] = {
|
|||
[property setValue:[NSNumber numberWithInteger:threshold] forKey:@"render3DDepthComparisonThreshold"];
|
||||
OSSpinLockUnlock(&spinlockRender3DDepthComparisonThreshold);
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.GFX3D_Zelda_Shadow_Depth_Hack = threshold;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (NSUInteger) render3DDepthComparisonThreshold
|
||||
|
@ -936,15 +939,15 @@ GPU3DInterface *core3DList[] = {
|
|||
numberCores = numberThreads;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.num_cores = numberCores;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
|
||||
if ([self render3DRenderingEngine] == CORE3DLIST_SWRASTERIZE)
|
||||
{
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
NDS_3D_ChangeCore(CORE3DLIST_SWRASTERIZE);
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -969,9 +972,9 @@ GPU3DInterface *core3DList[] = {
|
|||
cState = true;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(self.mutexOutputFrame);
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.GFX3D_LineHack = cState;
|
||||
pthread_mutex_unlock(self.mutexOutputFrame);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (BOOL) render3DLineHack
|
||||
|
|
Loading…
Reference in New Issue