Thread.Schedule Shared Method

Changes the execution priority and thread scheduling algorithm for the current thread.

Thread.Schedule(priority, period, high_priority_time, phase)

Prerequisites

None

Parameters

priority

A required numeric expression that evaluates to an Integer that specifies a new execution priority for the current thread. This value can range from 0 to 16. A value of 0 specifies that the current thread is to execute at the normal user thread priority and using the standard thread scheduling. Values > 0 specify a higher than normal priority using an alternate scheduling algorithm. Larger values indicate higher execution priority.

period

A required numeric expression that evaluates to a Double value that specifies the scheduling repetition rate in milliseconds. This value must be an even power of 2, multiplied by 0.125 msec, and greater than 0.125. Valid values are: 0.250, 0.5, 1.0, 2.0, 4.0, 8.0, 16.0, etc. This value is ignored if priority is zero.

high_priority_time

A required numeric expression that evaluates to a Double value that specifies the duration, in milliseconds, during which the thread runs at the priority level. This value must be greater than zero and less than the period parameter. It may be a fractional value and will be quantized to a multiple of 0.125. This value is ignored if priority is zero.

phase

A required numeric expression that evaluates to a Double value that specifies the phase offset, in milliseconds, when the thread begins to runs at the priority level. This value must be non-negative and less than the period parameter. It may be a fractional value and will be quantized to a multiple of 0.125. The trajectory generator thread always runs at phase offset 0. This value is ignored if priority is zero.

Remarks

This shared method is associated with the Thread class, not a specific Thread Object. This method allows a thread to change when it executes (how it is scheduled) relative to other threads. This allows a thread to run more often or with greater regularity than it would otherwise run. However, since the GPL system contains a number of system threads that can never be preempted by user threads, the response of a user thread cannot be absolutely guaranteed. The standard thread scheduling algorithm for normal user threads is a simple round-robin scheme where each standard thread gets to run for one millisecond before it is moved to the back of the list of all other standard threads. User threads compete with each other and with standard and higher-priority system threads as shown in Table 19-105. If the system is heavily loaded, a given user thread may only get to run for 1 out of 8 or more milliseconds. That may be undesirable for time-critical applications.

Table 19-105: Schedule Shared Method

Thread Priority Thread Type Specific Threads

> 16 (Highest)

High-Priority System Threads

Servos, trajectory generator, most device drivers

1-16 (High)

User Threads that execute Thread.Schedule

User Threads that execute Thread.Schedule

0 (Standard)

Standard Priority Threads

Standard user threads, web server, FTP, serial console, disk driver

An alternate scheduling algorithm, enabled by the Thread.Schedule method, allows a critical user thread to run in a timely manner, ahead of all other standard-priority threads. This algorithm is based on the POSIX sporadic scheduling policy, with the addition of a phase parameter. The algorithm schedules threads as follows:

  1. Every period milliseconds, offset by phase, a high priority user thread has its priority raised to the priority level above the standard thread priority.
  2. After the thread has run for high_priority_time milliseconds, the thread's priority is returned to the standard level, and it is placed at the end of the round-robin queue of standard-level threads.
  3. The thread may run at standard priority if it gets to the front of the round-robin queue before the start of its next high priority period.

The diagrams below show how the Thread.Schedule method affects thread execution. In these examples, we assume there are four user threads that are executing continuously. Figure 19-9 shows standard round-robin scheduling where each vertical division represents 125 usec.

Figure 19-9: Thread Schedule Method, Time in Milliseconds

Each thread runs for 1 msec, which consists of eight 125 µsec clock ticks. At the end of the 1 msec, the next thread begins, and the previous one goes to the end of the queue.

Figure 19-10 shows the results of Thread C issuing Thread.Schedule(1, 2, 0.25, 1).

Figure 19-10: Thread Schedule Method, Time in Milliseconds

This diagram shows Thread C having its priority raised every 2 msec, with a phase offset of 1 msec. So it runs at times 1, 3, 5, and 7. The thread's priority remains high for 0.25 msec (or 2 clock ticks). At the end of each interval, the thread's priority drops back to the standard value and the thread is placed at the end of the round-robin queue. The other threads each continue to run for a total of 1 msec each. Note that the real time from the start of Thread D at time 2.25 to the end of Thread D at 3.5, greater than 1 msec because Thread C preempts Thread D for 2 ticks.

Figure 19-11 shows the results of Thread C issuing Thread.Schedule(1, 4, 0.25, 0.5).

Figure 19-11: Thread Schedule Method, Time in Milliseconds

This diagram shows Thread C having it priority raised every 4 msec, with a phase offset of 0.5 msec. So it runs at times 0.5 and 4.5. The thread priority remains high for 0.25 msec (or 2 clock ticks). At the end of each interval, the thread's priority drops back to the standard value and the thread is placed at the end of the round-robin queue. The other threads each continue to run for a total of 1 msec each. Note that at time 3.25, Thread C runs at its normal priority because all the other threads in the round-robin queue ran after Thread C completed at time 0.75. Thread C still runs at high priority at time 4.5, its next scheduling interval. Thread.Schedule can be used to synchronize a thread with the trajectory generator when doing procedural motions or using the Move.SetRealTimeMod method. See the Examples section below.

Additional notes and cautions:

Examples

' Synchronize with the trajectory generator.
' Set period to be same as trajectory generator.
Thread.Schedule(1, Controller.Tick * 1000, 0.5, 0)
While True
... ' Compute trajectory changes
Move.SetRealTimeMod(changes)
Controller.SleepTick(1) ' Wait until next trajectory tick
End While

See Also

Thread Class| Thread.Sleep | Controller.SleepTick | Move.SetRealTimeMod