Accessing VAR and DAT from another cog
In this code:
Is it correct to refer to these VARs in OtherMethod, running in a different cog?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
VAR long pin1, pin2 long pinVal long stack[noparse][[/noparse]10] PUB Start(thePin1, thePin2) pin1 := thePin1 pin2 := thePin2 dira[noparse][[/noparse]pin1..pin2]~~ cognew(OtherMethod, @stack) PUB SetVal(theValue) pinVal := theValue PRI OtherMethod repeat outa[noparse][[/noparse]pin1..pin2] := pinVal waitcnt(clkfreq/20 + cnt)
Is it correct to refer to these VARs in OtherMethod, running in a different cog?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
Comments
Sure it must be possible to change the value from more then one cog..?!
But of course it must be atomic operations or protected with semaphores if consistent updates are required, but that dilemma also occurs for read access, as you are pointing out above.
I'm trying to keep my answer simple and straightforward, yet useful. SPIN does absolutely no checking of variable accesses. Variable names are not known outside the object that contains them, but that's the only limitation. With multiple processors, like with interrupt processing, you can do things that won't behave the way you expect them to do like change the value of a variable when some other routine is expecting it to have a particular other value. There have been textbooks written about how to get multi-processor programs to behave properly. For most of the things that the Propeller will be used for, there are mostly 3 cases:
1) The case I mentioned where one processor and one only can change the value of a variable and any number of other processors can reference the value. The only requirement here is that, if the value is referenced several times by a processor, the value must be assumed to change between the references. If you need the value several times in a calculation, you can make a local copy of it that represents its value at a single point of time.
2) Single producer, single consumer ... The most common example is a buffer that is filled by one processor and emptied by a second processor. There are two pointers, an input pointer and an output pointer. The filling processor uses the input pointer while the emptying processor uses the output pointer. The filling processor can reference the output pointer to check if the buffer is full already and the emptying processor can reference the input pointer to check if the buffer is empty. If the emptying processor thinks the buffer is empty even though the filling processor is adding a new entry, there's no problem ... eventually the emptying processor will see the updated input pointer and process the new entry. If the filling processor thinks the buffer is full even though the emptying processor is making room, there's no problem ... eventually the filling processor will find that there's room and will add a new entry.
There is a special case of this where the buffer has only one entry. The producer watches a buffer for "empty" (waits for a zero in the variable). When it finds a zero, it knows it can put a non-zero entry in the buffer. The consumer checks for a non-zero entry and does something with it if found. When the consumer is done, it sets the buffer back to empty (zero).
3) Pretty much anything else will require the use of a semaphore (or lock) so that only one processor will access the common information at any one time.
Post Edited (Mike Green) : 1/4/2007 5:36:30 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
Ok, then we are talking about the same thing. I was afraid I had missed some intricate spin variable protection feature.
- Mikael