rtai-core/sched/rtai/sched_up.c File Reference


Detailed Description

Scheduling function for uni-processor.

Author:
Paolo Mantegazza
This file is part of the RTAI project.

Note:
Copyright (C) 1999-2003 Paolo Mantegazza <mantegazza@aero.polimi.it>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

Include dependency graph for sched_up.c:

Include dependency graph

Functions

int rt_task_init (RT_TASK *task, void(*rt_thread)(int), int data, int stack_size, int priority, int uses_fpu, void(*signal)(void))
int rt_task_init_cpuid (RT_TASK *task, void(*rt_thread)(int), int data, int stack_size, int priority, int uses_fpu, void(*signal)(void), unsigned int cpuid)
void rt_set_runnable_on_cpus (RT_TASK *task, unsigned long runnable_on_cpus)
 Assign CPUs to a task.

void rt_set_runnable_on_cpuid (RT_TASK *task, unsigned int cpuid)
 Assign CPUs to a task.

void rt_sched_lock (void)
 Lock the scheduling of tasks.

void rt_sched_unlock (void)
 Unlock the scheduling of tasks.

int rt_task_delete (RT_TASK *task)
void rt_set_periodic_mode (void)
 Set timer mode.

void rt_set_oneshot_mode (void)
 Set timer mode.

RTIME start_rt_timer (int period)
 Start timer.

void start_rt_apic_timers (struct apic_timer_setup_data *setup_mode, unsigned int rcvr_jiffies_cpuid)
 Start local apic timer.

void stop_rt_timer (void)
 Stop timer.

void rt_preempt_always (int yes_no)
 Enable hard preemption.

void rt_preempt_always_cpuid (int yes_no, unsigned int cpuid)
 Enable hard preemption.

RTIME count2nano (RTIME counts)
 Convert internal count units to nanoseconds.

RTIME nano2count (RTIME ns)
 Convert nanoseconds to internal count units.

RTIME count2nano_cpuid (RTIME counts, unsigned int cpuid)
 Convert internal count units to nanoseconds.

RTIME nano2count_cpuid (RTIME ns, unsigned int cpuid)
 Convert nanoseconds to internal count units.

RTIME rt_get_time (void)
 Get the current time.

RTIME rt_get_time_cpuid (unsigned int cpuid)
 Get the current time.

RTIME rt_get_time_ns (void)
 Get the current time.

RTIME rt_get_time_ns_cpuid (unsigned int cpuid)
 Get the current time.

RTIME rt_get_cpu_time_ns (void)
 Get the current time.


Function Documentation

RTIME count2nano RTIME  counts  ) 
 

Convert internal count units to nanoseconds.

This function converts the time of timercounts internal count units into nanoseconds. Remember that the count units are related to the time base being used (see functions rt_set_oneshot_mode() and rt_set_periodic_mode() for an explanation).

Parameters:
counts internal count units.
Returns:
The given time in nanoseconds is returned.

RTIME count2nano_cpuid RTIME  counts,
unsigned int  cpuid
 

Convert internal count units to nanoseconds.

This function converts the time of timercounts internal count units into nanoseconds. It is to be used with the MUP scheduler since with such a scheduler it is possible to have independent timers, i.e. periodic of different periods or a mixing of periodic and oneshot, so that it is impossible to establish which conversion units should be used in the case one asks for a conversion from any CPU for any other CPU. All these functions have the same behavior with UP and SMP schedulers.

Parameters:
counts internal count units.
cpuid Identifier of the CPU (FIXME).
Returns:
The given time in nanoseconds is returned.

RTIME nano2count RTIME  ns  ) 
 

Convert nanoseconds to internal count units.

This function converts the time of nanosecs nanoseconds into internal counts units. Remember that the count units are related to the time base being used (see functions rt_set_oneshot_mode() and rt_set_periodic_mode() for an explanation).

The versions ending with_cpuid are to be used with the MUP scheduler since with such a scheduler it is possible to have independent timers, i.e. periodic of different periods or a mixing of periodic and oneshot, so that it is impossible to establish which conversion units should be used in the case one asks for a conversion from any CPU for any other CPU. All these functions have the same behavior with UP and SMP schedulers.

Parameters:
ns Number of nanoseconds.
Returns:
The given time in nanoseconds is returned.

RTIME nano2count_cpuid RTIME  ns,
unsigned int  cpuid
 

Convert nanoseconds to internal count units.

This function converts the time of nanosecs nanoseconds into internal counts units. Remember that the count units are related to the time base being used (see functions rt_set_oneshot_mode() and rt_set_periodic_mode() for an explanation).

This function is to be used with the MUP scheduler since with such a scheduler it is possible to have independent timers, i.e. periodic of different periods or a mixing of periodic and oneshot, so that it is impossible to establish which conversion units should be used in the case one asks for a conversion from any CPU for any other CPU. All these functions have the same behavior with UP and SMP schedulers.

Parameters:
ns Number of nanoseconds.
cpuid Identifier of the CPU (FIXME).
Returns:
The given time in nanoseconds is returned.

RTIME rt_get_cpu_time_ns void   ) 
 

Get the current time.

rt_get_cpu_time_ns always returns the CPU time in nanoseconds whatever timer is in use.

Returns:
The current time in internal count units is returned.

RTIME rt_get_time void   ) 
 

Get the current time.

rt_get_time returns the time, in internal count units, since start_rt_timer was called. In periodic mode this number is in multiples of the periodic tick. In oneshot mode it is directly the TSC count for CPUs having a time stamp clock (TSC), while it is a (FIXME) on 8254 units for those not having it (see functions rt_set_oneshot_mode() and rt_set_periodic_mode() for an explanation).

Returns:
The current time in internal count units is returned.

RTIME rt_get_time_cpuid unsigned int  cpuid  ) 
 

Get the current time.

rt_get_time_cpuid returns the time, in internal count units, since start_rt_timer was called. In periodic mode this number is in multiples of the periodic tick. In oneshot mode it is directly the TSC count for CPUs having a time stamp clock (TSC), while it is a (FIXME) on 8254 units for those not having it (see functions rt_set_oneshot_mode() and rt_set_periodic_mode() for an explanation). This version ending with _cpuid must be used with the MUP scheduler when there is the need to declare from which cpuid the time must be gotten (FIXME). In fact one can need to get the time of another CPU and timers can differ from CPU to CPU. (FIXME) All these functions have the same behavior with UP and SMP schedulers.

Parameters:
cpuid corresponds to the CPUI identifier.
Returns:
The current time in internal count units is returned.

RTIME rt_get_time_ns void   ) 
 

Get the current time.

rt_get_time_ns is the same as rt_get_time() but the returned time is converted to nanoseconds.

Returns:
The current time in internal count units is returned.

RTIME rt_get_time_ns_cpuid unsigned int  cpuid  ) 
 

Get the current time.

rt_get_time_ns is the same as rt_get_time but the returned time is converted to nanoseconds. The version ending with _cpuid must be used with the MUP scheduler when there is the need to declare from which cpuidthe time must be got. In fact one can need to get the time of another CPU and timers can differ from CPU to CPU. All these functions have the same behavior with UP and SMP schedulers.

Parameters:
cpuid corresponds to the CPUI identifier.
Returns:
The current time in internal count units is returned.

void rt_preempt_always int  yes_no  ) 
 

Enable hard preemption.

In the oneshot mode the next timer expiration is programmed after a timer shot by choosing among the timed tasks the one with a priority higher than the task chosen to run as current, with the constraint of always assuring a correct Linux timing. In such a view there is no need to fire the timer immediately. In fact it can happen that the current task can be so fast to get suspended and rerun before the one that was devised to time the next shot when it was made running. In such a view RTAI schedulers try to shoot only when strictly needed. This minimizes the number of slow setups of the 8254 timer used with UP and 8254 based SMP schedulers. While such a policy minimizes the number of actual shots, greatly enhancing efficiency, it can be unsuitable when an application has to be guarded against undesired program loops or other unpredicted error causes. Calling these functions with a nonzero value assures that a timed high priority preempting task is always programmed to be fired while another task is currently running. The default is no immediate preemption in oneshot mode, i.e. firing of the next shot programmed only when strictly needed to satisfy tasks timings.

Note:
With UP and SMP schedulers there is always only a timing source so that cpu_idinrt_preempt_always_cpuid is not used. With the MUP scheduler you have an independent timer for each CPU, so rt_preempt_always applies to all the CPUs while rt_preempt_always_cpuid should be used when preemption is to be forced only on a specific CPU.

void rt_preempt_always_cpuid int  yes_no,
unsigned int  cpuid
 

Enable hard preemption.

In the oneshot mode the next timer expiration is programmed after a timer shot by choosing among the timed tasks the one with a priority higher than the task chosen to run as current, with the constraint of always assuring a correct Linux timing. In such a view there is no need to fire the timer immediately. In fact it can happen that the current task can be so fast to get suspended and rerun before the one that was devised to time the next shot when it was made running. In such a view RTAI schedulers try to shoot only when strictly needed. This minimizes the number of slow setups of the 8254 timer used with UP and 8254 based SMP schedulers. While such a policy minimizes the number of actual shots, greatly enhancing efficiency, it can be unsuitable when an application has to be guarded against undesired program loops or other unpredicted error causes. Calling these functions with a nonzero value assures that a timed high priority preempting task is always programmed to be fired while another task is currently running. The default is no immediate preemption in oneshot mode, i.e. firing of the next shot programmed only when strictly needed to satisfy tasks timings.

Note:
With UP and SMP schedulers there is always only a timing source so that cpu_idinrt_preempt_always_cpuid is not used. With the MUP scheduler you have an independent timer for each CPU, so rt_preempt_always applies to all the CPUs while rt_preempt_always_cpuid should be used when preemption is to be forced only on a specific CPU.

void rt_sched_lock void   ) 
 

Lock the scheduling of tasks.

rt_sched_lock, lock on the CPU on which they are called, any scheduler activity, thus preventing a higher priority task to preempt a lower priority one. They can be nested, provided unlocks are paired to locks in reversed order. It can be used for synchronization access to data among tasks. Note however that under MP the lock is active only for the CPU on which it has been issued, so it cannot be used to avoid races with tasks that can run on any other available CPU. Interrupts are not affected by such calls. Any task that needs rescheduling while a scheduler lock is in placewill be only at the issuing of the last unlock

Note:
To be used only with RTAI24.x.xx.
See also: rt_sched_unlock().

void rt_sched_unlock void   ) 
 

Unlock the scheduling of tasks.

rt_sched_unlock, unlock on the CPU on which they are called, any scheduler activity, thus preventing a higher priority task to preempt a lower priority one. They can be nested, provided unlocks are paired to locks in reversed order. It can be used for synchronization access to data among tasks. Note however that under MP the lock is active only for the CPU on which it has been issued, so it cannot be used to avoid races with tasks that can run on any other available CPU. Interrupts are not affected by such calls. Any task that needs rescheduling while a scheduler lock is in placewill be only at the issuing of the last unlock

Note:
To be used only with RTAI24.x.xx.
See also: rt_sched_unlock().

void rt_set_oneshot_mode void   ) 
 

Set timer mode.

rt_set_periodic_mode sets the periodic mode for the timer. It consists of a fixed frequency timing of the tasks in multiple of the period set with a call to start_rt_timer(). The resolution is that of the 8254 (1193180 Hz) on a UP machine, or if the 8254 based SMP scheduler is being used. For the SMP scheduler timed by the local APIC timer and for the MUP scheduler the timer resolution is that of the local APIC timer frequency, generally the bus frequency divided 16. Any timing request not being an integer multiple of the set timer period is satisfied at the closest period tick. It is the default mode when no call is made to set the oneshot mode.

Note:
Stopping the timer by stop_rt_timer() sets the timer back into its default (periodic) mode. Always call rt_set_oneshot_mode() before each start_rt_timer() if you want to be sure to have it oneshot on multiple insmod without rmmoding the RTAI scheduler in use.

void rt_set_periodic_mode void   ) 
 

Set timer mode.

rt_set_periodic_mode sets the periodic mode for the timer. It consists of a fixed frequency timing of the tasks in multiple of the period set with a call to start_rt_timer(). The resolution is that of the 8254 (1193180 Hz) on a UP machine, or if the 8254 based SMP scheduler is being used. For the SMP scheduler timed by the local APIC timer and for the MUP scheduler the timer resolution is that of the local APIC timer frequency, generally the bus frequency divided 16. Any timing request not being an integer multiple of the set timer period is satisfied at the closest period tick. It is the default mode when no call is made to set the oneshot mode.

Note:
Stopping the timer by stop_rt_timer() sets the timer back into its default (periodic) mode. Always call rt_set_oneshot_mode() before each start_rt_timer() if you want to be sure to have it oneshot on multiple insmod without rmmoding the RTAI scheduler in use.

void rt_set_runnable_on_cpuid RT_TASK *  task,
unsigned int  cpuid
 

Assign CPUs to a task.

rt_set_runnable_on_cpuid select one or more CPUs which are allowed to run task task.

rt_set_runnable_on_cpuid assigns a task to a single specific CPU. If no CPU, as selected by cpu_mask or cpuid, is available, both functions choose a possible CPU automatically, following the same rule as above.

Note:
This call has no effect on UniProcessor (UP) systems.
See also: rt_set_runnable_on_cpus().

void rt_set_runnable_on_cpus RT_TASK *  task,
unsigned long  runnable_on_cpus
 

Assign CPUs to a task.

rt_set_runnable_on_cpus selects one or more CPUs which are allowed to run task task. rt_set_runnable_on_cpus behaves differently for MUP and SMP schedulers. Under the SMP scheduler bit<n> of cpu_mask enables the task to run on CPU<n>. Under the MUP scheduler it selects the CPU with less running tasks among those allowed by cpu_mask. Recall that with MUP a task must be bounded to run on a single CPU. If no CPU, as selected by cpu_mask or cpuid, is available, both functions choose a possible CPU automatically, following the same rule as above.

Note:
This call has no effect on UniProcessor (UP) systems.
See also: rt_set_runnable_on_cpuid().

int rt_task_delete RT_TASK *  task  ) 
 

Delete a real time task.

rt_task_delete deletes a real time task previously created by rt_task_init() or rt_task_init_cpuid().

Parameters:
task is the pointer to the task structure. If task task was waiting on a queue, i.e. semaphore, mailbox, etc, it is removed from such a queue and messaging tasks pending on its message queue are unblocked with an error return.
Returns:
0 on success. A negative value on failure as described below:
  • EINVAL: task does not refer to a valid task.

int rt_task_init RT_TASK *  task,
void(*  rt_thread)(int),
int  data,
int  stack_size,
int  priority,
int  uses_fpu,
void(*  signal)(void)
 

Creates a new real time task.

The newly created real time task is initially in a suspend state. It can be made active by calling: rt_task_make_periodic, rt_task_make_periodic_relative_ns, rt_task_resume.

When used with the MUP scheduler rt_task_init automatically selects which CPU the task will run on, while with the SMP scheduler the task defaults to using any of the available CPUs. This assignment may be changed by calling rt_set_runnable_on_cpus.

Parameters:
task is a pointer to an RT_TASK type structure whose space must be provided by the application. It must be kept during the whole lifetime of the real time task.
rt_thread is the entry point of the task function.
data The parent task can pass a single integer value data to the new task being created. Recall that an appropriately type casting allows data to be a pointer to whatever data structure one would like to pass to the task, so you can indirectly pass whatever you want to the task.
stack_size is the size of the stack to be used by the new task. In sizing it, recall to make room for any real time interrupt handler, as real time interrupts run on the stack of the task they interrupt. So try to avoid being too sparing.
priority is the priority to be given to the task. The highest priority is 0, while the lowest is RT_SCHED_LOWEST_PRIORITY.
uses_fpu is a flag. A nonzero value indicates that the task will use the floating point unit.
signal is a function that is called, within the task environment and with interrupts disabled, when the task becomes the current running task after a context switch. Note however that signal is not called at the very first scheduling of the task. Such a function can be assigned and/or changed dynamically whenever needed (see function rt_task_signal_handler.)
Returns:
0 on success. A negative value on failure as described below:
  • EINVAL: task structure pointed by task is already in use;
  • ENOMEM: stack_size bytes could not be allocated for the stack.
See also: rt_task_init_cpuid().

int rt_task_init_cpuid RT_TASK *  task,
void(*  rt_thread)(int),
int  data,
int  stack_size,
int  priority,
int  uses_fpu,
void(*  signal)(void),
unsigned int  cpuid
 

Creates a new real time task and assigns it to a single specific CPU.

The newly created real time task is initially in a suspend state. It can be made active by calling: rt_task_make_periodic, rt_task_make_periodic_relative_ns, rt_task_resume.

When used with the MUP scheduler rt_task_init automatically selects which CPU the task will run on, while with the SMP scheduler the task defaults to using any of the available CPUs. This assignment may be changed by calling rt_set_runnable_on_cpus or rt_set_runnable_on_cpuid. If cpuid is invalid rt_task_init_cpuid falls back to automatic CPU selection.

Whatever scheduler is used on multiprocessor systems rt_task_init_cpuid allows to create a task and assign it to a single specific CPU cpuid from its very beginning, without any need to call rt_set_runnable_on_cpuid later on.

Parameters:
task is a pointer to an RT_TASK type structure whose space must be provided by the application. It must be kept during the whole lifetime of the real time task.
rt_thread is the entry point of the task function.
data The parent task can pass a single integer value data to the new task being created. Recall that an appropriately type casting allows data to be a pointer to whatever data structure one would like to pass to the task, so you can indirectly pass whatever you want to the task.
stack_size is the size of the stack to be used by the new task. In sizing it recall to make room for any real time interrupt handler, as real time interrupts run on the stack of the task they interrupt. So try to avoid being too sparing.
priority is the priority to be given to the task. The highest priority is 0, while the lowest is RT_SCHED_LOWEST_PRIORITY.
uses_fpu is a flag. A nonzero value indicates that the task will use the floating point unit.
signal is a function that is called, within the task environment and with interrupts disabled, when the task becomes the current running task after a context switch. Note however that signal is not called at the very first scheduling of the task. Such a function can be assigned and/or changed dynamically whenever needed (see function rt_task_signal_handler.)
cpuid FIXME
Returns:
0 on success. A negative value on failure as described below:
  • EINVAL: task structure pointed by task is already in use;
  • ENOMEM: stack_size bytes could not be allocated for the stack.
See also: rt_task_init().

void start_rt_apic_timers struct apic_timer_setup_data *  setup_mode,
unsigned int  rcvr_jiffies_cpuid
 

Start local apic timer.

start_rt_apic_timers starts local APIC timers according to what is found in setup_data.

Parameters:
setup_mode is a pointer to an array of structures apic_timer_setup_data, see function rt_setup_apic_timers (FIXME) in RTAI module functions described further on in this manual.
rcvr_jiffies_cpuid is the CPU number whose time log has to be used to keep Linux timing and pacing in tune. This function is specific to the MUP scheduler. If it is called with either the UP or SMP scheduler it will use:
  • a periodic timer if all local APIC timers are periodic with the same period;
  • a oneshot timer if all the local APIC timers are oneshot, or have different timing modes, are periodic with different periods.

RTIME start_rt_timer int  period  ) 
 

Start timer.

start_rt_timer starts the timer with a period period. The period is in internal count units and is required only for the periodic mode. In the oneshot mode the period value is ignored. This functions uses the 8254 with the UP and the 8254 based SMP scheduler. Otherwise it uses a single local APIC with the APIC based SMP schedulers and an APIC for each CPU with the MUP scheduler. In the latter case all local APIC timers are paced in the same way, according to the timer mode set.

Returns:
The period in internal count units.

void stop_rt_timer void   ) 
 

Stop timer.

stop_rt_timer stops the timer. The timer mode is set to periodic.

Returns:
The period in internal count units.


Generated on Sat Jul 24 19:36:17 2004 for RTAI API by doxygen 1.3.4