dna

The URBI language provides four types of command separators, to express various temporal constraints between commands.

 

On top of the usual semicolon, which separates two commands that should be executed one after the other, URBI have separators like the & symbol to indicate that the two commands should run in parallel and start at the same time. The figure below summerize the four existing separators and their semantics:

 

 

separators

 

 

Of course, A and B could be anything: single commands or block of code between brackets. In the example below, C will start right after A and B have finished:

{ A & B } | C;

 

Commands duration in URBI

In most programming languages, commands are semantically "instantaneous": in theory, they take zero time to execute. In URBI, the notion of time is part of the language semantics, which is in fact necessary to handle parallelism (these are two connected topics). in URBI, some commands can last one second. For example, a simple assignment in URBI can target a variable to reach a value in a given time or at a given speed, or set a sinusoidal oscillation on it. The assignment is not instantaneous anymore and can be run in parallel with others:

  neck.val = 10 time:450ms
& leg.val = -45 speed:7.5
& tail.val = 14 sin:4s ampli:45;

time, speed, sin or ampli are called "modifiers". They modify the way the assignment is done. Suppose that the value of the neck.val variable is -2 before we start the above script. When the first line above is executed, the variable neck.val will reach the value 10 in 450ms:

 

time assignment

Tags

Running hundreds or thousands of commands in parallel is in important feature, but how to interact with these running commands? How to stop them if needed? URBI provides the notion of command tag: any portion of code can be prefixed with a tag. It is then later possible to stop, freeze, unfreeze this code from anywhere using the tag name, which brings powerful features to control the flow of execution of parallel code:

mytag: { some code };
stop mytag;
freeze mytag;
unfreeze mytag;

...

You can of course have hierarchical tags, multi tags and many other tools to help you define powerful context-based identifier at runtime to label your code and manipulate/debug it.

 

Concurrent access

One cannot talk about parallelism without discussing concurrent access. Traditional approaches rely on mutual exclusion (mutex) to insure that only one piece of code is using the ressource at a time.

URBI is a parallel language and it has knowledge about what is going on in parallel. Because parallelism is integrated in the language semantics, we can do much more than mutexes. Consider the following simple code:

x = 1 & x = 3;

The x variable is simultaneously assigned with 1 and 3. in URBI, variables have a blend mode which specifies how such conflicting simultaneous assignments should be handled. The 'add' mode for example will add the conflicting assignments, resulting in a value of 4 in the above example. The 'mix' mode does an average calculation and 'queue' is the classical mutex. There are six other different blend modes in URBI.

x->blend = add;
x = 1 & x = 3;
// now x equals 4