Shop OBEX P1 Docs P2 Docs Learn Events
Inter-Cog Messaging :: A contrived example — Parallax Forums

Inter-Cog Messaging :: A contrived example

TinkersALotTinkersALot Posts: 535
edited 2010-07-07 06:49 in Propeller 1
I was doing some investigation with the OBEX example of "eight talking cogs" with an RPM, and found it to be a bit unstable (I could never get a reliable all-cogs-going startup).

Thinking I must have done something wrong, I tore out, replaced, and double-inspected·the inter-cog-signal-pins·wiring(according to the diagram in the original example). After too many occurances of that exercise, I determined that it was not my wiring at all.

So, I decided to create my own variant of the idea, but with a couple of key differences.

* This variant of the project requires no specific wiring. It can work with an RPM "out of the box"
* This variant uses a simple message exchange buffer that the cogs exchange messages thruogh.
*·Each "message" in the buffer consists of a three-byte-set (the message sender, the message target, and the message-value)

In this rather contrived use of this mechanism:

*·Cog zero sends messages to all other cogs through the buffer (access to the buffer is wrapped in a lock).
* Each cog then sits in a "message loop" function that simply tries to read messages for that cog as a "target" of the message.
* If the receiving cog sees a message-value that matches its "assigned LED Pin (see the RPM)" it will toggle that pin. In this example, all other message-values are discarded by the receiving cog.
*·The message fetch function returns the first message found that is for the requesting cog, and then does some "buffer cleanup and management" so that the message buffer·will recognize·the first free message location for subsequent messages·written to the buffer.

Possible Improvements:

*·Right now all·cogs share a single message buffer, I think this could be replaced with a buffer for each cog, but that scheme would consume all avaiable locks (that may not be an issue really, but it·is worth being aware of)
* If this example is used as a foundation, then it is presumed that the messages between the cogs would have more relevance and have more message-handling-logic for each message. With this example, I suspect most of the time, all the cogs are spin-waiting for access to the singular buffer lock.

Summary:

While this variant owes its inspiration to the eight-talking-cogs example, I think this version is a lot more understandable as a first stab at "IPC" between cogs because it·is a·much more stripped down illustration of inter-cog·operations.

Hope this is helpful to somebody out there.

Comments

  • TinkersALotTinkersALot Posts: 535
    edited 2010-07-05 21:46
    Okay, So here is an interesting variation on the sample. This version splits up the messsage buffer into segments. Each segment has a single byte (for the message count within that segment). Each of the segments holds a message queue targeted at a single cog, so in effect it 'looks like this':

    | header0 | cog0buffer-segment | header1 | cog1buffer-segment ...| header7 | cog7buffer-segment |

    Okay, fine, but so what?

    Wait, there's more.·Here is where the real performance·improvement lies:

    Each of these segments is guarded by its own lock. So, that more than one cog can be operating on the buffer at the same time, just not in the same segment.

    Using this variant, the RPM "demo" for this project "blinks a whole lot faster"

    I can't promise "no bugs here" yet, but thought this still potentially interesting to those just getting used to how to make the propeller multi-process in a cooperative manner.
  • mparkmpark Posts: 1,305
    edited 2010-07-05 22:05
    What's RPM?
  • TinkersALotTinkersALot Posts: 535
    edited 2010-07-07 06:49
    This is some greener code (the newest variant is not yet tested), but hot off the presses for anyone interested in reviewing my progress here.

    This new variant includes improved message managment, by treating each of the buffer segments as a ring-buffer. The previous version did not guarantee FIFO treatment of messages sent between cogs (that could lead to chaos manor for sure).

    This version enforces a FIFO scheme in each of the message segments, and also will not allow the writer to over-write any message that has not yet been consumed. In this case, the sender can attempt to repost the message until it succeds. Typically, queue segment is full is expected to be the majority cause of queue-post errors (but other conditions are handled as well).

    The other feature this version brings is heap-based, multi-byte messages being able to be stored in the queue. This is done by adding another byte to the message (a message type descriptor) that allows heap·allocations·of various types to be sent through the·message queues. The message loops are expected to simply mark the message type in order to send a heap request through the system. (the·heap being experimented with here is the heap manager found on the OBEX).

    Anyhow, this framework·is getting near·the point where I will start to add actual application code to·it. It is my hope to use this as a basic framework for·my stingray -- where I hope the framework will support a form of pipelined subsumption processing model. By which I mean,·some·cogs will be dedicated to sensory tasks and will send their outputs to other 'decision making cogs'·through·this messaging system that will 'vote' on what to do with the stimulus.

    Well, that is the plan anyway....

    NOTE: This updated zip contains all variants developed over the last couple of days, just in case they are of interest to anyone else out there in the clouds.
Sign In or Register to comment.