JSR-282 SI 7:4 Provide an API to a) introduce a CPU-time clock b) support execution-time monitoring by allowing b1) the current, maximum and minimum CPU consumption of a schedulable object to be determined b2) the current, maximum and minimum CPU consumption of a processing group to be determined if the implementation supports CPU time monitoring. The CPU-time clock measures the execution time consumbed by a schedulable object since it was first release. The current, maximum and minimum values are on a per release basis. Last Updated: 17 July 2006 ---------------------------- Brief History of SI ------------------- Initially only b1) and b2) were proposed. This was extended to allow a). However, a) requires the RTSJ's support for multiple clocks to be to be fleshed out further. Also the topics of accuracy, jitter and the role of the feasability analysis has complicated the issues. The current proposal separates out the two areas. We can adopt both a) and b); neither a) or b); a) but not b) and b but not a). Summary: a) Support for CPU-Time Clocks: ---------------------------------------- a1) a subclass of the Clock class called CPUTimeClock a2) to the Clock class public static CPUTimeClock getCPUTimeClock() a3) to the Timer class // similar constructors will need to be added to the subclasses public Timer(RelativeTime resolution); public Timer(RelativeTime resolution, boolean isDaemon); public RelativeTime getResolution(); Summary: b) Support for execution-time monitoring --------------------------------------------------- b1) to the Schedulable interface (and the RealTimeThread and AsyncEventHandler classes). public RelativeTime getCurrentConsumption(current : RelativeTime); public RelativeTime getMaxConsumption(max : RelativeTime); public RelativeTime getMinConsumption(min : RelativeTime); b2) to the ProcessingGroupParameters class public RelativeTime getCurrentConsumption(current : RelativeTime); public RelativeTime getMaxConsumption(max : RelativeTime); public RelativeTime getMinConsumption(min : RelativeTime); b3) to the RealtimeSystems Class public static boolean costMonitoringSupported(); public static RelativeTime costMonitoringResolution(); -- If a) is not adopted public static integer costMonitoringAverageErrorMargin(); -- If a) is not adopted Specification References ----------------------- a) Section 10 Definitions, Section 10.1 a) Sections 5.1, 6.1 b) Section 6.11 Problem being address ------------------------------ Currently, the RTSJ supports an optional cost enforcement model (and the notion of processing groups) to help bound the impact a schedulable object (or group of schedulable objects) on other schedulable objects on the same platform. However, it provides no mechanisms whereby the actual amount of CPU time currently consumed by a schedulable object (or a processing group) can be obtained. Such information is often required when monitoring a system, along with maximum and minimum values. Proposed Solution ------------------ The proposed solution is given in two parts: a) The addition of CPU_Time clocks ---------------------------------- Definitions The CPU-Time clock: A clock that measures the execution time of schedulable objects. When read, it returns the execution time of the calling schedulable object. It is not possible to get the execution time of any other schedulable object. CPU Time (Execution Time): The time spent executing a schedulable object, including the time spent executing VM and system services on behalf of that schedulable object. CPU-Time clock resolution: the minimum time value interval that can be measured by the CPU-time clock. CPU-Time clock accuracy: the difference between the actual CPU-time consumed by a schedulable object and the value returned by its CPU-Time clock. This is the error margin associated with CPU-Time monitoring. The mechanism used to measure execution time is implementation defined. It is implementation defined which schedulable object, if any, is charged the execution time that is consumed by interrupt handlers and run-time services on behalf of the VM and system. API: a1) The CPUTimeClock class is defined as follows: public class CPUTimeClock extends Clock { public integer getAverageError(); public RelativeTime getEpochOffset(); public RelativeTime getResolution(); public AbsoluteTime getTime(); public AbsoluteTime getTime(AbsoluteTime time); public void setResolution(RelativeTime resolution); } The semantics of these methods are as follows: getEpochOffset : Throws UnsupportedOperationException. getResolution: returns the granularity of the CPU accounting. getTime: returns an AbsoluteTime indicating the amount of CPU time that the calling schedulable object has consumed since it was first released. setResolution: Throws UnsupportedOperationException. getAverageError: returns the average error margin for values read from the CPUTime clock as a +/- percentage. a2) The following method is added to the Clock class: public static CPUTimeClock getCPUTimeClock(); Returns a reference to a singleton of the CPUTimeClock class. Throws UnsupportedOperationException if CPU-Time Monitoring is not supported. The returned object act as a thread-local clock. All calls to it are associated with the calling schedulable object. A CPU-time clock can be used by the Timer classes to measure the passage of execution time and release asynchronous event handlers. Note 1: The timer is always associated with the clock of the schedulable object which created the timer Note 2: createReleaseParameters always returns AperiodicParameters. Note 3: Cost overrun handlers can now be implemented via the CPU Time clock and the appropriate timer. Note 4: The cost value given in the ReleaseParameters should be associated with the CPU clock. a3) The following methods are added to the Timer class public Timer(RelativeTime resolution); public Timer(RelativeTime resolution, boolean isDaemon); (similar constructors will needed to be added to the subclasses) public RelativeTime getResolution(); The semantics of these methods are as follows: The constructors allow a Timer to be created with a given resolution. The idea here is to allow a programmer to set a coarser granularity than that of the clock on which the timer is based. An implementation may (but does not have to) use this information to optimize performance. The method throws IllegalArgumentException if the requested resolution cannot be supported by the clock. getResolution returns the resolution of the Timer. This is usually the same as the resolution of the Clock on which it is based. For the real-time clock, they will be the same. For the CPU-time clock they may be different. b1) Determination of current CPU consumption of a schedulable object ------------------------------------------------------------------- Add the following thread-safe methods to the Schedulable interface (and the corresponding methods to the RealTimeThread and AsyncEventHandler classes). public RelativeTime getCurrentConsumption(current : RelativeTime); If current is null, returns a new RelativeTime value containing the amount of CPU time that has been consumed during the current release of the SO. If current is not null; update (and return) the given RelativeTime with the amount of CPU time that has been consumed during the currentSO's release. If the SO is between releases, return the value used in the last release. public RelativeTime getMaxConsumption(max : RelativeTime); If max is null, returns a new RelativeTime value containing the maximum amount of CPU time that has been consumed during any one release of the SO. If max is not null; update (and return) the given RelativeTime with the maximum amount of CPU time that has been consumed during any one release of the SO. public RelativeTime getMinConsumption(min : RelativeTime); If min is null, returns a new RelativeTime value containing the minimum amount of CPU time that has been consumed during any one release of the SO. If min is not null; update (and return) the given RelativeTime with the minimum amount of CPU time that has been consumed during any one release of the SO. Note: If CPU-time clocks are supported, the clock associated with the time values returned by the above method would be the appropriate CPU-time clock. Otherwize, they are associated with the real-time clock. b2) Determination of the current CPU consumption of a processing group Add the following thread-safe methods to the ProcessingGroupParameters class public RelativeTime getCurrentConsumption(current : RelativeTime); If current is null, returns a new RelativeTime value containing the amount of CPU time that has been consumed during the current processing group's release. If current is not null; update (and return) the given RelativeTime with the amount of CPU time that has been consumed during the current processing group's release. If the processing group is between periods, return the value used in the last period. public RelativeTime getMaxConsumption(max : RelativeTime); If max is null, returns a new RelativeTime value containing the maximum amount of CPU time that has been consumed during any one release of the processing group. If max is not null; update the given RelativeTime with the maximum amount of CPU time that has been consumed during any one release of the processing group. public RelativeTime getMaxConsumption(min : RelativeTime); If min is null, returns a new RelativeTime value containing the minimum amount of CPU time that has been consumed during any one release of the processing group. If min is not null; update the given RelativeTime with the minimum amount of CPU time that has been consumed during any one release of the processing group. b3) Additions to the RealtimeSystems class Add the following methods to the RealtimeSystems class public static boolean costMonitoringSupported(); Returns True, if cost monitoring (including cost enforcement) is implemented on the current systems. Returns false otherwise. public static RelativeTime costMonitoringResolution(); -- If a) is not adopted Returns the resolution of the notional CPU time clock timer. This method is only present if CPU time clocks are NOT visible at the API. public static integer costMonitoringAverageErrorMargin(); -- If a) is not adopted Returns the average error margin on cost monitoring as a +/- percentage of the cost value. Discussion Points ----------------- a) Determination of current CPU consumption of a schedulable object The API has been kept to a minimum. Other methods could be provided to reset the maximum and minimums back to zero. Also an average consumption could be supported. These methods could be made static to allow only the owning SO to access this information, but allowing any SO to access it is more useful. b) Determination of current CPU consumption of a processing group The API has been kept to a minimum. Other methods could be provided to reset the maximum and minimums back to zero. Also an average consumption could be supported. Compatibility Issues -------------------- The cost parameter in ReleaseParameters has a different clock association. To resolve this problem, the words in the ReleaseParameter class should be changed to indicate that any cost value associated with the real-time clock will be automatically converted to the CPU-Time clock. (Not sure this is enough as exceptions will be throwns if one adds to a cost with a relative or absolute time.) Development History ------------------