# An overview of RTAI schedulers.

RTAI has a UniProcessor (UP) specific scheduler and two for MultiProcessors (MP). In the latter case you can chose between a symmetricMultiProcessor (SMP) and a MultiUniProcessor (MUP) scheduler.

The UP scheduler can be timed only by the 8254 timer and cannot be used with MPs.

The SMP scheduler can be timed either by the 8254 or by a local APIC timer. In SMP/8254 tasks are defaulted to work on any CPU but you can assign them to any subset, or to a single CPU, by using the function "rt_set_runnable_on_cpus". It is also possible to assign any real time interrupt service to a specific cpu by using "rt_assign_irq_to_cpu" and "rt_reset_irq_to_sym_mode". Thus a user can statically optimize his/her application if he/she believes that it can be better done than using a symmetric load distribution. The possibility of forcing any interrupts to a specific CPU is clearly not related to the SMP scheduler and can be used also with interrupt handlers alone. Note that only the real time interrupt handling is forced to a specific CPU. That means that if you check this feature by using "cat /proc/interrupts" for a real time interrupt that is chained to Linux, e.g. the timer when rtai_sched is installed, you can still see some interrupts distributed to all the CPUs, even if they are mostly on the assigned one. That is because Linux interrupts are kept symmetric by the RTAI dispatcher of Linux irqs. For the SMP/APIC based scheduler if you want to statically optimize the load distribution by binding tasks to specific CPUs it can be useful to use "rt_get_timer_cpu()" just after having installed the timer, to know which CPU is using its local APIC timer to pace the scheduler. Note that for the oneshot case that will be the main timing CPU but not the only one. In fact which local APIC is shot depends on the task scheduling out, as that will determine the next shooting.

SMP schedulers allow to chose between a periodic and a oneshot timer, not to be used together. The periodic ticking is less flexible but, with the usual PC hardware much more efficient. So it is up to you which one to choose in relation to the applications at hand. It should be noted that in the oneshot mode the time is measured on the base of the CPU time stamp clock (TSC) and neither on the 8254 chip nor on the local APIC timer, which are used only to generate oneshot interrupts. The periodic mode is instead timed by either the 8254 or the local APIC timers. If the 8254 is used slow I/Os to the ISA bus are limited as much as possible with a sizable gain in efficiency. The oneshot mode has just about 15-20% more overhead than the periodic one. The use of the local APIC timers leads to a further improvement and substantially less jitter. Remember that local APICs are hard disabled on UPs, unless you are using just one CPU on an MP motherboard. Experience with local APIC timers shows that there is no performance improvement for a periodic scheduling, except for a marginal reduced jitter, while the oneshot case gain is the sizable 10-15% mentioned above. In fact by using the TSC just two outb are required to reprogram the 8254, i.e. approximately 3 us, against almost nothing for the APIC timer. However you have to broadcast a message to all the CPUs in any case, and that is at least about more than 3 us, the APIC bus is an open drain 2 wires one and is not lightning like. Note that the performance loss of the 8254 is just a fraction of the overall task switching procedure, which is always substantially heavier in the oneshot case than in periodic mode. No doubt however that if you have an SMP motherboard, or a local APIC enabled anyhow, you should use the APIC SMP scheduler. Note however that in this case we have chosen not to bound the timer to a specific CPU. Nonetheless, as recalled above, you can still optimise the static binding of your task by using the function "rt_get_timer_cpu()" which allows you to know which local APIC is timing your application so that you can "rt_set_runnable_on_cpus" any task accordingly. See README in "smpscheduler".

Since the TSC is not available on 486 machines for them we use a form of emulation of the "read time stamp clock" (rdtsc) assembler instruction based on counter2 of the 8254. So you can use RTAI also on such machines. Be warned that the oneshot timer on 486 is a performance overkill because of the need of reading the tsc, i.e. 8254 counter2 in this case, 2/3 times. That can take 6- 8 us, i.e. more than it takes for a full switch among many tasks while using a periodic timer. Thus only a few khz period is viable, at most, for real time tasks if you want to keep Linux alive. No similar problems exist for the periodic timer that needs not to use any TSC at all. So, compared to the 20% cited above, the real time performance ratio of the oneshot/periodic timer efficiency ratio can be very low on 486 machines. Moreover it will produce far worse jitters than those caused on Pentiums and upward machines. If you really need a oneshot timer buy at least a Pentium. Instead, for a periodic timing 486s can still be more than adequate for many applications.

The MUP scheduler instead derives its name by the fact that real time tasks MUST be bound to a single CPU at the very task initialization. They can be afterward moved by using functions rt_set_runnable_on_cpus and rt_set_runnable_on_cpuid. The MUP scheduler can however use inter CPUs services related to semaphores, messages and mailboxes. The advantage of using the MUP scheduler comes mainly from the possibility of using mixed timers simultaneously, i.e. periodic and oneshot, where periodic timers can be based on different periods, and of possibly forcing critical task on the CPU cache. With dual SMP machines we cannot say that there is a noticeable difference in efficiency. MUP has been developed primarily for our, not so fast, a few khz, PWM actuators, BANG-BANG air jet thrusters, coupled to a periodic scheduler. All the functions of UP and SMP schedulers are available in the MUP scheduler.