EEEN30141 Concurrent Systems
1. Introduction
In this part of the assignment, the focus is on synchronisation – specifically designing and implementing synchronisation objects for the start of the race and for the baton exchange. The termination of the race is considered in the third and final part of the assignment. The synchronisation mechanisms will use C++ mutexes, locks and condition_variables.
The objective of this part is to properly model the blocking, starting nd termination of each thread in a simulated race.
2. Track Layout
Each team is allocated a lane on the track, and each athlete in a team runs a specific part (‘leg’) of the race. One athlete runs the first leg and hands the baton to the athlete who runs the second leg etc. Recall that theThreads is declared as:
thread theThreads[NO_TEAMS][NO_MEMBERS];
The first index identifies the lane, and the second identifies the leg of the race that the athlete runs.
At the start of a relay race, all athletes must take up their correct positions and wait, either for the start of the race, or for their preceding team member to arrive at the exchange zone. In terms of the elements of the theThreads array:
-
theThreads[0][j], j {0, 3} must be at the start
-
theThreads[1][j], j {0, 3} must be at exchange zone 0
-
theThreads[2][j], j {0, 3} must be at exchange zone 1
-
theThreads[3][j], j {0, 3} must be at exchange zone 2
Start Finish
exchanges[0][0] exchanges[1][0] exchanges[2][0] exchanges[3][0]
Exchange zone 1
theThread[0][1] theThread[1][1] theThread[2][1] theThread[3][1]
Examples:
theThread[0][3] theThread[1][3] theThread[2][3] theThread[3][3]
Exchange zone 3
exchanges[0][2] exchanges[1][2] exchanges[2][2] exchanges[3][2]
theThread[3][0] theThread[2][0]
Figure 1 Track, start, finish, exchange zones
and unblocks
thread[2][1] which is blocked in
• theThread
[0][1] is blocked at sync object
theThread
[0][0]
3. The Start of the Race
There are two stages to the start of a relay race. First, athletes must take their positions. These are either the start, for the first team members or what is called an exchange zone. (see Figure 1). The second athlete in each team starts from Exchange Zone 1 etc etc.
Once all the athletes are in position, there is a pause before the starting pistol is fired. This is a random delay. When they reach Exchange Zone 1 they hand over the baton to the second member of the team, who then starts to run to Exchange Zone 2 etc.
Once the last members of each team have been handed the baton, they run for the finishing line, where there is no handover. The team of the first athlete to cross the finishing line wins the race. The team of the second athlete to cross the finish line is second etc.
3.1 Synchronisation
Thread synchronisation is needed to implement the rules of a relay race in this simulation.
All athletes must be in position before the race can start. See Figure 1 and the description at the start of Section 3.
3
In concurrent programming terms this means that all the threads representing the athletes running a particular leg of the race must have started to execute but have become blocked in a synchronisation object before the simulated race can begin.
The athlete threads running the first leg of the race become blocked in a synchronisation object of class StartAgent (see Appendix A2). The athletes running the other legs are blocked at a synchronisation object. There are three such objects, one for each Exchange Zone, and they are of class EZAgent. See Appendix A3.
3.1.1 Start
The simulation should represent the actual start of a relay race as closely as possible. In a relay race the athletes must first take their position at their starting positions – either the start or the appropriate exchange zone. This should be represented in the simulation by each created thread blocking in the appropriate synchronisation object, after updating readyCount.
Once all the athletes’ threads have blocked, the race can start. theThreads[0][j], j {0, 3} are unblocked by main releasing the waiting threads representing the starting athletes in each team.
How does main know when all threads have blocked? StartAgent and EZAgent have a data member readyCount that records the number of threads blocked in each synchronisation object. They also have a member function readyToStart which returns false if the number of blocked threads < NO_TEAMS and true if the number of blocked threads == NO_TEAMS.
When there are NO_TEAMS threads blocked in the StartAgent object and the one thread blocked in each of the twelve EZAgent objects, the race can be started. a short random delay has elapsed which represents the athletes in position awaiting the start i,e,, waiting for the starting gun. When this time delay finishes main calls the proceed member function in the StartAgent object.
The threads that are blocked in EZAgents must simply wait to be unblocked by the preceding thread in their team.
3.1.2 Baton Exchange
At the end of the time delays of theThreads[0][j], j {0, 3} , each thread must
unblock the next member of its team that is blocked at exchange zone 0 i.e.
4
• theThreads[0][j] must theThreads[1][j], j {0, 3}
individually unblock the corresponding
The unblocked threads then enter their own time delay representing the running of their leg of the race. theThreads[0][j], j {0, 3} all then terminate after recording the time that it took to run their leg of the race i.e., their time delay. This should be stored in the appropriate entry in the ThreadMap and will require a modification to the Competitor class.
The above protocol is executed by theThreads[1][j], j {0, 3} unblock theThreads[2][j], j {0, 3} that are waiting at exchange zone 1.
This is repeated at exchange zone 2, where theThreads[2][j], j {0, 3} unblock theThreads[3][j], j {0, 3}.
NOTE: the diagram in Figure 1 shows that 12 EZ objects are required. This is correct for the FINAL simulation. However, the sync object at the end of the race (of class FinishAgent) is developed in the third and final part of this assignment. Hence for THIS part, use 4 additional EZAgents (exchanges[x][3]) at the end of the race. These will not block any threads and theThread[x][3] will simply call proceed on these final EZAgents, and then terminate.
In the final simulation, which includes part 3, exchanges[x][3] will be removed and replaced by a single object of class FinishAgent.
4. Advice
You should aim to complete this part of the assignment by the start of Week 9. Support for the final part of the assignment (part 3) will be available in Week 9.
5. Requirements
In the final program that you submit, you will need to provide .h and .cpp files for each class that you develop.
6. Malpractice
There are well known solutions to some aspects of the synchronisation problems that feature in this part of the assignment. However, YOU ARE EXPECTED TO WRITE YOUR OWN CODE ON YOUR OWN and to follow the code structure outlined above. Therefore, each line of your code for this part of the assignment should be carefully commented, explaining its role in the synchronisation protocols. Omitted or inadequate comments will result in a substantial loss of marks, as will block copying from any published source. The unit leader’s decision is final in the event of a dispute.