Professional Documents
Culture Documents
Vittorio Giovara
26/01/2009
Abstract
In this document a solution will be described for implementing a concurrent programming
scheme in a real-time operating system.
The first part of the document will carry out the design planning, describing the main
procedures and functions in pseudo-code and taking care of two possible issues, deadlock
and starvation. Moreover an actual implementation of the problem will be discussed for the
RTEMS Operating System.
In the second part a complete working implementation of the solution will be presented
for a general purpose operating system, providing profiling and time analysis.
Contents
I Preparation 2
1 The pseudo-code 2
1.1 Functions and Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Proposed Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Message Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
II Implementation 6
4 Development details 6
4.1 IPC Mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5 Profiling 7
5.1 Testcases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
5.2 Mean and Maximum Wait Time . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.3 Execution Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1
Part I
Preparation
1 The pseudo-code
1.1 Functions and Structures
• void sync (int w)
function for normal processes to put themselves in a passive wait; the argument w represent
the weight of the wait;
• information vector
contains general data about every process: it stores the process identifier, its status (blocked
or running), its weight and the age, which counts how many times a process eligible for
activation has not been woken up after an admit; an additional field is required for the
final solution to work, that is the fdlisten, need for communicating with the process;
• vector order
is a vector containing the ordered (by age) list of all the processes that are activated by an
admit;
1. check if the argument w is greater or equal than 1 and less or equal than 10;
1. send a message asking the server to perfom the wake up of some processes;
2. return.
2
server process M
1. spawn a given number of P and Q processes and initilize the “information vector”;
4. if a sync has been called, update the status of the process in the information vector;
6. initialize a list (vector of index) for storing the set of processes that are going to be activated
(called “vector order”) ;
7. select the set of waiting processes with their weight and age from the information vector;
8. order the vector from highest age to the lowest and initialize pound equal to a ;
9. for every element in the vector, send a wake up if its weight is less than pound and if pound
minus the weight is positive;
10. when a wake up is sent update the pound by subtracting the weight of the process; in this
way both the conditions of the assignment are respected;
11. update the information vector with the new status for the selected processes and the incre-
mented age for the unselected ones;
3
2.2 Proof for deadlock free solution
In order for deadlocks to appear, the following four conditions are must appear simultaneously
(Coffman’s Conditions):
• Hold and Wait: processes holding resources request for other resources;
• No preempion: resources can be released only by explicit action of the holding process;
In this implementation there is no risk for deadlocks because the server M handles the processes
only one at a time: in fact a single send can activate the server procedure because there is a single
recv in the loop. Thanks to this implicit serialization, the necessary condition of the circular
wait never occurs, thus neglecting the presence of possible deadlocks.
T = n ∗ ta
As n and ta are finite values, also the T wait time is finite, thus neglecting the presence of
starvation which requires an indefinite wait.
4
One final minor problem may be byte ordering that should be considered when dealing with
message passing on different architectures; since it has been assumed that the processes run on a
same machine it is possible to neglect this problem.
5
Part II
Implementation
4 Development details
The proposed solution has been implemented on Mac OS X 10.5.6, but as design choice only
ANSI POSIX compliant directives have been used, resulting in highly portable code. As a matter
of fact the program has been tested (and proved working) on Linux with kernel 2.6.24 and on
Solaris (SunOS 5.19) over an UltraSPARC IIi.
The solution heavily relies on wrappers for error checking and error analysis, as well as the
errlib library by W. Richard Stevens for error reporting and general Input/Output management.
Resource allocation is carefully considered (foreseeing a possible real-time port) and in fact when
server and process are closed, socket descriptors are closed, pipes removed, memory deallocated
and child processes killed.
It is possible to select the level of verbosity for info and debug message by passing the TRACE
and DEBUG symbols at compile time, while passing TIMETEST enables timing functions to be
activated.
Before starting the program asks the user to insert the number of processes of type P and
to select the behiavior of the processes: actually the user can either choose to let the processes
generate a random number or interact actively with an interface. In the first case the process sleeps
for that random amount of time (only to prserve readability of the output; the program works even
without the sleep() clauses) and then use that value to perform block or wake up. In the second
case the user is prompted to an interface that allows process selection with PID and value insertion
for the sync() and admit() (as well as a clean closing for the program); the interface process
is generated only when interactive behavior is chosen.
6
5 Profiling
5.1 Testcases
The following sets of trace of execution from the program are obtained with both random test
cases and with interactive input test. These test aim to cover all the relevant part of code describing
correct functionality of the algorithm, process interaction and concurrent behavior; thanks to the
the fork() approach, no critical regions needed to be defined.
Output may have been reduced with respect to the actual produced to preserve readability.
Tests have been performed on Mac OS X, Linux and Solaris.
Basic functionality In the following test case, the algorithm functionality will be taken in con-
sideration. Five P processes are being generated and each of them performs a sync with a given
value; Q sends an admit capable of activating only four of them and so only four are woken up,
increasing the age of 8500.
Then two of the activated processes perform other sync’s; at the next admit of 8 from Q, the
first process to be awakened is the one that was left behind (8500) as it respects the given conditions
and avoids starvation. Also process 8502 can be activated and it is awakened right away.
Now processes 8501 and 8498 have their age increased and so are candidate to be activated at
next sync; however Q sends a very low admit and so they have to be discarded in favour of 8500
which has just perfomed an equally low sync. They will be activated by the next admit of Q.
7
(./rtos-hw2) P:8502 sent a sync(1)
(./rtos-hw2) server received a sync(1) from P:8502
(./rtos-hw2) P:8498 sent a sync(3)
(./rtos-hw2) server received a sync(3) from P:8498
(./rtos-hw2) Q:8503 sent an admit(8)
(./rtos-hw2) server received a request for admit(8)
(./rtos-hw2) server sent WAKE UP to process 8500
(./rtos-hw2) server sent WAKE UP to process 8502
(./rtos-hw2) P:8500 has been woken up!
(./rtos-hw2) P:8502 has been woken up!
(./rtos-hw2) P:8500 sent a sync(1)
(./rtos-hw2) server received a sync(1) from P:8500
(./rtos-hw2) Q:8503 sent an admit(1)
(./rtos-hw2) server received a request for admit(1)
(./rtos-hw2) server sent WAKE UP to process 8500
(./rtos-hw2) P:8500 has been woken up!
(./rtos-hw2) server received a sync(1) from P:8500
(./rtos-hw2) Q:8503 sent an admit(5)
(./rtos-hw2) server received a request for admit(5)
(./rtos-hw2) server sent WAKE UP to process 8501
(./rtos-hw2) server sent WAKE UP to process 8500
(./rtos-hw2) P:8501 has been woken up!
(./rtos-hw2) P:8500 has been woken up!
8
(./rtos-hw2) P:8264 sent a sync(4)
(./rtos-hw2) server received a sync(4) from P:8264
(./rtos-hw2) P:8265 sent a sync(5)
(./rtos-hw2) server received a sync(5) from P:8265
(./rtos-hw2) Q:8268 sent an admit(9)
(./rtos-hw2) server received a request for admit(9)
(./rtos-hw2) P:8267 has been woken up!
(./rtos-hw2) sent WAKE UP to process 8267
(./rtos-hw2) sent WAKE UP to process 8264
(./rtos-hw2) sent WAKE UP to process 8266
(./rtos-hw2) P:8264 has been woken up!
(./rtos-hw2) P:8266 has been woken up!
(./rtos-hw2) P:8264 sent a sync(1)
(./rtos-hw2) server received a sync(1) from P:8264
(./rtos-hw2) Q:8268 sent an admit(1)
(./rtos-hw2) process 8264 is set to BLOCKED with weight 1
(./rtos-hw2) server received a request for admit(1)
(./rtos-hw2) sent WAKE UP to process 8264
(./rtos-hw2) P:8264 has been woken up!
Interface testing This test demonstrates the capability of the interface process. It detectes all
possible kind of inputs and correctly manages selected processes . This is possible because the
interface is generated as last child when all the other P processes have been generated and so it has
stored in memory all information of the other processes.
In the following program trace it is verified in order:
• blank input
• program closing
9
(./rtos-hw2) warning - command not correct
Enter ’<process pid> <value>’ to command the program (’0 0’ to exit)
> 12345
(./rtos-hw2) warning - command not correct
Enter ’<process pid> <value>’ to command the program (’0 0’ to exit)
> 12345 4
(./rtos-hw2) warning - no process 12345 found
Enter ’<process pid> <value>’ to command the program (’0 0’ to exit)
> 8232 20
(./rtos-hw2) warning - command not correct (accepted values [1-10])
Enter ’<process pid> <value>’ to command the program (’0 0’ to exit)
> 8232 2
(./rtos-hw2) P:8232 sent a sync(2)
(./rtos-hw2) server received a sync(2) from P:8232
Enter ’<process pid> <value>’ to command the program (’0 0’ to exit)
> 8233 5
(./rtos-hw2) P:8233 sent a sync(5)
(./rtos-hw2) server received a sync(5) from P:8233
Enter ’<process pid> <value>’ to command the program (’0 0’ to exit)
> 8233 9
(./rtos-hw2) warning - could not send packet to 16689! Is it already blocked?
Enter ’<process pid> <value>’ to command the program (’0 0’ to exit)
> 8236 7
(./rtos-hw2) Q:8236 sent an admit(7)
(./rtos-hw2) server received a request for admit(7)
(./rtos-hw2) server sent WAKE UP to process 8232
(./rtos-hw2) server sent WAKE UP to process 8233
(./rtos-hw2) P:8232 has been woken up!
(./rtos-hw2) P:8233 has been woken up!
Enter ’<process pid> <value>’ to command the program (’0 0’ to exit)
> 0 0
Closing interface and program. Goodbye!
(./rtos-hw2) info - received signal number 15. Closing server and processes.
Random generation While the previous example was generated through the interface, this test
show a similar functionality but with random generation of values, as well as with a greater number
of processes involved.
From the point of view of functionality, there is not much differnce from the first test case,
apart from the generation of a wrong sync value. This value is detected right away and discarded.
Process Q can autonomously generate an higher value than allowed just to test this case.
10
(./rtos-hw2) server received a sync(1) from P:8306
(./rtos-hw2) P:8307 sent a sync(2)
(./rtos-hw2) server received a sync(2) from P:8307
(./rtos-hw2) P:8308 sent a sync(3)
(./rtos-hw2) server received a sync(3) from P:8308
(./rtos-hw2) P:8309 sent a sync(4)
(./rtos-hw2) server received a sync(4) from P:8309
(./rtos-hw2) P:8303 sent a sync(6)
(./rtos-hw2) server received a sync(6) from P:8303
(./rtos-hw2) P:8304 sent a sync(7)
(./rtos-hw2) server received a sync(7) from P:8304
(./rtos-hw2) P:8305 sent a sync(8)
(./rtos-hw2) server received a sync(8) from P:8305
(./rtos-hw2) Q:8310 sent an admit(10)
(./rtos-hw2) server received a request for admit(10)
(./rtos-hw2) server sent WAKE UP to process 8303
(./rtos-hw2) server sent WAKE UP to process 8306
(./rtos-hw2) server sent WAKE UP to process 8307
(./rtos-hw2) P:8303 has been woken up!
(./rtos-hw2) P:8306 has been woken up!
(./rtos-hw2) P:8307 has been woken up!
(./rtos-hw2) P:8303 sent a sync(11)
(./rtos-hw2) warning - wrong weight value for 8303 (received: 11)
(./rtos-hw2) P:8306 sent a sync(5)
(./rtos-hw2) server received a sync(5) from P:8306
(./rtos-hw2) P:8307 sent a sync(6)
(./rtos-hw2) server received a sync(6) from P:8307
(./rtos-hw2) P:8303 sent a sync(2)
(./rtos-hw2) server received a sync(2) from P:8303
(./rtos-hw2) Q:8310 sent an admit(14)
(./rtos-hw2) server received a request for admit(14)
(./rtos-hw2) server sent WAKE UP to process 8304
(./rtos-hw2) server sent WAKE UP to process 8308
(./rtos-hw2) server sent WAKE UP to process 8309
(./rtos-hw2) P:8304 has been woken up!
(./rtos-hw2) P:8308 has been woken up!
(./rtos-hw2) P:8309 has been woken up!
(./rtos-hw2) P:8304 sent a sync(3)
(./rtos-hw2) server received a sync(3) from P:8304
(./rtos-hw2) P:8308 sent a sync(7)
(./rtos-hw2) server received a sync(7) from P:8308
(./rtos-hw2) P:8309 sent a sync(8)
(./rtos-hw2) server received a sync(8) from P:8309
(./rtos-hw2) Q:8310 sent an admit(9)
(./rtos-hw2) server received a request for admit(9)
(./rtos-hw2) server sent WAKE UP to process 8305
(./rtos-hw2) P:8305 has been woken up!
(./rtos-hw2) P:8305 sent a sync(4)
(./rtos-hw2) server received a sync(4) from P:8305
11
No blocked processes This test show that after every process has been activated, it may happen
that Q asks for another admit; the server is capable of handling this situation warning that no
blocked processes are present.
Blocked processes, admit value too little In this test a P process (8063) is stopped with an high
weight; then Q asks for low value admit. The server detects the blocked process but can’t correctly
acativate it.
12
Since by hypothesis an admit is executed every 50 ns and there are 4 process, the maximum
wait time for any process PI is given by:
2. Pi has the highest priority but there is another process with same priority (Pj );
3. Pi has the highest priority but there are other two processes with same priority (Pj , Pk );
4. Pi has the highest priority but there are other three processes with same priority (Pj , Pk , Pl ).
1. no wait;
It has been computed that the probability for the last three to happen is 50%, 69% and 96%
respectively.
Since it has been supposed that the processes are independent between each other, it is possible
to compute a mean probability of 71,6%.
Finally, to compute the mean time waiting it is sufficient to compute
13
Function Execution Time
sync() 28.2 µs
admit() 15.4 µs
14