RTSync Tutorial 5 - Synchronizers

So far this tutorial has not gone over any of the aspects of the language that are devoted to maintaining real-time constraints. Synchronizers are used in RTSync to uphold these constraints. A synchronizer is set up similar to an actor, but it does not have any methods. Instead there are four blocks: initialization, constraints, triggers and exceptions. Here is a skeleton of a synchronizer declaration:

  synchronizer synchronizer_name
  {
      variable declarations
  
      init( actor pairs to synchronize )
      {
          initialization code
      }
  
      constraints
      {
          timing constraints
      }
  
      trigger
      {
          synchronization actions
      }
  
      exception
      {
          what to do on a timing violation
      }
  }

All four of these sections must be in place, otherwise there is an error. So what are these four blocks? That is what will be discussed now.

The synchronizer is what handles the messages between actors. So in order to see which messages to intercept, the synchronizer must be told which actors to monitor. In the init block, there is the initialization code that is run when the synchronizer is created, but also in the parentheses after the init keyword the actor pairs to synchronize are specified. An actor pair in this declaration list is specified using the following syntax:

  actor1 <-> actor2

The order that the two actors come in does not have any significance. Any number of pairs may be synchronized by one synchronizer, separated by commas.

The constraints section handles the timing constraints for messages. There are two types of constraints: maximum constraints and minimum constraints. The maximum constraints can be thought of as a sort of deadline for a message (the time by which the message must be sent) and the minimum constraint is the earliest time that a message will be sent. Given minimum constraints, it is possible for a long period of time to pass between the time when the first actor sends a message and the time when the method is actually received by the second actor. The syntax of these two constraints is as follows:

  min actor1.method1 -> actor2.method2 = some_expression;
  max actor1.method1 -> actor2.method2 = another_expression;

The min statement here means that when actor1.method1() calls actor2.method2(), an amount of time equal to some_expression must pass before actor2 actually gets the message. The max statement here means that when actor1.method1() calls actor2.method2(), if an amount of time passes equal to another_expression before the message actually gets to actor2 then an exception is thrown (hence the exception block). However, note that if some_expression is always greater than another_expression, then you will always have a timing violation.

The trigger and exception blocks are described in the next tutorial.