Re: Shape of a knotty(?) threading problem
Re: Shape of a knotty(?) threading problem
- Subject: Re: Shape of a knotty(?) threading problem
- From: Graham Cox <email@hidden>
- Date: Tue, 26 Mar 2013 15:12:25 +1100
On 26/03/2013, at 2:20 PM, Ken Thomases <email@hidden> 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@hidden)
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:
This email sent to email@hidden