Stoping Running SPIN to allow 8 PASM COGs
Brian Fairchild
Posts: 549
I'm not going to be near any real hardware for a few days to try but will this code snippet allow me to end up with 8 COGs all running PASM...
coginit(1,@cog1_pasm,0)
coginit(2,@cog2_pasm,0)
coginit(3,@cog3_pasm,0)
coginit(4,@cog4_pasm,0)
coginit(5,@cog5_pasm,0)
coginit(6,@cog6_pasm,0)
coginit(7,@cog7_pasm,0)
coginit(0,@cog0_pasm,0)
...where "cogx_pasm" points to my pasm code?
I'm just not sure about that last line. I know it's going to overwrite the running SPIN interpreter but is it a 'clean' switch over to the running PASM?
coginit(1,@cog1_pasm,0)
coginit(2,@cog2_pasm,0)
coginit(3,@cog3_pasm,0)
coginit(4,@cog4_pasm,0)
coginit(5,@cog5_pasm,0)
coginit(6,@cog6_pasm,0)
coginit(7,@cog7_pasm,0)
coginit(0,@cog0_pasm,0)
...where "cogx_pasm" points to my pasm code?
I'm just not sure about that last line. I know it's going to overwrite the running SPIN interpreter but is it a 'clean' switch over to the running PASM?
Comments
Assuming you start from reset or otherwise know that you are running on cog 0.
Otherwise I would get the ID of the cog running this code with "cogid". Then start the 7 cogs that are not this one with the PASM routines. Finally restart the current cog with:
cogint (cogid, @whatever_pasm, 0)
That's assuming you are not fussy about which cog runs which PASM routine. I believe there are cases where you might want to be fussy, and you would have to orchestrate things a bit more carefully there.
What you have there might fail on any of those cognew statements if there are already cogs running.
I was hinting at the general case where you don't know which cog you are or what is running on other cogs and you just want to trash them all for your new code.
That is probably not required though.
@Mark_T - I was thinking "why stop the cogs first?", then I realized that if you don't stop them first then there's a risk releasing the locks will cause something bad to happen.
-Phil
So the challenge comes down to:
How can you reliably stop all COG except your self and be sure all locks are released. So that you can safely start with a clean slate?
This is a generalized problem that may be relevant if you are part of some OS and you have no knowledge of what the current application is doing with the COGs.
Of course it could that the COGs you are trying to kill off are also wanting to take the entire machine including you!
What we have here is a modern day "core wars" but this time with real cores.
Another way is to launch all the cogs you can, to take up the free COG slots, then alternately kill the other running COGs and launch a replacement in it's place. Eventually you will force out the running COGs even if they aren't playing nice. Then you can reinit the locks and set a "start/continue" flag for the COGs.
Since there is no way to send "signals" to the COGs, you have to rely on them checking flags periodically.
In the face of malicious code running in the cogs there is no way to do this reliably unless there is a special "master cog" with extra hardware protection. Which there is not.
-Phil
Being fast in PASM does not help. How do you know the malicious code is not also fast?
Doing cogstop many times does not help. How do you know the malicious code is not doing that as well.
In fact as you are running trying to be the master cog and shut everyone else down you have to consider that whatever you do the maliciois code might also be doing. Indeed it may be a clone of your own code.
So in the end you cannot be sure who wins unless one of you has some extra hardware privilages.
"what does cog stop do to a cog that is loading?"
Sounds like time for an experiment.
-Phil
The additional cost is the $8 for the second prop.
Forces stop mode I should think. I suspect that's just a single cog-reset line that overrides everything in that cog.
Similarly coginit during loading would restart the loading with the new parameters. That's how I'd design it (i.e. idempotent) for simplicity and avoidance of race conditions. I am guessing that loading is a done with a special circuit with two counters to copy hub ram to cog ram and then enable execution. coginit would simply have to set that circuit running. In fact I'd arrange that one counter is actually the program counter itself temperarily re-purposed. Wonder if it's done that way...