gnu.cajo.utils.extra
Class Scheduler

java.lang.Object
  extended by gnu.cajo.utils.extra.Scheduler
All Implemented Interfaces:
java.io.Serializable

public final class Scheduler
extends java.lang.Object
implements java.io.Serializable

This class is for scheduling the non-preemptive execution of tasks. The class creates a single thread, and will independently manange and run its loaded objects. The Scheduler accepts objects for scheduling, at any time during its existence. The scheduled object must implement no-arg, void slice() method, to be used as a time slice, in which to perform some fixed piece of functionality. The scheduler will provide the calling mechanism. An objectwith this type of method implementation will be considered a task for the purposes of this class.

The scheduler's purpose is to provide an exclusive thread of execution amongst the scheduled tasks. It will assure that only one of the tasks is running at any given time, therefore shared memory between the tasks cannot be corrupted by the scheduler due to synchronization problems.

All scheduler methods are properly synchronized, to allow task loading, unloading, and management, from other threads, as well as by the scheduled tasks themselves.

Up to 32 tasks can be loaded, at any given time, for scheduling. Once loaded, tasks can be scheduled to run in any, or all, of three ways; Synchronous, Triggered, or Asynchronous. The class implements three methods to flag a loaded task as such. The following is a description of the scheduling algorithm:

When a task is flagged as asynchronous, it will be run only when no tasks are flagged as synchronous, or triggered, at the start of its slice. Its asynchronous flag is not cleared when it is run, meaning until stopped, it will be run again automatically, as scheduling permits. Scheduling among multiple asynchronous flags is round-robbin, to ensure each an opportunity to run. This provides a method for scheduling low-priority tasks. Typically an asynchronous task will break its functionality into distinct pieces, and use a switch() type mechanism to execute only one piece per timeslice.

When a task is flagged as triggered, will run before any tasks flagged asynchronous, but only when no tasks are flagged as synchronous, at the start of its slice. The trigger flag is cleared when the task is run, meaning that unless re-flagged as triggered, it will not run again through the trigger scheduling algorithm. This provides an event-driven mode of execution, but at a lower priority than the synchronous mode.

When a task is flagged as synchronous, it will run before any triggered, or asynchronous flagged tasks are allowed to run. Its synchronous flag is also cleared when the task is run. Since the scheduling is not preemptive, any currently running task is allowed to complete. This flag provides the highest responsiveness to a synchronizing event.

The stop method is used to prevent the execution of any flagged task. General notes:

Note: This class supports serialisation. It will restart the scheduling task automatically on deserialisation. However, in order for serialisation to succeed, all of the loaded tasks must also be serialisable.

Version:
1.0, 01-Nov-99 Initial release
Author:
John Catherino
See Also:
Serialized Form

Constructor Summary
Scheduler()
          Nothing is performed in the constructor, since no tasks can be scheduled for execution until they have been loaded.
 
Method Summary
 void drop(int task)
          This method clears all scheduling flags for the indicated task, and also removes it from the table.
 int load(java.lang.Object task)
          This method accepts a task to be scheduled.
 boolean pending()
          The purpose of this function is to reduce event-driven task latency by allowing asynchronous tasks to voluntarily exit prematurely.
 boolean setEnabled(boolean enabled)
          This method will start, or suspend, the scheduler.
 boolean soon(int task)
          This method sets the triggered execution flag for a task.
 void stop(int task)
          This method clears all scheduling flags for indicated task.
 boolean sync(int task)
          This method sets the synchronous execution flag for a task.
 boolean wake(int task)
          This method sets the asynchronous execution flag for a task.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Scheduler

public Scheduler()
Nothing is performed in the constructor, since no tasks can be scheduled for execution until they have been loaded.

Method Detail

setEnabled

public boolean setEnabled(boolean enabled)
This method will start, or suspend, the scheduler. The scheduler will be started automatically when the first task is flagged for execution. The method is idempotent; therefore enabling an already enabled scheduler will cause no effect, just as disabling a currently disabled scheduler.

Parameters:
enabled - The flag to indicate if this is a startup, or suspend operation.
Returns:
true if successfully started or stopped, false if not for logical reasons, i.e. already stopped/started, no tasks running.

load

public int load(java.lang.Object task)
This method accepts a task to be scheduled. If the task is accepted, it is placed in the table, but will not be executed, until it is flagged for operation. If the execution of the task slice results in an exception, the task will be automatically dropped from the queue.

Parameters:
task - The task to attempt to schedule, it may be either local, remote, or even a proxy, when enabled.
Returns:
the index of the task in the table. The task table index is used in the scheduling methods.
Throws:
java.lang.IllegalArgumentException - If the task table is full.

sync

public boolean sync(int task)
This method sets the synchronous execution flag for a task. The flag will be cleared automatically, when the scheduler calls this task.

Parameters:
task - The index of the task in the table
Returns:
false if the task was already flagged, or not in the queue, else true if successfully flagged.
Throws:
java.lang.IllegalArgumentException - If the task table index is invalid.

soon

public boolean soon(int task)
This method sets the triggered execution flag for a task. It will be cleared just before passing execution on to the task.

Parameters:
task - The index of the task in the table
Returns:
true if successfully flagged, false if already flagged
Throws:
java.lang.IllegalArgumentException - If the task table index is invalid.

wake

public boolean wake(int task)
This method sets the asynchronous execution flag for a task. It will not be cleared when passing execution on to the task. The flag will retain its state, until disabled through the stop method.

Parameters:
task - The index of the task to be scheduled for continuous asynchronous execution.
Returns:
true if successfully flagged, false if already flagged.
Throws:
java.lang.IllegalArgumentException - If the task table index is invalid.

stop

public void stop(int task)
This method clears all scheduling flags for indicated task. The task will reamain in the table however. Note: to remove a task, use the drop method instead, it automatically calls stop, before removing the task from the table.

Parameters:
task - The index of the task in the table
Throws:
java.lang.IllegalArgumentException - If the task table index is invalid.

drop

public void drop(int task)
This method clears all scheduling flags for the indicated task, and also removes it from the table.

Parameters:
task - The index of the task to stop and remove from the table.
Throws:
java.lang.IllegalArgumentException - If the task table index is invalid.

pending

public boolean pending()
The purpose of this function is to reduce event-driven task latency by allowing asynchronous tasks to voluntarily exit prematurely. To improve responsiveness, asynchronous tasks could check this method, before going on to another functionally distinct section of its task execution. It is normally checked when the async task has some periodic extra work, if the method returns false, the extra work could be processed in its current slice.

Returns:
true if synchronous or triggered tasks have been flagged for execution, false if it is OK for the task to continue running a little longer.