Re: Shape of a knotty(?) threading problem
Re: Shape of a knotty(?) threading problem
- Subject: Re: Shape of a knotty(?) threading problem
- From: Ken Thomases <email@hidden>
- Date: Mon, 25 Mar 2013 22:20:02 -0500
On Mar 25, 2013, at 7:45 PM, Graham Cox wrote:
> So here's what I'm thinking. The simulated cpu can run on its own thread, rather than be locked to the simulation thread. This allows the CPU to run at its own pace and operate in the way it was designed to - in charge of its own destiny. When it needs to perform a memory read or write, the external read/write handlers implement some sort of lock which block the CPU thread and issue the memory address on the simulation thread. The device is then put into a wait state. After some time (this is a bit awkward, I'm not sure how to handle this, there isn't usually a 'data ready' line available in the logic, it might just be a case of counting some arbitrary number of cycles and assuming/stipulating that the data must be ready after a certain number have elapsed - this is analogous to the data setup/settling time allowed in a real hardware system) the data is ready, which satisfies the lock which then unblocks the cpu thread which continues with the returned data exactly at the point it left off. The cpu code is none the wiser, and doesn't need to be refactored so that it implements asynchronous memory access.
Your first task is to figure out how you want to deal with that parenthetical. That sounds like it's wholly within your problem domain and so not something that we can help much with.
> Note that the blocked cpu thread could wait forever. If the simulated cpu device is not connected to any peripheral memory (as it would be when first added to a system) a memory fetch will never complete. That must be allowed - if the device is subsequently deleted, the blocked thread must be killed even though it never ran to completion.
In general, it's not safe to kill threads from outside. Instead, whatever blocking mechanism you choose should have a means of being woken from outside. You then set some state that indicates to the thread that it should exit itself and make sure the thread checks that and does so. Then you set that state and wake the thread.
> So my question is, does this sound like a feasible way to approach this?
Yes.
> If so, what sort of thing is this lock - would NSConditionLock be useful here? Does it do what I'm supposing it does - block one thread until another thread satisfies the condition?
It can work that way. The lock has a state value. The meaning of that value is defined solely by your code. Cocoa doesn't interpret it. A caller can lock the lock unconditionally or it can attempt to lock it only when the state value has some specific value. Whenever a thread which has previously locked the lock unlocks it, it may set a new state value.
Putting those things together, you can achieve "block one thread until another thread satisfies the condition".
> If so, a brief example of its use would be gratefully received. Or some other completely different solution....
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.
And, yes, this is effectively emulating a semaphore.
Regards,
Ken
_______________________________________________
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