VPL Lab 5 - Exclusivity Test
Glossary Item Box
In this lab you will explore the concept of exclusivity.
This lab is provided in the language. You can find the project files for this lab at the following location under the Microsoft Robotics Developer Studio installation folder:
This lab teaches you how to:
This lab does not require any hardware.
This lab is designed for use with VPL.
Exclusivity of Control Flows in VPL
Exclusivity is one of the more advanced VPL concepts, but something that you must understand so you can avoid unexpected behavior. You have already learnt quite a lot about concurrency in VPL. In previous labs you have used merges, joins and notifications to construct your programs. Something that has not been covered is how VPL decides which control flows are exclusive (i.e. which control flows will not be executed concurrently).
If you are a novice programmer, you might not understand the importance of exclusivity. A common example of where it becomes essential is when you update a variable in your program that is also referred to in other parts of the program.
Consider a counter that is incremented from time to time from two different places in the program. At the lowest level inside the computer it is necessary to read (get) the value of the variable, add one to it, and then store (set) it back into memory. Assume that the first code path has just read the value, but before it can write the result back into memory the second code path updates the value. Now when the first code path stores a new value it will overwrite what the second code path has just written. The result is that the counter will be one less than it should be because the first code path was using stale information.
To solve this problem, each code path must have exclusive access to the counter until it has completed the increment operation. This is referred to as an atomic operation because it is treated as indivisible even though it involves several steps: read value, increment, write value. No other code can alter the value of the counter until the increment operation is finished. The problem of simultaneous updates has been eliminated.
When you write RDS code in C#, you decide, as the programmer, which control flows are exclusive and which are not. Concurrency and asynchrony is handled with the support of the Concurrency and Coordination Runtime (CCR). CCR forms a large part of the architecture underlying RDS. CCR makes it relatively easy for programmers to handle concurrency and asynchrony in their code. When you use VPL however much of this management is taken care of for you.
The following figure shows an example of when VPL will or will not run code concurrently.
You can see from the figure, that the top block of code (inside the dashed rectangle) will not be run concurrently with other code in the diagram. This is because there is a variable set in this part of the control flow, and variables are shared by the whole diagram. (Variables are part of the service state). Inside this block, the control flow is split on the same event (or notification). When this happens, even though a variable is set these two branches can be run concurrently with each other. It is left up to the programmer in this instance to manage any getting and setting of variables so that there are no conflicts.
The following diagram shows another interesting case.
In the previous example, we saw that if the control flow splits on the same event, from the same activity/service, then the two flows run concurrently. This is not the case if two different events split the control flow from an activity/service. Consider the case where notifications arrive from a robot service. One notification might be about a bumper being pressed and another from a range sensor. Clearly different notifications from the same activity/service can be quite independent. If one of these control flows sets a variable, it will be exclusive, and cannot run concurrently with the other control flow.
The following diagram shows one further case of interest.
You saw previously that if the same event split into two different control flows from the same code block for an activity/service, then the two control flows would be run concurrently. If you divide your code as in the preceding diagram, however, the behavior changes as described.
Exclusive control flows have priority when it comes to execution if there are multiple flows waiting to execute. However, an exclusive flow cannot interrupt a concurrent flow, or vice versa. The fact that an exclusive flow will wait for all concurrent flows to finish is illustrated in the example at the end of this lab.
It is important not to have exclusive control flows that run for a long period of time blocking the execution of all other flows. While the execution of other flows is blocked, it is not possible to do a get on the state of the service to view the variables. For example, you should not in general call Wait on a Timer in an exclusive flow.
Creating a Test Program
You can open the diagram supplied with RDS or follow through the steps below to create a diagram of your own.
Open VPL to create a new diagram. Add a Variable to the diagram by selecting Variables... from the Edit menu. Call the variable counter and leave it with a data type of int.
Using a Flexible Dialog
Locate the FlexibleDialog in the Services panel and drag it to the diagram. In the Properties panel under Configuration select "Set initial configuration". It should look similar to Figure 1 below.
The FlexibleDialog allows you to create your own Windows Forms and interact with them from your VPL program. Although it is possible to add controls to the Form in your code, it is more common to set the configuration using the Properties panel.
Begin by changing the name of the dialog to RaiseExclusive. (Figure 2 below shows the fully configured dialog). Tick the checkbox beside the Visible property. If you forget to do this the dialog will not appear on the screen. Your program can also send requests to the dialog to make it invisible and to reappear while the program is running. However, you will want it to be visible initially in this case.
The FlexDialogState contains two collections: Controls and Buttons. You can add to these collections using the plus sign to the right of the word Count. Start by adding a label that says "Raise an Exclusive event" in its Text property. Note that every control or button on the dialog must have a unique Id (which is just a text string). For this control the name is not important. You can select the ControlType from the dropdown list. Make sure you select Label.
When the dialog is displayed, all the Controls will appear arranged vertically one after another in the order that you create them. You can delete a control by clicking on the X at the right-hand side of the control properties.
Now add a button. Give it an Id of btnRaise, set the ControlType to Button and the Text to "Raise". When you have done this the Properties panel should look like Figure 2.
Buttons are added across the bottom of the dialog in the order that they appear in the list. In this case there is only one.
When you run the program later you will see three dialogs displayed as shown in Figure 3. The top one is the one that you have just created. The other two are very similar, but they are separate dialogs.
Exclusive Control Flow
Now that know how to configure a FlexibleDialog you should be able to complete the rest of the first control flow in the program. This is shown in Figure 4. You have used all of these types of Activity blocks before.
Make sure you set the AlertText for the SimpleDialog to:
"Exclusive Counter: " + Counter
Note that there is a Calculate activity at the end of the control flow. This is necessary to complete it.
Concurrent Control Flow
Use Figure 5 as a guide to create the control flow for the Concurrent path. This path does not set any variables and therefore can operate concurrently with itself or the Independent path.
Make sure you set the AlertText for the SimpleDialog to:
"Concurrent Counter: " + state.Counter
By referring to the Counter (which is part of the state for the diagram), you make this a Concurrent control flow. (Unfortunately, you cannot see this in Figure 5). Note however that this flow does not change the value of Counter.
Independent Control Flow
Figure 6 shows the control flow for the third and final path in this diagram. This path is Independent, which means that it can operate regardless of whether there is another concurrent or exclusive control flow being executed.
Make sure you set the AlertText for the SimpleDialog to:
"Independent event handler"
This control flow does not refer to, or modify, and state variables. (Again, you cannot tell this by looking at Figure 6, which looks the same as Figure 5. You have to examine the connections between activities to see the difference.) Therefore it can run independently - exclusivity has no effect on this flow.
Running the Program
Now that you have completed the diagram, save it and run it. Three dialog boxes should appear as shown in Figure 3. It is possible that one or more of the dialog boxes might appear behind the VPL window, or the VPL Run dialog, or each other. Look at the Taskbar to find the dialogs. Move them around so that they do not overlap, as shown in Figure 3.
To begin with, click on the Raise button for a Concurrent event, then an Independent event, and then another Concurrent event. You should see three dialogs pop up as shown in Figure 7.
This test shows that Concurrent and Independent control flows can run at the same time. They do not interfere with each other.
Now click on the Raise button for the Exclusive event. It might appear that nothing happens. However, the Exclusive control flow is waiting to execute. It cannot run as long as a Concurrent event is active, so click on the OK buttons on the two Concurrent Alert dialogs. Leave the Independent Alert dialog alone. As soon as you close the second Concurrent Alert, the Exclusive Alert should appear. Notice that the counter in the Exclusive Alert is now 1, instead of 0.
Obviously the Exclusive flow can run at the same time as an Independent flow because the Independent Alert dialog is still displayed.
Try clicking on each of the Raise buttons without closing the Exclusive Alert dialog. Only the Independent Alert will pop up. When you close the Exclusive Alert, the next Alert to pop up should be another Exclusive even if you had also clicked on Concurrent several times.
There are many different combinations of events. Play around with the program until you understand how they interact.
Note that if you leave an Alert dialog for too long, its response will time out and it will be the same as if you had clicked on OK. An error message will appear in the VPL Run dialog and also in the Debug and Trace Messages if you open a web browser and look at the DSS node. An example of this error message is shown below:
### DsspForwarder:OutboundFailureHandler. Exception:The operation has timed out. Action:http://schemas.microsoft.com/xw/2004/10/dssp.html:SubmitRequest Body Type:Microsoft.Robotics.Services.Sample.Dialog.AlertRequest Target Service:dssp.tcp://xxx.microsoft.com:50001/dialog/a76ed22b-03e8-4767-a8c4-a56e3f68a557 Source Service:dssp.tcp://xxx.microsoft.com:50001/model/exclusivitytest
It is important that you understand why control flows become exclusive (when any activity in the flow updates a state variable) and how this affects other control flows. If you do not have a good understanding of this, then you can create situations where the program might hang due to a deadlock. This occurs when one control flow wants exclusive access to a resource, but another control flow already has the resource and will not release it.
VPL Hands On Labs: VPL Lab 6 - Sensing and Simple Behaviors
VPL User Guide: Getting Started
© 2012 Microsoft Corporation. All Rights Reserved.