sim_model

class SimThreadExecution
#include <sim_model.h>

This class handles the management of a given “thread” of execution and provides the main mechanism for running concurrent jobs inside BSK

Public Functions

SimThreadExecution() = default
explicit SimThreadExecution(uint64_t threadIdent, uint64_t currentSimNanos = 0)

Constructor for a given sim thread.

~SimThreadExecution()

Request shutdown and join the worker before destroying its state.

inline void updateNewStopTime(uint64_t newStopNanos)

Method to update a new simulation stop time.

inline void clearProcessList()

clear the process list

void selfInitProcesses() const

This method is used by the “child” thread to walk through all of its tasks and processes and initialize them serially. Note that other threads can also be initializing their systems simultaneously.

void crossInitProcesses() const

This method is vestigial and should probably be removed once MT message movement has been completed.

void resetProcesses()

This method allows the “child” thread to reset both its timing/scheduling, as well as all of its allocated tasks/modules when commanded. This is always called during init, but can be called during runtime as well.

void addNewProcess(SysProcess *newProc)

This method pops a new process onto the execution stack for the “child” thread. It allows the user to put specific processes onto specific threads if that is desired.

inline uint64_t procCount() const

Gets the current “thread-count” in the system.

inline bool threadActive() const

Tells the caller if the thread is currently allocated processes and is in execution.

inline void threadReady()

Allows the system to put the thread into a running state.

void waitOnInit()

Once threads are released for execution, this method ensures that they finish their startup before the system starts to go through its initialization activities. It’s very similar to the locking process, but provides different functionality.

void postInit()

This method allows the startup activities to alert the parent thread once they have cleared their construction phase and are ready to go through initialization.

inline bool threadValid() const

Determines if the thread is currently usable or if it has been requested to shutdown.

void requestStop()

Request shutdown and wake the worker without waiting for it to finish.

Note

Only the first stop request releases the worker semaphore. Repeated calls, including through killThread(), are harmless. The owner must keep this execution record alive until the worker has been joined.

inline void killThread()

Compatibility alias for requestStop(), including waking an idle worker.

void lockThread()

This method provides a synchronization mechanism for the “child” thread ensuring that it can be held at a fixed point after it finishes the execution of a given frame until it is released by the “parent” thread.

void unlockThread()

This method provides an entry point for the “parent” thread to release the child thread for a single frame’s execution. It is intended to only be called from the parent thread.

void lockParent()

This method provides a forced synchronization on the “parent” thread so that the parent and all other threads in the system can be forced to wait at a known time until this thread has finished its execution for that time.

void unlockParent()

This method provides an entry point for the “child” thread to unlock the parent thread after it has finished its execution in a frame. That way the parent and all of its other children have to wait for this child to finish its execution.

void StepUntilStop()

Step simulation until stop time uint64_t reached.

This method steps the simulation until the specified stop time and stop priority have been reached.

void SingleStepProcesses(int64_t stopPri = -1)

Step only the next Task in the simulation.

This method steps all of the processes forward to the current time. It also increments the internal simulation time appropriately as the simulation processes are triggered

Parameters:

stopPri – The priority level below which the sim won’t go

void moveProcessMessages() const

This method is currently vestigial and needs to be populated once the message sharing process between different threads is handled. TODO: Make this method move messages safely between threads

Public Members

uint64_t CurrentNanos = 0

[ns] Current sim time

uint64_t NextTaskTime = 0

[ns] time for the next Task

uint64_t currentThreadNanos = 0

Current simulation time available at thread.

uint64_t stopThreadNanos = 0

Current stop conditions for the thread.

int64_t stopThreadPriority = -1

Current stop priority for thread.

uint64_t threadID = 0

Identifier for thread.

std::thread threadContext

Owned worker, joined before this execution record is destroyed.

int64_t nextProcPriority = -1

[-] Priority level for the next process

bool selfInitNow = {}

Flag requesting self init.

bool crossInitNow = {}

Flag requesting cross-init.

bool resetNow = {}

Flag requesting that the thread execute reset.

std::exception_ptr threadException = nullptr

Exception pointer for thread errors

Private Members

bool threadRunning = {}

Flag that will allow for easy concurrent locking.

std::atomic<bool> terminateThread = {false}

Shutdown request shared by the parent and worker.

BSKSemaphore parentThreadLock

Lock that ensures parent thread won’t proceed.

BSKSemaphore selfThreadLock

Lock that ensures this thread only reaches allowed time.

std::vector<SysProcess*> processList

List of processes associated with thread.

std::mutex initReadyLock

Lock function to ensure runtime locks are configured.

std::condition_variable initHoldVar

Conditional variable used to prevent race conditions.

class SimModel
#include <sim_model.h>

The top-level container for an entire simulation.

Public Functions

SimModel()

The SimModel constructor.

This Constructor is used to initialize the top-level sim model.

SimModel(const SimModel&) = delete
SimModel &operator=(const SimModel&) = delete
SimModel(SimModel&&) = delete
SimModel &operator=(SimModel&&) = delete
~SimModel()

Stop and join all owned workers.

Stop workers before destroying the simulation’s other members.

void selfInitSimulation()

Method to initialize all added Tasks.

This method goes through all of the processes in the simulation, all of the tasks within each process, and all of the models within each task and self-inits them.

void resetInitSimulation() const

Method to reset all added tasks.

This method goes through all of the processes in the simulation, all of the tasks within each process, and all of the models within each task and resets them.

void StepUntilStop(uint64_t SimStopTime, int64_t stopPri)

Step simulation until stop time uint64_t reached.

This method steps the simulation until the specified stop time and stop priority have been reached.

Parameters:
  • SimStopTime – Nanoseconds to step the simulation for

  • stopPri – The priority level below which the sim won’t go

void SingleStepProcesses(int64_t stopPri = -1)

Step only the next Task in the simulation.

This method steps all of the processes forward to the current time. It also increments the internal simulation time appropriately as the simulation processes are triggered

Parameters:

stopPri – The priority level below which the sim won’t go

void addNewProcess(SysProcess *newProc)

This method allows the user to attach a process to the simulation for execution. Note that the priority level of the process determines what order it gets called in: higher priorities are called before lower priorities. If priorities are the same, the proc added first goes first.

Parameters:

newProc – the new process to be added

void addProcessToThread(SysProcess *newProc, size_t threadSel)

This method allows the user to specifically place a given process onto a specific thread index based on the currently active thread-pool. This is the mechanism that a user has to specifically spread out processing in a way that makes the best sense to them. Otherwise it happens in the round-robin manner described in the allocate-remaining-processes method.

Parameters:
  • newProc – The process that needs to get emplaced on the specified thread

  • threadSel – The thread index in the thread-pool that the process gets added to

void ResetSimulation()

Reset simulation back to zero.

This method is used to reset a simulation to time 0. It sets all process and tasks back to the initial call times. It clears all message logs. However, it does not clear all message buffers and does not reset individual models.

void clearProcsFromThreads() const

This method removes all of the active processes from the “thread pool” that has been established. It is needed during init and if sims are restarted or threads need to be reallocated. Otherwise it is basically a no-op.

void resetThreads(uint64_t threadCount)

Stop and join existing workers, then replace the thread pool.

Note

Processes are borrowed and remain available for reassignment.

Parameters:

threadCount – Number of worker records to allocate; must be positive.

void deleteThreads()

Stop and join all workers and release their execution records.

Note

Safe to call repeatedly, including before workers have been started. Every worker receives its stop request before any worker is joined.

void assignRemainingProcs()

This method provides a seamless allocation of processes onto active threads for any processes that haven’t already been placed onto a thread. If the user has allocated N threads, this method just walks through those threads and pops all of the processes onto those threads in a round-robin fashion.

inline uint64_t getThreadCount() const

returns the number of threads used

Public Members

BSKLogger bskLogger

&#8212; BSK Logging

std::vector<SysProcess*> processList

&#8212; List of processes we’ve created

std::vector<std::unique_ptr<SimThreadExecution>> threadList

Owned worker execution records.

std::string SimulationName

&#8212; Identifier for Sim

uint64_t CurrentNanos = 0

[ns] Current sim time

uint64_t NextTaskTime = 0

[ns] time for the next Task

int64_t nextProcPriority = -1

[-] Priority level for the next process