robotology/yarp — pull request #247 by apaikan (2014-10-17 16:54:38+00:00)
Title: Prioritized thread

Adjusting communication thread priority via port admin commands
------------------------------------------------------------------------------------
Shortly, we wan to have a way to adjust the priorities of threads which handle communication in PortCorUnits. This is important when we want to give priority to a specific communication among processes. Imagine a `sender` module sends data to two different receivers (`receiver1` and `receiver2`) using a single BufferedPort. For now, assume that all the modules are running on the same machine. As we know, Yarp instantiates two separate threads (i.e. PortCoreOutputUnit), each one handling a connections (`C1`, `C2`) to the receivers.
Now Imagine, we want to minimize the latency of the data packet which passes through `C1` to the `receiver1` when the system is overly loaded. This means that, we may have more delay in `C2` but for my specific application, it is important to get the `C1` always close to the real-time (less delay). In very simple case, the priority of the PortCoreOutputUnit's thread which handles `C1` should be higher than thread for `C2`.

1. To do this, I have elaborated a bit the Thread::setPriorirty() function to be able to set the real-time priority of threads on POSIX machines by setting also the scheduling policy too. This works on windows machine (obviously the thread policy is not used on windows) and ACE will adjust the windows thread priority according the current priority class. This can be investigated better in windows later.

2. I have modified the admin block from PortCore to interpret the admin messages to be able to adjust the priority of PortCoreUnits via (`yarp admin rpc`) at run-time. This can be applied to both side of a connection. If the PortCoreUnit is not threaded (i.e. when using a Port on sender side), the prioritizing is simply omitted. However, this can be also achieved, for example, by increasing the priority of the main thread.

To test the implementation,
- open a terminal and `$ yarp write /w`
- in another terminal `$ yarp read /r`
- in another one '$ yarp connect /w /r'
- use `top -H` or `htop` to see the priority of the child threads of the `yarp read /r` process which is normal as the others (20). Notice that `yarp write` does not use BufferedPort and there is not any dedicated thread to handle the communication.
- now open a new terminal and `$ echo "prop set /w (sched ((priority 30) (policy 1)))" | yarp admin rpc /r`
- Check again the priority of child threads of the `yarp read /r` and you will see that one of them has changed accordingly which is the one handles data transmission (believe me is the one :p).

The command `prop set /w (sched ((priority 30) (policy 1)))` indicate that the priority of the thread of a PortCoreUnit (in this case /w) should be set to 30 using scheduling policy 1 which is SCHED_FIFO in Linux machines. if the policy is not set, then only the priority within the current policy/class of the thread will be set. The following combination are valid on most Linux machine:
`SCHED_OTHER : policy=0, priority=[0 .. 0]`
`SCHED_FIFO : policy=1, priority=[1 .. 99]`
`SCHED_RR : policy=2, priority=[1 .. 99]`

Adjusting thread priority/policy relies on ACE and the priority values are highly platform dependent (mentioned also in ACE documentation).