Using xdc.runtime Timestamps

From RTSC-Pedia

Jump to: navigation, search
revision tip
—— LANDSCAPE orientation
[printable version]  [offline version]offline version generated on 18-Nov-2017 00:11 UTC

Using xdc.runtime Timestamps

How to get and use timestamps

Contents

Introduction

The xdc.runtime.Timestamp module, as the name suggests, provides timestamping services. This module can be used for benchmarking code, adding timestamps to Log events for correlation with other system events, monitoring real-time performance, etc.

Overview

By definition, real-time systems require some means to track and measure elapsed time. However, different systems use very different methods. Some systems leverage platform-specific timer peripherals while others use application-specific data streams that are known to produce data at a fixed rate (i.e., telephony TDM data). The choice of how to measure time is application and platform specific, so it is important that the timer services provided by xdc.runtime enable the system integrator to specify an appropriate time source.

In addition to variations in how time is measured, different applications have very different precision and range requirements. Applications that only require millisecond precision often don't require more than 32-bits of range (almost 50 days), whereas measurements used to causally relate events in a multi-core system requires near nanosecond precision (yielding less than 5 seconds of range from a 32-bit value). In fact, it is not unusual for a single application to require more than one timer with different precision and range requirements.

Architecture

Although the Timestamp module provides two methods for acquiring a timestamp, Timestamp_get32() and Timestamp_get64(), 64-bit timestamps may not be supported on all devices. In this case, the upper 32-bits of Types.Timerstamp are simply set to zero. The values returned by these methods are in implementation-dependent units called "cycles".

The Timestamp module also provides a Timestamp_getFreq() method that returns the frequency of the timestamp counter in Hz. This method can be used to convert the numbers returned by Timestamp_get32() and Timestamp_get64() (cycles) to actual time units (milliseconds).

In order to support multiple timestamp modules, each providing different ranges and precisions, the interface implemented by Timestamp is formally specified by (i.e., inherited from) xdc.runtime.ITimestampClient. By separately defining the ITimestampClient interface from the Timestamp module, multiple "timestamp providers" each implementing the same interface (ITimestampClient) can be present in an application.

Timestamp values returned by different timestamp providers cannot be directly compared. If you need to compare values between different providers, you must use Timestamp_getFreq() to first convert the timestamps to units of time.

Since the xdc.runtime package can only provide portable C sources and mechanisms for generating timestamps are inherently platform-dependent, the Timestamp module can be configured to use a platform or application-specific "timestamp provider". In effect, the Timestamp methods simply call the methods of the timestamp provider specified by the application's configuration script.

Configuration

The Timestamp module has a single configuration parameter, named SupportProxy, of type ITimestampProvider. Depending on the provider used, the underlying counter may be implemented quite differently; e.g., it may be a software timer, a 64-bit dedicated counter in the CPU's core, or a 32-bit counter that is part of a timer peripheral.

Built-in Timestamp Providers describes the timestamp providers included in the xdc.runtime package and illustrates their use. One such provider, xdc.runtime.TimestampNull, can be used when timestamp services are not needed by the application. The TimestampNull module always returns a timestamp of ~0. In this case, any modules that use xdc.runtime.Timestamp will see an unchanging timestamp but the overhead of getting the timestamp is negligible.

TimestampNull is the default timestamp provider for the Timestamp module. As a result, unless you explicitly configure the Timestamp.SupportProxy parameter, all timestamps returned by Timestamp will be 0.

Extending xdc.runtime Timestamps describes how to create new custom timestamp providers that can, for example, leverage platform-specific timer capabilities.

Examples

The following configuration script shows how to "bind" an implementation of the underlying timestamp services to the Timestamp module. This configuration script is used for the remainder of the C applications in this section.

app.cfg
 
 
var Timestamp = xdc.useModule("xdc.runtime.Timestamp");
Timestamp.SupportProxy = xdc.useModule("xdc.runtime.TimestampStd");

The following C fragment calculates a time delta based on timestamp values. Note that the units returned by Timestamp_get32() and Timestamp_get64() are implementation dependent; timestamp values from different timers cannot be compared, even if both timers are on the same CPU.

app.c
 
 
 
 
 
 
 
 
#include <xdc/runtime/Timestamp.h>
 
UInt32 time1, time2, delta;
 
time1 = Timestamp_get32();
callLongFunction();
time2 = Timestamp_get32();
delta = time2 - time1;

This next C example uses Timestamp_getFreq() to print a message every second. Although this application is impractical, it illustrates the use of Timestamp_getFreq() to measure real elapsed time. Timestamp_getFreq() can also be used to convert timestamps from different timers to a common unit (such as milliseconds) so these values can be compared.

app.c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#include <xdc/runtime/Types.h>
#include <xdc/runtime/Timestamp.h>
#include <assert.h>
 
main ()
{
    ...
    Types_FreqHz freq;
 
    Timestamp_getFreq(&freq);
 
    /* works only for timestamps with 32-bit frequencies */
    assert(freq.hi == 0);
 
    for (;;) {
        UInt32 start = Timestamp_get32();
        while ((Timestamp_get32() - start) < freq.lo) {
            ; /* do nothing */
        }
        System_print("A second has elapsed");
    }
    ...
}

This example also illustrates an important point about portability. Modern processors often supply timestamp registers that track the number of CPU clock cycles since the last reset. These same processors may require more than 32 bits to represent the number of CPU cycles per second. As a result, applications should take care when converting from a timestamp value to real time units; don't assume that the timestamp frequency is less than 4294967296 (= 2^32).

Built-in Timestamp Providers

The xdc.runtime package includes two built-in timestamp providers:

  1. TimestampNull - a timestamp provider that always returns a timestamp of 0, and
  2. TimestampStd - a timestamp provider that uses the ANSI C Standard Library function clock() to obtain timestamps.

These modules are sufficient for early development but, because they are written to be 100% portable, they don't take advantage of any platform-specific features (such as device-specific instruction counters). Fortunately it's easy to create a custom timestamp provider that takes full advantage of your platform's execution environment and can be bound to Timestamp as easily as TimestampNull or TimestampStd. Extending xdc.runtime Timestamps contains more details about how to create custom timestamp modules and includes a simple example that can easily be extended to leverage unique platform capabilities.

The TimestampStd module

The TimestampStd module.  During debugging, you may plug Timestamp.SupportProxy with xdc.runtime.TimestampStd, which simply calls the ANSI Standard C runtime function clock(). For example:

 
 
var Timestamp = xdc.useModule("xdc.runtime.Timestamp");
Timestamp.SupportProxy = xdc.useModule("xdc.runtime.TimestampStd");
The TimestampNull module

The TimestampNull module.  If timestamps are only used during debugging (to embed time values in Log events, for example), you can plug Timestamp.SupportProxy with xdc.runtime.TimestampNull to keep the time and space overhead for the Timestamp module to an absolute minimum.

 
 
var Timestamp = xdc.useModule("xdc.runtime.Timestamp");
Timestamp.SupportProxy = xdc.useModule("xdc.runtime.TimestampNull");
[printable version]  [offline version]offline version generated on 18-Nov-2017 00:11 UTC
Copyright © 2008 The Eclipse Foundation. All Rights Reserved
Personal tools
package reference