On 26/03/2013, at 2:20 PM, Ken Thomases <[email protected]> wrote:

> I'd define some state values like:
> 
> enum {
>       DATA_LINE_IDLE,
>       DATA_LINE_READ_IN_PROGRESS,
> };
> 
> Initialize the lock with [[NSConditionLock alloc] 
> initWithCondition:DATA_LINE_IDLE];
> 
> Then, when the CPU simulator does a read, it does [lock 
> lockWhenCondition:DATA_LINE_IDLE], it issues the read to the simulation 
> thread (asynchronously), and then does [lock 
> unlockWithCondition:DATA_LINE_READ_IN_PROGRESS].  It then immediately tries 
> to lock it again with [lock lockWhenCondition:DATA_LINE_IDLE], gets the 
> result of the read from some storage somewhere, and unlocks the lock without 
> changing its value with [lock unlock].
> 
> When the simulation thread has completed the read (however you determine 
> that), it should lock the lock unconditionally with [lock lock], store the 
> results where the CPU simulator expects to find them, and unlock it with 
> [lock unlockWithCondition:DATA_LINE_IDLE].
> 
> When a controller thread needs to shut things down, it will have to lock the 
> lock unconditionally with [lock lock].  Then, it sets a flag that the CPU 
> simulator will understand means it needs to exit, and it unlocks the lock 
> with [lock unlockWithCondition:DATA_LINE_IDLE].  That's the condition that 
> the CPU simulator thread is blocked on, so it will wake and check the 
> termination flag, and terminate.


Hmmm, this doesn't seem to work.

I have the following states:

enum
{
        kLOB6502Ready                           = 0,
        kLOB6502Running                 = 1,
        kLOB6502MemoryReadWait  = 2,
        kLOB6502MemoryWriteWait  = 3,
        kLOB6502DataAvailable           = 4
};


The normal running condition is 'running'; when it starts a memory read or 
write request it sets 'readWait' or 'writeWait' (I use separate states so I can 
tune the wait period individually) and when data is available it sets 
'dataAvailable'.


The CPU thread calls this:

- (u_int8_t)    memoryReadAddress:( uint16_t ) address
{
        if( mCPUThreadRunning )
        {
                [mMemoryAccessLock lockWhenCondition:kLOB6502Running];
                
                mAddressValue = address;
                mAsyncAccessCycleCount = 0;

                // flag that the address should be output by the main thread 
here
                
                // block this thread until the data is available
                
                [mMemoryAccessLock unlockWithCondition:kLOB6502MemoryReadWait];
                [mMemoryAccessLock lockWhenCondition:kLOB6502DataAvailable];
                
                // data is available, so set the emulation state and return the 
data
                
                [mMemoryAccessLock unlockWithCondition:kLOB6502Running];
        }
        return mDataValue;
}


And the main simulation thread does this upon data being available, as far as 
it knows:

                        [mMemoryAccessLock lock];
                        
                        // read the data value into mDataValue ivar
                        
                        // free the lock which unblocks the cpu thread which 
grabs the data value
                        
                        [mMemoryAccessLock 
unlockWithCondition:kLOB6502DataAvailable];


This follows your pattern with the exception that the cpu lock is unlocked with 
the 'running' condition, which is the usual condition. (Equivalent to your IDLE 
state). I think I need to do this so that a subsequent call from the cpu to 
acquire the lock checks the 'running' state. If left in the 'data ready' state 
the first lock will block forever.

What is happening is that the cpu thread falls straight through the 
-memoryReadAddress: method without blocking at any point. Shouldn't it block in 
the second call to -lockWhenCondition:? It has just unlocked it in the 'read 
wait' state, so it should not be able to immediately acquire the lock in the 
'data ready' state. That's my rather woolly understanding of how this is meant 
to work.

I can probably eliminate the 'data ready' state as it's redundant and returning 
to the 'running' state should suffice, but nevertheless shouldn't this work? 
Why not? :)

--Graham




_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to