7.7.3 sg::SchedulerInterfaceForComponents class

This section describes the main scheduler interface class.

About sg::SchedulerInterfaceForComponents

The modeling components use this interface class, which gives access to all other parts of the Scheduler API, directly or indirectly. The scheduler must implement this class.

Version 1 of this class supersedes version 0. ARM deprecates v0, while maintaining backward compatibility where possible.

  • New simulated time representation.
  • sg::ticks_t now represents simulated time for better alignment with SystemC.
  • Updated scx_scheduler_mapping.* files.
// Main scheduler interface class, 
// listing only the functions that a version v1 compatible scheduler needs.
class sg::SchedulerInterfaceForComponents
{
public:
    static eslapi::if_name_t IFNAME() { return "sg.SchedulerInterfaceForComponents"; }
    static eslapi::if_rev_t IFREVISION() { return 1; }
    virtual eslapi::CAInterface * ObtainInterface(eslapi::if_name_t, eslapi::if_rev_t, eslapi::if_rev_t *) = 0;
    virtual sg::Timer * createTimer(const char *, sg::TimerCallback *) = 0;
    virtual sg::SchedulerThread * createThread(const char *, sg::SchedulerRunnable *) = 0;
    virtual sg::SchedulerThread * currentThread() = 0;
    virtual sg::ThreadSignal * createThreadSignal(const char *) = 0;
    virtual void wait(sg::ticks_t) = 0;
    virtual void wait(sg::ThreadSignal *) = 0;
    virtual void setGlobalQuantum(sg::ticks_t) = 0;
    virtual sg::ticks_t getGlobalQuantum(sg::Tag<sg::ticks_t> *) = 0;
    virtual void setMinSyncLatency(sg::ticks_t) = 0;
    virtual sg::ticks_t getMinSyncLatency(sg::Tag<sg::ticks_t> *) = 0;
    virtual void addSynchronisationPoint(sg::ticks_t) = 0;
    virtual sg::ticks_t getNextSyncPoint(sg::Tag<sg::ticks_t> *) = 0;
    virtual void getNextSyncRange(sg::ticks_t &, sg::ticks_t &) = 0;
    virtual void addCallback(sg::SchedulerCallback *) = 0;
    virtual void removeCallback(sg::SchedulerCallback *) = 0;
    virtual sg::ticks_t getCurrentSimulatedTime(sg::Tag<sg::ticks_t> *) = 0;
    virtual double getSimulatedTimeResolution() = 0;
    virtual void setSimulatedTimeResolution(double resolution) = 0;
    virtual void stopRequest() = 0;
    virtual void stopAcknowledge(sg::SchedulerRunnable *) = 0;
 };

Use the sg::Tag class to select v1 get...() functions. Select v1 by passing a null pointer to the extra Tag<> argument. See getGlobalQuantum(), getMinSyncLatency(), getNextSyncPoint(), and getCurrentSimulatedTime().

ARM deprecates these v0 Scheduler API functions:

    wait(sg::ticks_t, sg::FrequencySource *)
    sg::SchedulerThread::setFrequency(sg::FrequencySource *)
    sg::SchedulerRunnable::breakQuantum(sg::ticks_t)
    sg::Timer::setFrequency(sg::FrequencySource *)

ARM deprecates classes sg::FrequencySource and sg::FrequencyObserver. Modeling components must not use these classes to directly communicate with the Scheduler API. They must use the new sg::Time class, which allows conversion between v0 and v1 simulated time representations.

Modeling components use this interface to create threads, asynchronous and timed events, system synchronization points, and to request a simulation stop. Examples of components that access this interface are:

  • CT core models.
  • Timer peripherals.
  • Peripheral components with timing or that indicate system synchronization points.
  • Peripheral components that can stop the simulation for certain conditions (external breakpoints).
  • GUI components.

Passive components that do not interact with the scheduler (and that do not need explicit scheduling) usually do not access this interface.

eslapi::CAInterface and eslapi::ObtainInterface

The CAInterface base class and the ObtainInterface() function make the interface discoverable at runtime through a runtime mechanism. All interfaces in Fast Models that must be discoverable at runtime derive from CAInterface.

The functions IFNAME(), IFREVISION(), and ObtainInterface() belong to the base class eslapi::CAInterface. IFNAME() and IFREVISION() return static information (name and revision) about the interface (not the interface implementation). An implementation of the interface cannot re-implement these functions. To access this interface, Code must pass these two values to the ObtainInterface() function to acquire the SchedulerInterfaceForComponents.

Use ObtainInterface() to access the interfaces that the scheduler provides. As a minimum requirement, the implementation of ObtainInterface() must provide the SchedulerInterfaceForComponents interface itself and also the eslapi::CAInterface interface. The easiest way to provide these interfaces to use the class eslapi::CAInterfaceRegistry and register these two interfaces and forward all ObtainInterface() calls to this registry. See the default implementation of the Scheduler API over SystemC for an example.

Note:

CAInterface and ObtainInterface() are not part of the scheduler functionality but rather of the simulation infrastructure. The information here is what is necessary to understand and implement ObtainInterface(). For more details on the eslapi::CAInterface class, see the header file $PVLIB_HOME/include/fmruntime/eslapi/CAInterface.h.

sg::SchedulerInterfaceForComponents::addCallback

This method schedules a call-back in the simulation thread. AsyncSignal uses it.

void addCallback(SchedulerCallback *callback);
callback
Call-back object to call. If callback is NULL, the call has no effect.

Any host thread can call this method. It is thread safe. It is always the simulation thread (host thread which runs the simulation) that calls the call-back function (callback->schedulerCallback()). The scheduler calls the call-back function when it can respond to the addCallback() function.

Multiple call-backs might be pending. The scheduler can call them in any order. Do not call addCallback() or removeCallback() from a call-back function.

Call-backs automatically vanish once called. Removing them deliberately is not necessary unless they become invalid, for example on the destruction of the object implementing the call-back function.

sg::SchedulerInterfaceForComponents::addSynchronisationPoint

This method adds synchronization points.

void addSynchronisationPoint(ticks_t ticks);
ticks
Simulated time for synchronization relative to the current simulated time, in ticks relative to simulated time resolution.

Modeling components can call this function to hint to the scheduler when a potentially useful system synchronization point will occur. The scheduler uses this information to determine the quantum sizes of threads.

Calling this function again adds another synchronization point.

Synchronization points automatically vanish when reached.

sg::SchedulerInterfaceForComponents::createThread

CT core models and modeling components call this method to create threads. This method returns an object implementing SchedulerThread. (Not NULL except when runnable is NULL.)

SchedulerThread *createThread(const char *name, SchedulerRunnable *runnable);
name
Instance name of the thread. Ideally, the hierarchical name of the component that owns the thread is included in the name. If name is NULL, it receives the name '(anonymous thread)'. The function makes a copy of name.
runnable
Object that implements the SchedulerRunnable interface. This object is the one that contains the actual thread functionality. The returned thread uses this interface to communicate with the thread implementation in the modeling component. If runnable is NULL, the call returns NULL, which has no effect.

Having created the thread, start it with a call to SchedulerThread::start().

Destroying the returned object with the SchedulerThread destructor might not kill the thread.

sg::SchedulerInterfaceForComponents::createThreadSignal

CT core models use this method to create thread signals. A thread signal is a nonschedulable event that threads wait for. Giving the signal schedules all waiting threads to run.

ThreadSignal *createThreadSignal(const char *name);
name
Instance name of the thread. Ideally, the hierarchical name of the component that owns the thread is included in the name. If name is NULL, it receives the name '(anonymous thread signal)'. The function makes a copy of name.

Destroying the returned object while threads are waiting for it leaves the threads unscheduled.

sg::SchedulerInterfaceForComponents::createTimer

Modeling components call this method to create objects of class Timer. They use timers to trigger events in the future (one-shot or repeating events).

Timer *createTimer(const char *name, TimerCallback *callback);

sg::SchedulerInterfaceForComponents::currentThread

This method returns the currently running scheduler thread, which createThread() created, or null pointer if not in any threadProc() call.

SchedulerThread *currentThread();

sg::SchedulerInterfaceForComponents::getCurrentSimulatedTime

This method returns the simulated time in ticks relative to simulated time resolution, since the creation of the scheduler. ClockDivider and MasterClock(ClockSignalProtocol::currentTicks()) use it.

ticks_t getCurrentSimulatedTime(Tag<ticks_t> *);

This clock accurately reflects the time on the last timer call-back invocation or the last return from SchedulerThread::wait(), whichever was last. The return values monotonically increase over (real or simulated) time.

sg::SchedulerInterfaceForComponents::getGlobalQuantum

This method returns the global quantum in ticks relative to simulated time resolution.

ticks_t getGlobalQuantum(Tag<ticks_t> *);

sg::SchedulerInterfaceForComponents::getMinSyncLatency

This method returns the minimum synchronization latency in ticks relative to simulated time resolution.

ticks_t getMinSyncLatency(Tag<ticks_t> *);

sg::SchedulerInterfaceForComponents::getNextSyncPoint

This method returns the next synchronization point relative to the current simulated time. The next synchronization point is expressed in ticks relative to simulated time resolution.

ticks_t getNextSyncPoint(Tag<ticks_t> *);

Modeling components can call this function for a hint about when a potentially useful system synchronization point will occur. Core threads use this information to determine when to synchronize.

sg::SchedulerInterfaceForComponents::getSimulatedTimeResolution

This method returns the simulated time resolution in seconds.

double getSimulatedTimeResolution();

sg::SchedulerInterfaceForComponents::removeCallback

This method removes all call-backs that are scheduled using addCallback() for this call-back object. AsyncSignal uses it.

void removeCallback(SchedulerCallback *callback);
callback
The call-back object to remove. If callback is NULL, an unknown call-back object, or a called call-back, then the call has no effect.

Any host thread can call this method. It is thread safe.

The scheduler will not call the specified call-back after this function returns. It can, however, call it while execution control is inside this function.

Call-backs automatically vanish once called. Removing them deliberately is not necessary unless they become invalid, for example on the destruction of the object implementing the call-back function.

sg::SchedulerInterfaceForComponents::setGlobalQuantum(ticks_t ticks)

This method sets the global quantum.

void setGlobalQuantum(ticks_t ticks);
ticks
Global quantum value, relative to simulated time resolution. The global quantum is the maximum time that a thread can run ahead of simulation time.

All threads must synchronize on timing points that are multiples of the global quantum.

sg::SchedulerInterfaceForComponents::setGlobalQuantum(ticks_t ticks, FrequencySource *timebase)

This method sets the global quantum. ARM deprecates this v0 function.

sg::SchedulerInterfaceForComponents::setMinSyncLatency

This method sets the minimum synchronization latency.

void setMinSyncLatency(ticks_t ticks);
ticks
Minimum synchronization latency value, relative to simulated time resolution.

The minimum synchronization latency helps to ensure that sufficient simulated time has passed between two synchronization points for synchronization to be efficient. A small latency increases accuracy but decreases simulation speed. A large latency decreases accuracy but increases simulation speed. The scheduler uses this information to set the minimum synchronization latency of threads with sg::SchedulerRunnable::setThreadProperty(), and to compute the next synchronization point as returned by getNextSyncPoint().

sg::SchedulerInterfaceForComponents::setSimulatedTimeResolution

This method sets the simulated time resolution in seconds.

void setSimulatedTimeResolution(double resolution)
resolution
Simulated time resolution in seconds.

Setting simulated time resolution after the start of the simulation is not possible. Setting simulated time resolution after setting timers is not possible.

sg::SchedulerInterfaceForComponents::stopAcknowledge

This function blocks the simulation thread until being told to resume.

void stopAcknowledge(SchedulerRunnable *runnable);
runnable
Pointer to the runnable instance that called this function, or NULL when not called from a runnable instance. If not NULL this function calls runnable->clearStopRequest() once it is safe to do so (with respect to nonsimulation host threads).

CT core models call this function from within the simulation thread in response to a call to stopRequest() or spontaneously (for example, breakpoint hit, debugger stop). The call must always be from the simulation thread. The scheduler must block inside this function. The function must return when the simulation is to resume.

The scheduler usually implements a thread-safe mechanism in this function that allows blocking and resuming of the simulation thread from another host thread (usually the debugger thread).

Calling this function from a nonsimulation host thread is wrong by design and is forbidden.

This function must clear the stop request that led to calling this function by calling runnable->clearStopRequest().

This function must have no effects other than blocking the simulation thread.

sg::SchedulerInterfaceForComponents::stopRequest

This function requests the simulation of the whole system to stop (pause).

void stopRequest();

You can call this function from any host thread, whether the simulation is running or not. The function returns immediately, possibly before the simulation stops. This function will not block the caller until the simulation stops. The simulation stops as soon as possible, depending on the syncLevel of the threads in the system. The simulation calls the function stopAcknowledge(), which blocks the simulation thread to pause the simulation. This function must not call stopAcknowledge() directly. It must only set up the simulation to stop at the next sync point, defined by the syncLevels in the system. Reset this state with stopAcknowledge(), which calls SchedulerRunnable::clearStopRequest().

Debuggers and modeling components such as CT cores and peripherals use this function to stop the simulation from within the simulation thread (for example for external breakpoints) and also asynchronously from the debugger thread. Calling this function again (from any host thread) before stopAcknowledge() has reset the stop request, using SchedulerRunnable::clearStopRequest() is harmless. The simulation only stops once.

Note:

The simulation can stop (that is, call stopAcknowledge()) spontaneously without a previous stopRequest(). This stop happens for example when a modeling component hits a breakpoint. A stopRequest() is sufficient, but not necessary, to stop the simulation.

The scheduler implementation of this function is to forward this stopRequest() to the running runnable object, but only for stopRequest() calls from the simulation thread. When the runnable object accepts the stopRequest() (SchedulerRunnable::stopRequest() returns true), the scheduler need do nothing more because the runnable object will respond with a stopAcknowledge() call. If the runnable object did not accept the stopRequest() (SchedulerRunnable::stopRequest() returns false) or if this function call is outside of the context of a runnable object (for example, from a call-back function) or from a non-simulation host thread, then the scheduler is responsible for handling the stopRequest() itself by calling stopAcknowledge() as soon as possible.

The stop handling mechanism should not change the scheduling order or model behavior (non-intrusive debugging).

sg::SchedulerInterfaceForComponents::wait(ThreadSignal)

This method waits on a thread signal.

void wait(ThreadSignal *threadSignal);
threadSignal
Thread signal object to wait for. A call with threadSignal of NULL is valid, but has no effect.

wait() blocks the current thread until it receives ThreadSignal::notify(). This function returns when the calling thread can continue to run.

Only call this method from within a SchedulerRunnable::threadProc() context. Calling this method from outside of a threadProc() context is valid, but has no effect.

sg::SchedulerInterfaceForComponents::wait(ticks_t)

This method blocks the running thread and runs other threads for a specified time.

void wait(ticks_t ticks);
ticks
Time to wait for, in timebase units. ticks can be 0.

Only call this method from within a SchedulerRunnable::threadProc() context. Calls from outside of a threadProc() context are valid, but have no effect.

This method blocks a thread for a time while the other threads run. It returns when the calling thread is to continue, at the co-routine switching point. Typically, a thread calls wait(ticks) in its loop when it completes ticks ticks of work. ticks is a "quantum".

sg::SchedulerInterfaceForComponents::wait(ticks_t, FrequencySource)

This function blocks the running thread and runs other threads for a specified time. ARM deprecates this v0 function.

Non-ConfidentialPDF file icon PDF versionARM 100965_1101_00_en
Copyright © 2014–2017 ARM Limited or its affiliates. All rights reserved.