Guidelines for Writing Thread-Safe S-Functions
Simulink® lets you run S-functions in parallel with multithreaded programming, which makes simulations run more quickly than serial runs. Multithreaded programming with S-functions requires you to make S-functions thread-safe. Creating thread-safe code involves ensuring that data shared between multiple threads is protected so that data and results are as expected. Simulation with S-functions that are not thread-safe might cause unexpected behavior.
C/C++ S-functions are implemented in C or C++ and built into shared libraries known as MEX files. When an S-function block refers to a shared library, MATLAB® loads the S-function block into the process. When multiple S-function blocks refer to the same shared library, they also refer to the initial shared library copy. This process results in multiple S-function blocks sharing the same data owned by the shared library. Thus, multithreaded S-function blocks access the same data at the same time.
In addition, if these S-functions refer to the same resources, multithreaded S-function blocks can access the same resources (such as files) at the same time, even when the S-function blocks are associated with different S-functions.
An S-function is generally considered thread-safe when it can safely execute
concurrently using multiple threads. To designate an S-function as thread-safe, use the
ssSetRuntimeThreadSafetyCompliance function. If you are not sure about
the thread-safety of your S-function, use these guidelines to investigate and make it
S-function refers to data using pointers (for example,
Multiple threads can use pointers to access the same data. If the threads try to write to the same memory location at the same time, they violate thread-safety. Concurrent reads from multiple threads are safe as long as there are no writes before, during, or after the reads, which can cause incoherent caches.
Be cautious when accessing data shared by multiple threads.
Global variables are shared data accessible throughout an application.
Multiple threads writing to non-protected shared data is not safe. Reading is safe as long as there are no writes before, during, or after the reads, which can cause incoherent caches.
Local Static Variables Initialization
Local static variables are stored in one location.
If multiple threads enter the function scope at the same time, the software makes multiple attempts to write to the same location. This issue holds even if the local static variable is constant.
Resources are entities that are explicitly requested from and returned to the system. Some examples of resources include dynamically allocated memory, files, database connections, and network sockets. Your application might need to manage resources.
Accessing resources from multiple threads might not be thread-safe, such as reading and writing to a file from multiple threads. Even if these operations are thread-safe, they might not produce the expected results.
Be cautious when managing a resource. Thread-safety of a resource depends on its implementation. For more information about thread-safety specifications, see the resource documentation. Optionally, you can guard access to the resource using a mechanism such as a mutex.
A function is reentrant if it is safe to call multiple times
from the same thread (recursively) . For example, the
Calling a nonreentrant function from multiple threads might not be safe.
Make your function reentrant. For example:
An S-function might call MATLAB using the
Simulink code that handles
Do not call
Exception Free Code
An S-function is exception free as long as none of its subroutines, when called, has the potential of long jumping. For more information about exception free S-functions, see Exception Free Code.
When an S-function is not exception free, its subroutines are
indirectly called through
Examine your S-function for long jumps. If there are none, mark
the S-function as exception free using the
If an S-function throws an exception but uses a try/catch block to catch the exception, that S-function is safe.
Data race occurs when the output of your application depends on the order of execution such that the behavior of your application changes between executions.
The application might have unexpected behavior.
Consider one of the following:
Applications might mistakenly use
Do not use the
Use the thread-safe