Home > Message-Passing, Projects, RTOS, SKC++ > SKC++: Message-Passing Principles

SKC++: Message-Passing Principles

Monday, November 2, 2009 Leave a comment Go to comments

Message-passing is used, in an RTOS-based system, to provide a safe way of transferring data from one context to another or, in other words, from task to task. What is safe, though, is not always efficient and vice versa.

To copy or not to copy?

Some systems use copying to transfer data across the context boundary – pass-by-value on a grand scale. This is safe because the copying takes place in the middle of a system call, in the controlled environment of the kernel – which has not itself the slightest interest in reading or modifying the data. By the time the application code of either the sending or the receiving task (re)gains control, each has its own copy of the data and can do what it likes with it. Typically, the sending task will refill the same area with new data to form the next message while the receiving task may or may not still be using its copy of the original data. Clearly, though, this method is very slow for large amounts of data.

The obvious alternative to copying the data is to copy just a pointer to the data – otherwise known as pass-by-reference. However, this is very dangerous in its most primitive form. As soon as the receiving task has access to the data, we have two potential problems:

  • Depending on the order of events and the priorities of the two tasks, the sending task might rewrite the data before the receiving task has finished with it.
  • Before the receiving task has finished with it, the data might actually disappear, logically, and be corrupted by something unrelated to either task. This will happen if the message is built locally (on the stack) by the sender using a function which returns before the receiver’s processing is complete.

“Bad programming”, you might say, and you’d be right. However, these are the very techniques a programmer might have used, in complete safety, on a previous project with a different RTOS which used pass-by-value message-passing. I’ve seen both of these mistakes made, causing the kinds of sporadic bug manifestations we all hate to have to track down. To get around these problems and gain the performance benefits of pass-by-reference, we need to enforce – or at least strongly encourage – disciplined use of dynamic message allocation:

  • The sender creates, builds, sends and forgets the message.
  • The receiver processes then frees the message (or forwards it for eventual freeing elsewhere).

In enforcing the discipline, the key concept is one of ownership:

  • The message is owned by only one task at a time.
  • Ownership passes from one task to another as the message is sent around the system.
  • Only the current owner can access the message.

Even in C++, the word “enforce” is a bit strong but we can go further along this road than we can in C. You may know of the auto_ptr class in the C++ Standard Template Library. This does quite a good job of transferring ownership, but it is too open to abuse for the rigorous standards of SKC++!

As you will have guessed, SKC++ uses something like an auto_ptr to pass dynamically-allocated messages around without copying. Details next time.

Direct or indirect message-passing?

Let’s be clear, first of all, that messages need to be queued for their receiving tasks; we don’t want to lose any while the receivers are busy with other activities.

Most older RTOSes use indirect message-passing:

  • A message queue is created as a standalone object.
  • Tasks send messages to the queue. Messages are usually queued in FIFO order.
  • Other tasks (any other tasks) can wait at the queue for messages, in FIFO order or in order of task priority.

Direct message-passing works like this:

  • Queues are still necessary but they belong to particular tasks. This implies that only one task can wait at a given queue.
  • Tasks send messages directly to other tasks; the queueing happens invisibly.

For reasons of performance, cohesion, simplicity and elegance – none of which I intend to dwell upon here – I much prefer direct message-passing.

SKC++ implements direct message-passing but cunningly combines it with the event-handling scheme already described, allowing messages to have different priorities, if required, and allowing each task to wait for both events and messages at a single point in its execution sequence. Details next time (or maybe the time after).

Categories: Message-Passing, Projects, RTOS, SKC++ Tags:
  1. Anonymous
    Thursday, November 5, 2009 at 08:41

    In general, what you are touching on is the problem of shared memory and message passing (and pass-by-value) is an attempt to avoid it.

    But if you only allow direct message-passing, how will you implement a task-pool concept (dare I say “pattern”)? That’s where I can can have X (identical) tasks all waiting on one message queue. I guess I would need an additional mediator/coordinator task?

  2. Peter Bushell
    Thursday, November 5, 2009 at 09:42

    Yes, this is the only flaw, as far as I know, with direct message-passing. Up to now, I haven’t seen such task-pools used a lot and that weighed into my decision to go for the direct approach. I suppose the task-pool concept might become more popular with the inevitable rise of multicore and transparent multiprocessing (tasks – not necessarily identical – queueing for processors), though most of that stuff should be hidden from view within the kernel and should not influence what is provided at application level.

    As you say, an intermediate task provides a solution, when needed. However, I’m thinking hard just now about synchronisation approaches for SKC++ and I’m sure there’s a more efficient solution lurking in there, somewhere.

  3. Anonymous
    Thursday, November 5, 2009 at 10:30

    You’re right, shared-memory approaches are not good for parallel processing, so if the kernel avoids/solves it cleanly, then moving to multiprocessor/core will be eased.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: