Runtime Configuration Repository

The purpose of the Runtime Configuration Repository is to make available runtime configuration parameters to SRTC components. The parameters are a subset of configuration parameters from the Persistent Configuration Repository that pertain to the current active deployment.

SRTC components must read their configuration parameters from the Runtime Configuration Repository during the initialisation activity when the Init command is received. Datapoint creation is normally not necessary by individual SRTC components, since these are typically created by the RTC Supervisor before the component is initialised. If a case arises that a datapoint needs to be created anyway, this should also occur during the initialisation activity.

Certain computed results can also be written to the repository as dynamic datapoints while the component is running. Such dynamic datapoints should be setup in the Persistent Configuration Repository if they require default initial values. This allows the default values to be adjusted and handled in the same manner as any other static datapoint value. Meaning that the datapoint is created by the RTC Supervisor when populating the Runtime Configuration Repository during initialisation. Otherwise the datapoint will have to be created by the component during the initialisation activity.

Datapoints should typically not be deleted from the Runtime Configuration Repository by SRTC components directly. Cleanup of the Runtime Configuration Repository is done externally. Still, it is possible to delete a datapoint if needed.

Data Access

An overview of the API is provided here, which should be enough to become familiar with it and to be able to use it. Refer to the API reference documentation for technical details.

Access to the Runtime Configuration Repository should always be performed through an instance of RuntimeRepoIf. The RTC Toolkit framework will automatically prepare such an instance when requested from the ServiceContainer, as long as it is correctly configured in the Service Discovery with the runtime_repo_endpoint datapoint.

The following URI schemes are supported for runtime_repo_endpoint:

  • rtr

    This is the fully fledged Runtime Configuration Repository implemented as a standalone server process, e.g. rtr://127.0.0.1:8000/rtr_topic.

  • cii.oldb

    This is a legacy Runtime Configuration Repository implementation using CII OLDB, e.g. cii.oldb:/rtc/repo. It is deprecated and will be removed soon.

The ServiceContainer is itself passed to the constructor of the user derived BusinessLogic class, and is accessible in user code through the attribute m_services. The following is an example of how to retrieve the RuntimeRepoIf within the Initialising method of BusinessLogic:

void BusinessLogic::Initialising(componentFramework::StopToken st) {
    auto repository = m_services.Get<RuntimeRepoIf>();
    // Can now access the datapoints with repository ...
}

Datapoint Paths

Configuration parameters are stored in a tree hierarchy as leaf nodes. This can also be described as a folder structure, similar to a file system. The nodes from the root of the tree to a particular leaf node form the components of a path. By adding the ‘/’ character as the path separator between each component, this forms a datapoint path string.

The canonical structure for the path is as follows:

/<component>/{static,dynamic}/<parameter>

Where <component> will typically be the SRTC component instance name and <parameter> can represent a hierarchical sub-path with multiple sub-folders if a deeper hierarchy of configuration parameters is desired for a particular SRTC component, besides the basic grouping into static and dynamic parameters.

Path components must contain only lowercase alpha numeric characters or the underscore, i.e. characters from the set [a-z0-9_].

Note

The canonical path structure is a suggested convention to follow. Reusable components delivered by the RTC Toolkit follow this convention. However, it is not enforced by RuntimeRepoIf, except for making sure that the path components only contain characters from the accepted character set. Therefore the user is technically free to choose any path structure desired.

The paths are handled in the API with the DataPointPath class, which is responsible for checking syntactical structure of the path. This DataPointPath is passed to the methods of RuntimeRepoIf to identify the specific datapoint to operate on.

Datapoint Creation

Datapoints need to be created before they can be used. Attempting to write a datapoint that does not exist will throw an exception. A datapoint can be created with the CreateDataPoint method as follows:

RuntimeRepoIf& repo = ...
DataPointPath path = "/mycomp/static/param1";
repo.CreateDataPoint<int32_t>(path);

The datapoint type to use is explicitly passed as a template parameter to the method. The currently supported types are indicated in the Supported Data Types section. There are alternative method signatures that allow to specify the type as an additional argument instead or to optionally give a default value. These can be used as follows:

RuntimeRepoIf& repo = ...
DataPointPath path = "/mycomp/static/param1";

// Pass type as argument:
repo.CreateDataPoint(path, typeid(int32_t));

// With a default value:
int32_t default_value = 123;
repo.CreateDataPoint(path, default_value);

All datapoints created using the above signatures will use a default value for the server alias setting. The server alias is a legacy mechanism used to control on which backend instance the data point should reside. The legacy mechanism is now also deprecated. When using the legacy CII backend, every external Redis instance must be configured with an appropriate server alias in the OLDB’s configuration. See the OLDB documentation for details about configuring the server alias strings for external Redis instances. By default the server alias is the empty string, which will indicate that the OLDB’s internal Redis instance should be used to store the datapoints.

To change the external Redis to use or to query the current default value the SetDefaultServerAlias and GetDefaultServerAlias methods can be used respectively. For example:

RuntimeRepoIf& repo = ...
DataPointPath path = "/mycomp/static/param1";

repo.SetDefaultServerAlias("ext_redis_1");
repo.CreateDataPoint<int32_t>(path);

std::string current_default = repo.GetDefaultServerAlias();

It is also possible to explicitly provide the server alias setting to certain CreateDataPoint method overloads. These will use the given server alias value for that datapoint, rather than the default server alias setting. These versions of the method can be used as follows:

RuntimeRepoIf& repo = ...
DataPointPath path = "/mycomp/static/param1";

// Pass type as argument:
repo.CreateDataPoint(path, typeid(int32_t), "ext_redis_1");

// With a default value:
int32_t default_value = 123;
repo.CreateDataPoint(path, default_value, "ext_redis_1");

Datapoint Reading

Reading a datapoint can be done with the GetDataPoint method, or the ReadDataPoint method to update an existing variable in place, which may be useful for large vectors and matrices. In addition, it is possible to pass a gsl::span or MatrixSpan to the ReadDataPoint method instead of a reference to a container for numerical vectors and matrices. This may be useful in situations where ownership of the buffer must be kept by the callers, but the data buffer cannot be instantiated as a standard container object. For example:

RuntimeRepoIf& repo = ...
int32_t param1 = repo.GetDataPoint<int32_t>("/mycomp/static/param1"_dppath);

std::vector<float> param2;
repo.ReadDataPoint("/mycomp/static/param2"_dppath, param2);

auto buffer1 = ...;
gsl::span<double> vector_span(buffer1);
repo.ReadDataPoint("/mycomp/static/param3"_dppath, vector_span);

auto buffer2 = ...;
MatrixSpan<double> matrix_span(buffer2);
repo.ReadDataPoint("/mycomp/static/param3"_dppath, matrix_span);

You will see the _dppath suffix is added to the string representations of the datapoint paths in the example above. This is a shorthand to construct a DataPointPath object from a null terminated character string.

The GetDataPoint and ReadDataPoint methods are blocking, and will only return to the caller once the data has been received. In certain situations it may be better to avoid blocking. To support this, the API provides the SendReadRequest method that takes a ReadRequest object as the input argument and returns a Response object, which can be used to eventually synchronise. The ReadRequest class is used to represent a read request for one or more datapoints to be fetched from the Runtime Configuration Repository. The Response object is effectively a future that provides a Wait method that will block until the request has been completed. An optional timeout threshold can be given to the Wait method.

This pattern allows a read request to be sent without blocking, some other work can then be performed while the request is completed in the background; and finally the Wait method can be called to synchronise with the background request. Ideally, by the time the Wait method is called, the request that was initially sent would have completed and the Wait method would return immediately without blocking. Otherwise it will block as long as is necessary for the request to complete.

Any processing, which requires some or all of the datapoints sent as part of the read request, must be performed after having invoked the Wait method and it returns without a timeout condition. Otherwise there will be a race condition between the read request and processing code.

The following example code shows how a ReadRequest object is prepared, how the request is sent and how the response is handled.

RuntimeRepoIf& repo = ...
int32_t param1;
std::vector<float> param2;

// An example callback lambda function that will force all negative values to zero.
auto handler = [](std::vector<float>& buffer) {
        for (auto& value: buffer) {
            if (value < 0.0) {
                value = 0.0;
            }
        }
    };

ReadRequest request;
request.Add("/mycomp/static/param1"_dppath, param1);
request.Add("/mycomp/static/param2"_dppath, param2, handler);
auto response = repo.SendReadRequest(request);

// Other processing not requiring param1 or param2 can happen here ...

response.Wait();

// Any processing requiring access to param1 or param2 goes here ...

As can be seen, the Add method is used to add all the datapoints needed to the request. Two alternative invocations are shown, one with a callback handler function and one without. The optional callback allows processing of a single datapoint’s data asynchronously as soon as it arrives. The callback is executed in a different thread than the one that invoked the SendReadRequest method. Therefore care should be taken if accessing any global variables to avoid race conditions.

Warning

Only the data explicitly passed to the callback’s argument should be accessed within the callback, since it is the only datapoint guaranteed to have been delivered when the callback is executed. No other data buffers for any other datapoints should be accessed within the callback function. Any such attempt will result in race conditions and likely data corruption.

In addition, the datapoint buffers that were added to the request with the Add method must not be accessed outside of a callback function once SendReadRequest has been called. Only after Wait returns successfully can the buffers for all these datapoints be accessed.

Warning

One should typically allow the C++ compiler to perform template argument deduction, as shown in the above examples, and not provide the template argument explicitly. For example, the following is considered a mistake:

request.Add<int32_t>("/mycomp/static/param1"_dppath, param1);

Datapoint Writing

Writing a new value to a datapoint can be done with the SetDataPoint method, or the WriteDataPoint method to pass a reference to the data instead, which is more optimal for large vectors or matrices. Similarly to the read method, it is possible to pass a gsl::span or MatrixSpan to the WriteDataPoint method instead of a reference to a container for numerical vectors and matrices. This may be useful in situations where the data buffer cannot be instantiated easily as a standard container object. For example:

RuntimeRepoIf& repo = ...
repo.SetDataPoint<int32_t>("/mycomp/static/param1"_dppath, 123);

std::vector<float> value2 = {1.2, 3.4, 5.6, 7.8};
repo.WriteDataPoint("/mycomp/static/param2"_dppath, value2);

auto buffer1 = ...;
gsl::span<double> vector_span(buffer1);
repo.WriteDataPoint("/mycomp/static/param3"_dppath, vector_span);

auto buffer2 = ...;
MatrixSpan<double> matrix_span(buffer2);
repo.WriteDataPoint("/mycomp/static/param3"_dppath, matrix_span);

The SetDataPoint and WriteDataPoint methods are blocking, and will only return to the caller once the data has been sent to the repository.

Similar to the reading methods, a non-blocking option exists with the SendWriteRequest method. It works in an analogous manner to the SendReadRequest method described in the previous Datapoint Reading section. The SendWriteRequest method accepts a WriteRequest object and returns a Response object. All datapoints that should be updated must be added to the WriteRequest object with the Add method. The Wait method of the Response object should be called to synchronise with the request completion. The call to Wait will block until the datapoints have been successfully sent to the repository. The Wait method can optionally take a timeout argument.

Warning

The buffers of the datapoints added to the request with the Add method must not be modified after SendWriteRequest has been called. Only after the Wait method returns successfully, can the datapoint buffers be modified. Modifying the contents before a successful invocation of Wait will result in race conditions and possible data corruption.

The following is an example of using SendWriteRequest:

RuntimeRepoIf& repo = ...
int32_t param1 = ...
std::vector<float> param2 = ...

WriteRequest request;
request.Add("/mycomp/static/param1"_dppath, param1);
request.Add("/mycomp/static/param2"_dppath, param2);
auto response = repo.SendWriteRequest(request);

// Other processing can happen here, but param1 and param2 must not be
// changed ...

response.Wait();

// param1 and param2 can be modified again after the Wait call here ...

Datapoint Querying

To check the data type of a datapoint one can use the GetDataPointType method as follows:

RuntimeRepoIf& repo = ...
auto& type = repo.GetDataPointType("/mycomp/static/param1"_dppath);

This will return the std::type_info object corresponding to the data type as one would get from the typeid operator. See the possible C++ types in the Supported Data Types section.

The data size, or more specifically the number of elements for a datapoint, is retrieved with the GetDataPointSize method. Note that this will always return the value 1 for basic types such as int32_t or float. For strings the number of characters is returned, i.e. the length of the string. For vectors and matrices the total number of elements is returned.

The following is an example of using GetDataPointSize:

RuntimeRepoIf& repo = ...
size_t size = repo.GetDataPointSize("/mycomp/static/param1"_dppath);

It may be necessary to check for the existence of a datapoint. This can be achieved with the DataPointExists method, which will return true if the datapoint exists and false otherwise. For example:

RuntimeRepoIf& repo = ...
if (repo.DataPointExists("/mycomp/static/param1"_dppath)) {
    // Can operate on the datapoint here ...
}

There is also a mechanism to query the names of available datapoint paths using the GetChildren method. This method takes a datapoint path and lists all the child nodes under the path. Specifically, it returns a pair of lists. The first list contains all the datapoints found within the path and the second list contains all the child paths, i.e. sub-folders. The GetChildren method provides a general mechanism to traverse the datapoint path hierarchy. The following shows an example of traversing and printing all datapoint paths available:

void traverse(RuntimeRepoIf& repo, DataPointPath path) {
    auto [datapoints, child_paths] = repo.GetChildren(path);
    for (auto& dp_path: datapoints) {
        std::cout << dp_path << std::endl;
    }
    for (auto& child_path: child_paths) {
        traverse(repo, child_path);
    }
}

RuntimeRepoIf& repo = ...
traverse(repo, "/"_dppath);

Datapoints can be created on different external Redis instances by changing their server alias setting. To find out the server alias with which a datapoint was created, the GetServerAlias method can be used. For example:

RuntimeRepoIf& repo = ...
std::string server_alias = repo.GetServerAlias("/mycomp/static/param1"_dppath);

Warning

Usage of the server alias within RTC Toolkit is a deprecated mechanism.

Datapoint Deletion

Existing datapoints are deleted with the DeleteDataPoint method. For example:

RuntimeRepoIf& repo = ...
repo.DeleteDataPoint("/mycomp/static/param1"_dppath);

Command-line/Graphical Manipulation

Manipulating the datapoints in the Runtime Configuration Repository can be performed with the rtctkConfigTool command line tool. See section Configuration Tool for details. This way of accessing the datapoints works for either the legacy OLDB backed Runtime Configuration Repository implementation, or the new implementation.

If using the OLDB backed Runtime Configuration Repository, it is also possible to view and manipulate the datapoints with the oldbGui tool. Refer to the CII OLDB documentation for further details about using this tool.

Note

The oldbGui is a default GUI tool provided by CII and currently has limited support for visualising and manipulating large vectors or matrices.

Datapoint Subscription

A simple API is available to support subscription to datapoints and registering callbacks for new data updates or datapoint removal notifications.

Subscribing

To subscribe to new data updates for a single datapoint, one can use the Subscribe method.

It is possible to subscribe to datapoint value change notifications without getting the actual value. This can be useful and more efficient when dealing with huge vector and matrix datapoint types since the value does not need to be transferred when only a change notification is wanted.

In this case the following needs to be provided:

  • A datapoint path to identify the datapoint being subscribed to.

  • A callback function (or generalised functor) that will be called when new data is received.

void Callback(const DataPointPath& path) {
    ...
}

RuntimeRepoIf& repo = ...
repo.Subscribe("/mycomp/static/param1"_dppath, Callback);

It is also possible to subscribe to datapoint value changes where one gets the actual value together with the notification. This can be useful and more efficient when dealing with small scalar datapoint types.

In this case, the following needs to be provided:

  • A datapoint path to identify the datapoint being subscribed to.

  • A reference to a buffer object that will be filled with the received data.

  • A callback function (or generalised functor) that will be called when new data is received.

void Callback(const DataPointPath& path, std::vector<float>& buffer) {
    ...
}

RuntimeRepoIf& repo = ...
std::vector<float> buffer;
repo.Subscribe("/mycomp/static/param1"_dppath, buffer, Callback);

Notice that the callback function declaration always takes two arguments in this case. The first is the datapoint path. This allows to know which datapoint is being dealt with if the same callback is reused in multiple subscriptions. The second argument is a reference to the buffer that was originally passed to the Subscribe method.

Warning

One should typically allow the C++ compiler to perform template argument deduction, as shown in the above example, and not provide the template argument explicitly for the buffer. Not putting the right type can lead to hard to debug compiler errors. For example it is not recommended to write the above code as:

repo.Subscribe<std::vector<float>>("/mycomp/static/param1"_dppath, buffer, Callback);

When a new data value is received, the buffer object will be modified in place. This possibly means memory reallocation when dealing with std::string, std::vector or MatrixBuffer. After the buffer has been updated the callback is invoked.

It is possible to use gsl::span instead of std::vector as the type of the buffer argument for numerical vectors. Similarly MatrixSpan can be used instead of MatrixBuffer for numerical matrices. This can be useful to fill buffers where full ownership or more control of the buffer must be retained by the caller to Subscribe. The following code shows an example of using MatrixSpan:

void Callback(const DataPointPath& path, MatrixSpan<float>& buffer) {
    ...
}

RuntimeRepoIf& repo = ...
float buffer[100];
MatrixSpan<float> span(10, 10, buffer);
repo.Subscribe("/mycomp/static/param1"_dppath, span, Callback);

Warning

The callback is executed in a different thread than the one calling the Subscribe method. Care must be taken when accessing the buffer to avoid race conditions and data corruption. This is applicable from the moment the subscription is initiated, e.g. by calling Subscribe, until the datapoint has been successfully unsubscribed from. If other threads must also access the buffer, e.g. the thread that originally called Subscribe, it is up to the user to implement appropriate synchronisation mechanisms.

Only callbacks for new data updates can be registered with the Subscribe method. For registering datapoint removal notifications one must use the SendSubscribeRequest method instead. In addition, SendSubscribeRequest is more appropriate to subscribe to multiple datapoints at once or if the subscription itself should occur asynchronously in the background. In this case, one prepares a SubscribeRequest object and passes it to SendSubscribeRequest. The following is an example of subscribing to two datapoints and also registering a removal notification callback for one of them:

void OnRemoved(const DataPointPath& path) {
    ...
}

void OnNewMatrix(const DataPointPath& path, MatrixBuffer<double>& buffer) {
    ...
}

void OnNewVector(const DataPointPath& path, gsl::span<int32_t>& buffer) {
    ...
}

RuntimeRepoIf& repo = ...
MatrixBuffer<double> matrix;
int32_t buffer[100];
gsl::span<int32_t> span(buffer);

SubscribeRequest request;
request.AddRemoveHandler("/mycomp/dynamic/matrix"_dppath, OnRemoved);
request.AddNewValueHandler("/mycomp/dynamic/matrix"_dppath, matrix, OnNewMatrix);
request.AddNewValueHandler("/mycomp/static/vector"_dppath, span, OnNewVector);
auto response = repo.SendSubscribeRequest(request);
// ... can do some other work here ...
response.Wait();

As can be seen from this example, callbacks for multiple datapoints are registered by adding them to the request with the AddNewValueHandler and AddRemoveHandler methods. AddNewValueHandler is used to register new data update callbacks. AddRemoveHandler is used to register datapoint removal notifications.

Once the request has been sent, the caller must eventually invoke the Wait method on the response object to synchronise. The Wait method will block until the request has completed. There is also a version of the Wait method that allows setting a timeout. However, in that case the Wait method must be invoked multiple times until it eventually succeeds.

Warning

The callbacks registered with SendSubscribeRequest are executed in different threads than the one that called SendSubscribeRequest. It is the users responsibility to implement synchronisation mechanisms to avoid race conditions between these threads. There is also no guarantee of ordering of the callbacks if multiple datapoints are updated simultaneously.

Unsubscribing

To unsubscribe callback handlers for a datapoint one can use the Unsubscribe method. This method will unsubscribe all callback handlers for a given datapoint path, i.e. all new data update callbacks and also all datapoint removal callbacks. To remove only one or the other type of callback the SendUnsubscribeRequest method should be used instead.

The following is an example of unsubscribing from a datapoint:

RuntimeRepoIf& repo = ...
repo.Unsubscribe("/mycomp/static/param1"_dppath);

It is possible to unsubscribe multiple callbacks by using the SendUnsubscribeRequest method. In this case an UnsubscribeRequest object is prepared and passed to SendUnsubscribeRequest. This method is also executed asynchronously, similarly to SendSubscribeRequest, where the Wait method must be eventually invoked on the returned response object to synchronise. The following is an example of unsubscribing from multiple datapoints:

RuntimeRepoIf& repo = ...
UnsubscribeRequest request;
request.AddRemoveHandler("/mycomp/dynamic/matrix"_dppath);
request.AddNewValueHandler("/mycomp/dynamic/matrix"_dppath);
request.AddNewValueHandler("/mycomp/static/vector"_dppath);
auto response = repo.SendUnsubscribeRequest(request);

Supported Data Types

The following is a table of currently supported data types for the Runtime Configuration Repository:

C++ Type

Internal Type Name

bool

RtcBool

int8_t

RtcInt8

int16_t

RtcInt16

int32_t

RtcInt32

int64_t

RtcInt64

uint8_t

RtcUInt8

uint16_t

RtcUInt16

uint32_t

RtcUInt32

uint64_t

RtcUInt64

float

RtcFloat

double

RtcDouble

std::string

RtcString

std::vector<std::byte>

RtcBinary

std::vector<bool>

RtcVectorBool

std::vector<int8_t>

RtcVectorInt8

std::vector<int16_t>

RtcVectorInt16

std::vector<int32_t>

RtcVectorInt32

std::vector<int64_t>

RtcVectorInt64

std::vector<uint8_t>

RtcVectorUInt8

std::vector<uint16_t>

RtcVectorUInt16

std::vector<uint32_t>

RtcVectorUInt32

std::vector<uint64_t>

RtcVectorUInt64

std::vector<float>

RtcVectorFloat

std::vector<double>

RtcVectorDouble

std::vector<std::string>

RtcVectorString

MatrixBuffer<bool>

RtcMatrixBool

MatrixBuffer<int8_t>

RtcMatrixInt8

MatrixBuffer<int16_t>

RtcMatrixInt16

MatrixBuffer<int32_t>

RtcMatrixInt32

MatrixBuffer<int64_t>

RtcMatrixInt64

MatrixBuffer<uint8_t>

RtcMatrixUInt8

MatrixBuffer<uint16_t>

RtcMatrixUInt16

MatrixBuffer<uint32_t>

RtcMatrixUInt32

MatrixBuffer<uint64_t>

RtcMatrixUInt64

MatrixBuffer<float>

RtcMatrixFloat

MatrixBuffer<double>

RtcMatrixDouble

MatrixBuffer<std::string>

RtcMatrixString

The indicated C++ type should be used for declaring the data variables in source code and when identifying the type to use in methods like CreateDataPoint. The internal type name is the corresponding string representation of the type. It is stored as meta-data inside the backend to identify the exact type of a datapoint and also used inside the YAML files when using the file based repository adapters. The rtctkConfigTool uses the internal type name for its command line arguments.

Composite Datapoints

A Composite Datapoint is the combination of multiple datapoints from a common root path that has been standardised. This section documents these standard Composite Datapoints.

NUMA Policies

This Composite Datapoint defines optional NUMA policies for CPU affinity, scheduling and memory policy.

The parameters are indicated in the following table relative to the Composite Datapoint root path. For example the root path is /mycomp/static/thread_policy the CPU parameter setting cpu_affinity would be /mycomp/static/thread_policy/cpu_affinity.

Configuration Path

Type

Description

/cpu_affinity

RtcString

Sets the optional CPU affinity for the thread. This is a mask of CPUs on which the thread is allowed to be scheduled. See the numa_parse_cpustring_all function in the numa(3) manpage for details about the correct format of this string.

/scheduler_policy

RtcString

Specifies the optional scheduling policy to apply to the thread with priority as defined in /scheduler_priority. Valid values are indicated in Table 1.

/scheduler_priority

RtcInt32

Indicates the priority or nice-value of the thread. If scheduler_policy is Fifo or Rr it must be set and with valid range [1..99]. If scheduler_policy is Other or Batch it is optional with valid range [-20..19], with a default value of 0.

/memory_policy_mode

RtcString

Specifies the optional memory allocation policy to apply to the thread and if provided it must be provided together with memory_policy_nodes. Valid values are indicated in Table 2.

/memory_policy_nodes

RtcString

Indicates a mask of NUMA nodes to which the memory policy is applied. See the numa_parse_nodestring_all function in the numa(3) manpage for details about the correct format of this string. This parameter must be provided together with memory_policy_mode.

Table 1 Scheduling policy options, see the sched_setscheduler(2) manpage for a detailed description of the options.

Value

System API Equivalent

Other

SCHED_OTHER

Batch

SCHED_BATCH

Fifo

SCHED_FIFO

Rr

SCHED_RR

Table 2 Memory policy mode options, see the set_mempolicy(2) manpage for a detailed description of the options.

Value

System API Equivalent

Default

MPOL_DEFAULT

Bind

MPOL_BIND

Interleave

MPOL_INTERLEAVE

Preferred

MPOL_PREFERRED

The following is an example of the configuration parameters in a YAML file for NUMA policies assuming /mycomp/static/example as root path:

mycomp:
    static:
        # Configure NUMA policies at Composite Datapoint "example"
        example:
            cpu_affinity: !cfg.type:string "1-4"
            scheduler_policy: !cfg.type:string Fifo
            scheduler_priority: !cfg.type:int32 10
            memory_policy_mode: !cfg.type:string Bind
            memory_policy_nodes: !cfg.type:string "1-4"

Limitations and Known Issues

When using the legacy CII OLDB backend, the same limitation apply as for the OLDB adapter. Refer to the Limitations and Known Issues sub-section for further details.

Other Bugs

  • One cannot pass gsl::span or MatrixSpan objects that use constant types in the template type argument to the methods of adapters based on RepositoryIf. For example, gsl::span<const float> cannot be used, it must be gsl::span<float> (RTCTK-958).