Main Content

Guidelines for Writing Thread-Safe S-Functions

万博1manbetx®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.

Background

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.

此外,如果这些S-functions指的是山姆e 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.

Guidelines

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 thessSetRuntimeThreadSafetyCompliancefunction. If you are not sure about the thread-safety of your S-function, use these guidelines to investigate and make it thread-safe.

Data Share

Definition Problem Solution

S-function refers to data using pointers (for example,ssSetUserData,ssGetUserData,ssSetPWorkValueandssGetPWorkValue). An S-function easily shares data using these pointers.

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.

  • Make the data constant if it is read-only.

  • To control access to data, consider using mutexes. Mutexes can also ensure cache coherence.

Global Variables

Definition Problem Solution

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.

  • If you are writing to global data, localize it, control access to it using mutexes, or change the semantics of your algorithm. To ensure cache coherence, also consider using memory fences such as atomic or mutex.

  • If you are reading, make your global variable constant.

Local Static Variables Initialization

Definition Problem Solution

Local static variables are stored in one location.

  • In C++, local static variables are initialized upon entering the function scope and are not thread-safe.

  • In C, local static variables are initialized at the start of the application as long as the value on the right of the assignment (the value being assigned into the variable) is compile-time constant. These variables are thread-safe.

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.

  • If you are using a C++ version prior to C++11, protect the initialization of local static variable using a mutex or thread-safe initialization mechanism, such asstd::call_onceorboost::call_once.

  • If you are using C++11 or later, local static variable initialization is guaranteed to be thread-safe.

Resources

Definition Problem Solution

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.

Reentrancy

Definition Problem Solution

A function is reentrant if it is safe to call multiple times from the same thread (recursively) . For example, thestrtokfunction is not reentrant because it keeps some internal state of the string to be tokenized. A function is reentrant if it does not call nonreentrant functions.

Calling a nonreentrant function from multiple threads might not be safe.

Make your function reentrant. For example:

  • 埃尔iminate the states the function holds.

  • Replace nonreentrant functions calls with reentrant equivalents. For example, replacestrtokwithstrtok_r.

mexCallMATLAB

Definition Problem Solution

An S-function might call MATLAB using themexCallMATLABfunction.

Simulink code that handlesmexCallMATLABfunctionality is not thread-safe.

Do not callmexCallMATLABin your S-function.

Exception Free Code

Definition Problem Solution

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, seeException Free Code.

When an S-function is not exception free, its subroutines are indirectly called throughmexCallMATLAB, which is not thread-safe (seemexCallMATLAB).

Examine your S-function for long jumps. If there are none, mark the S-function as exception free using thessSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE)function. If the S-function long jumps despite this flag, unpredictable behavior occurs.

If an S-function throws an exception but uses a try/catch block to catch the exception, that S-function is safe.

Data Race

Definition Problem Solution

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.

应用程序可能意想不到的行为。

Consider one of the following:

  • Revise your algorithm to eliminate data races.

  • Use locks to control the order of execution in critical parts of your code, or make critical operations atomic.

Volatile

Definition Problem Solution

Thevolatilekeyword tells the compiler not to optimize a variable because its value might be changed by some mechanism that the compiler is not aware of.

Applications might mistakenly usevolatileto achieve thread-safety.volatiledoes not provide atomicity or synchronization among threads.

Do not use thevolatilekeyword for thread-safety.

Error Status

Definition Problem Solution

S-functions usessSetErrorStatus,ssGetErrorStatus,ssSetLocalErrorStatus, andssGetLocalErrorStatusto access error status.

ssSetErrorStatusandssGetErrorStatusare not thread-safe. These functions can overwrite existing errors and cause reporting of inaccurate errors. For example, Block A might report the error thrown by Block B.

Use the thread-safessSetLocalErrorStatus, andssGetLocalErrorStatusfunctions. Do not usessSetErrorStatusandssGetErrorStatus.

See Also

|

Related Topics