Shop OBEX P1 Docs P2 Docs Learn Events
Simultaneous calls to an object method — Parallax Forums

Simultaneous calls to an object method

Agent420Agent420 Posts: 439
edited 2009-08-27 11:21 in Propeller 1
Still wrapping my head around some of the parallel processing ideology and just thought of this...

Is it possible that a Prop app has a cog that contains some public methods, and several other cogs have calls or references to those methods?· If so, could there then be a case where several cogs attempt to call the same method in another cog at the same time?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Comments

  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-26 19:44
    Sure, there are a couple of easy ways to cause it - have a object with DAT data that is included in multiple other objects. A object that starts multiple cogs. If you have this you have to code to sync access to the data. There are locks available to help you do this.
  • Agent420Agent420 Posts: 439
    edited 2009-08-26 19:51
    My thought isn't entirely related to data access so much as it is a method within a cog receiving multiple requests to run the same code from several other cogs.· I've not used the locks much yet, but I have a general understanding of that aspect.

    I'll try to come up with a good program example, but the question relates to something like this:

    Cog 1 has a public method named 'Callme'

    Cogs 3,4 and 5 all contain code that references the 'Callme' method in Cog 1.

    A situation developes where cogs 3, 4 and 5 all attempt to run the 'Callme' method in Cog 1 at the same time.

    Is that possible?· What would be the result?· Would there be some kind of priority given based on cog id or similar?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-08-26 20:22
    Hello Agent420,

    it is different

    everytime you start a new cog by using the command cognew

    the COG-RAM of another cog is loaded with the SPIN-interpreter and the interpreter starts fetching spin-tokens and parameters
    from HUB-RAM and is interpreting the spin-tokens

    This means your method "Callme" is stored ONE time in HUB-RAM and then the SPIN-tokens are fetched from 1-8 cogs to be interpreted
    Thereby every cog uses his own stack

    if something does interfere with each other depends on the OBJECTS but NOT on the cogs !

    global variables are accessible allover ONE object (= *.spin-file)
    so if two methods which are stored in the same object access the same global variable
    If methods are running in DIFFERENT cogs then
    the methods will interfere on this variable in an mostly unpredictable way as you would have to calculate the executiontime of both methods
    (and everything that has been executed before) in every loop to see which method will be first to reach the point of accessing the variable

    "normal" global variables are NOT accessable across OBJECTS (but well accessable across cogs as long as the methods running in the cogs are from the same object)

    Variables in the DAT-section are accessable across OBJECTs and here you have to use a lockmechanism too


    This might be confusing. You will get it clear by playing around with different configurations.

    Play around with some simple methods belonging to one object but start the methods in different cogs
    then distribute the methods M1 and M2 over two different objects ObjA.spin ObjB.spin and try to access the method M2 from inside ObjA.spin

    etc. etc.

    best regards

    Stefan
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-08-26 20:22
    They can easily be executed in parallel wthout a problem, unless they share DAT-defined data. VARs are replicated for each instance of th object, and local method variables exist only on the various stacks.

    In your example, if cogs 3, 4, and 5 have refrences to Callme, Callme will be executed in those cogs, not from cog 1.

    -Phil
  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-26 20:24
    Its allowed, each cog has its own stack so local variables and routine parameters work. It the object is another copy (included in a different file) then VAR variables are separate. If each copy starts a cog then you get 2 cogs. If you are calling the same copy or you have 2 or more copies with DAT variables then in the first case VAR and DAT objects are shared. In the 2nd case only DAT variables are shared.
    So the problem turns into a shared variable problem. So if you are updating multiple variables then you have to worry about updating overwrite probelms. which is what locks are meant to protect.
    For an example look at http://forums.parallax.com/forums/attach.aspx?a=34061 this object is meant ot be included in multiple other objects. It is coded to start 1 cog for all opies of this objects and multiple cogs can call the pub routines. The shared variables are protected with locks and locks are also used to protect against the asm cog being asked to do multiple things at the same time by different cogs.
  • photomankcphotomankc Posts: 943
    edited 2009-08-26 20:46
    Ok, so I have been looking at a couple code examples to figure out how to write an object that can be accessed by multiple other objects and while I understand the locks what I didn't see was how the compiler generated one object in one instance and in my case the variables were demonstrably separate. So if I understand this correctly the DAT section is the difference. By declaring the variables in DAT then those variables are not local to each object but shared among them? If I declare them in VAR then each time I declare the object in other .spin files' OBJ sections it's getting it's own variables.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-08-26 21:45
    You need to be careful to separate the idea of objects from the idea of multiprocessing. You can have a program all in one file (object) that uses all 8 cogs and has 3 or 4 cogs all executing the same method at the same time. You can have a program made up of several objects, nested several deep, where everything is executed by a single cog and the other 7 cogs are all idle. They're separate ideas.

    That said, it's common practice for an object to make use of a cog to do most of its work where there's a start and stop method that takes care of initializing the new cog and any shared variables (and stopping the cog if needed). Most of the other methods are interface routines that are called from other objects and communicate with the "hidden" cog that's doing most of the work.
  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-26 22:02
    Also using VAR doesn't mean you dont have a multi-cog problem. as mike said objects and cogs are different. VAR means each copy of an object has its own set of data. DAT means all copys of an object share the same data.
    Separately you have a multi-cog /data problem if multiple cogs can access the same variable. This could be multiple cogs accessing a VAR variable in 1 object, or multiple cogs accessing a DAT variable in multiple copies of an object.
  • SamMishalSamMishal Posts: 468
    edited 2009-08-27 04:33

    What nobody has mentioned so far is the HUB Round Robin access.

    Yes there are potential problems LOGICALLY for two cogs to access the same variable. But NOT LOGISTICALLY.
    ·
    Cogs cannot access the HUB RAM simultaneously. Each cog has EXCLUSIVE access to the variable when its turn comes
    to be able to access the HUB.
    ·
    The problem of LOGICAL access is up to YOU. It's perfectly fine for instance to have one cog writing the variabel while another
    reading and due to the HUB round robin access style there is no LOGISITCAL problem at all.
    ·
    If you have both cogs write the variable then AGAIN there is no problem if that is what you want. Due to HUB access
    both CANNOT try to write the variable at the same time. BUT....you might have LOGICAL problems if your program LOGIC
    does not work this way......BUT...this is up to you.
    ·
    Where there is a problem LOGISTICALLY is when there are MULTIPLE variables that need to be EXCLUSIVELY accessed
    by a cog. Hub round robin access only guarantees exclusive access to one LONG from the HUB.
    ·
    If you need to maintain exclusive access over MULTIPLE LONGS then you need to ensure exclusive access over multiple
    round robin cycles.....this is achieved with the aide of LOCKS....see LOCKNEW, LOCKCLR, LOCKRET and·LOCKSET in the manual.
    ·
    Also see page 24 in the manual regarding hub access.
    ·
    Samuel

    P.S. in PASM each cog can also have its OWN local variables which are only in that cog even though they appear
    in the same DAT area they would be part of the PASM code and thus become part of the cog RAM and are thus
    only local to the cog and cannot be accessed by other cogs at all.

    Post Edited (SamMishal) : 8/27/2009 4:45:29 AM GMT
  • Agent420Agent420 Posts: 439
    edited 2009-08-27 10:27
    Mike Green said...
    You need to be careful to separate the idea of objects from the idea of multiprocessing. You can have a program all in one file (object) that uses all 8 cogs and has 3 or 4 cogs all executing the same method at the same time. You can have a program made up of several objects, nested several deep, where everything is executed by a single cog and the other 7 cogs are all idle. They're separate ideas.

    That said, it's common practice for an object to make use of a cog to do most of its work where there's a start and stop method that takes care of initializing the new cog and any shared variables (and stopping the cog if needed). Most of the other methods are interface routines that are called from other objects and communicate with the "hidden" cog that's doing most of the work.
    I think this is the area that I need to focus on better understanding.·

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (Agent420) : 8/27/2009 11:01:38 AM GMT
  • he1957he1957 Posts: 58
    edited 2009-08-27 11:21
    For a more detailed description and some pseudo example code see: http://en.wikipedia.org/wiki/Spinlock

    Spin locks, as their name implies, cause a code thread to "spin" when attempting to access a common resource that is currently in use be another CPU (or COG in this case). This is the reason Mr Chip Gracey included this mechanism in the SMP architectured Propeller :- to allow multiple COGs access to a common "location" that needs to be protected for single update access. When the possibility of conflict arises or to avoid infinite loops, spin-locks are often organised into a hierarchical structure; based on the order of operations/actions that need to occur for the protected resource.

    Multiple CPU/COG access to common READ data is not of concern; WRITE access by more than one is - hence the need for the protection. In order to determine which CPU/COG should be the "last writer" is up to the implementation but the use of a hierachy makes this easier to enforce. Certain "rules" are adopted to allow enforcement of such a hierachy. To prevent "system hangs"; "spin-lock-timeouts" are often used. Common implementations of these involve a mechanism called STOMITH.

    STOMITH (Shoot The Other Machine In The Head) is a technique used to cause a lock holder to "die" if is is deemed the lock has been held too long and could potentially lead to more serious system failure.

    Implementing this kind of mechanism in a Propeller may prove problematic because there is no hardware based interrupt or NMI mechanism but; well crafted code that takes this into consideration could use some common flag/mask location, that, if set for a given CPU/COG ID causes the specific COG as flagged masked to execute a "REBOOT" (or whatever). How to release/recover the resources and actions performed by the "hung" COG is left as an exercise for the reader.


    Cheers,

    Harry E.
Sign In or Register to comment.