# C API Reference

# Tracing

# Macros

The following macros are used to provide functionality while exposing additional metadata to the CLI tooling, like description and tag strings. The extra metadata is detected by the CLI for generating manifest information and compiles away.

# MODALITY_PROBE_INIT

MODALITY_PROBE_INIT(
  dest,
  dest_size,
  probe_id,
  time_res,
  wc_id,
  next_sid_fn,
  next_sid_state,
  probe,
  ...)

Initialize a new Modality probe instance with probe metadata information for the CLI tooling.

Parameters:

  • uint8_t *dest
    • User provided backing storage for the probe.
  • size_t dest_size
    • Size of the user provided backing storage for the probe in bytes.
  • identifier probe_id
    • Token to serve as the probe identifier, required to be unique throughout the system. The header-gen command will create a header file assigning an integer value to this identifier.
  • uint32_t time_res
    • The wall clock time resolution in nanoseconds. If this probe does not use wall clock time or the resolution is unknown, use MODALITY_PROBE_TIME_RESOLUTION_UNSPECIFIED.
  • uint16_t wc_id
    • A wall clock identifier that indicates the time domain this probe resides in. If this probe does not use wall clock time or belongs to no other time domains, use MODALITY_PROBE_WALL_CLOCK_ID_LOCAL_ONLY.
  • modality_probe_next_sequence_id_fn next_sid_fn
    • Function pointer to a user defined persistent sequence number retrieval. If null, then next_sequence_id_user_state is unused and this probe will not do any restart handling (any events logged after a restart will be seen as duplicates). Otherwise, if non-null, then the probe will call this function to retrieve a new sequence number when needed.
  • void *next_sid_state
    • User state provided to the next_sequence_id_fn function (if one was provided).
  • modality_probe **probe
    • Receives the pointer to the newly initialization probe instance, which will be somewhere within the provided destination memory.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the probe description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD

MODALITY_PROBE_RECORD(probe, event, ...)

Record an event with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this identifier.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_TIME

MODALITY_PROBE_RECORD_W_TIME(probe, event, time_ns, ...)

Record an event with time, with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_I8

MODALITY_PROBE_RECORD_W_I8(probe, event, payload, ...)

Record an event with an i8 payload along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • int8_t payload
    • The payload.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_I8_W_TIME

MODALITY_PROBE_RECORD_W_I8_W_TIME(probe, event, payload, time_ns, ...)

Record an event with an i8 payload and wall clock time, along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • int8_t payload
    • The payload.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_U8

MODALITY_PROBE_RECORD_W_U8(probe, event, payload, ...)

Record an event with a u8 payload along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • uint8_t payload
    • The payload.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_U8_W_TIME

MODALITY_PROBE_RECORD_W_U8_W_TIME(probe, event, payload, time_ns, ...)

Record an event with a u8 payload and wall clock time, along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • uint8_t payload
    • The payload.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_I16

MODALITY_PROBE_RECORD_W_I16(probe, event, payload, ...)

Record an event with an i16 payload along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • int16_t payload
    • The payload.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_I16_W_TIME

MODALITY_PROBE_RECORD_W_I16_W_TIME(probe, event, payload, time_ns, ...)

Record an event with an i16 payload and wall clock time, along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • int16_t payload
    • The payload.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_U16

MODALITY_PROBE_RECORD_W_U16(probe, event, payload, ...)

Record an event with a u16 payload along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • uint16_t payload
    • The payload.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_U16_W_TIME

MODALITY_PROBE_RECORD_W_U16_W_TIME(probe, event, payload, time_ns, ...)

Record an event with a u16 payload and wall clock time, along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • uint16_t payload
    • The payload.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_I32

MODALITY_PROBE_RECORD_W_I32(probe, event, payload, ...)

Record an event with an i32 payload along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • int32_t payload
    • The payload.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_I32_W_TIME

MODALITY_PROBE_RECORD_W_I32_W_TIME(probe, event, payload, time_ns, ...)

Record an event with an i32 payload and wall clock time, along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • int32_t payload
    • The payload.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_U32

MODALITY_PROBE_RECORD_W_U32(probe, event, payload, ...)

Record an event with a u32 payload along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • uint32_t payload
    • The payload.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_U32_W_TIME

MODALITY_PROBE_RECORD_W_U32_W_TIME(probe, event, payload, time_ns, ...)

Record an event with a u32 payload and wall clock time, along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • uint32_t payload
    • The payload.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_BOOL

MODALITY_PROBE_RECORD_W_BOOL(probe, event, payload, ...)

Record an event with a bool payload along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • bool payload
    • The payload.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_BOOL_W_TIME

MODALITY_PROBE_RECORD_W_BOOL_W_TIME(probe, event, payload, time_ns, ...)

Record an event with a bool payload and wall clock time, along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • bool payload
    • The payload.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_F32

MODALITY_PROBE_RECORD_W_F32(probe, event, payload, ...)

Record an event with an f32 payload along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • float payload
    • The payload.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_RECORD_W_F32_W_TIME

MODALITY_PROBE_RECORD_W_F32_W_TIME(probe, event, payload, time_ns, ...)

Record an event with an f32 payload and wall clock time, along with metadata information for the CLI tooling.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • float payload
    • The payload.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Description: A string for the event description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_EXPECT

MODALITY_PROBE_EXPECT(probe, event, expr, ...)

Record an expectation with metadata information for the CLI tooling. Expectations aid analysis by highlighting potential problems, impact certain metrics, and can influence the mutation planner.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • expr
    • Boolean expression for expectation success, true is passing.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Severity: MODALITY_SEVERITY(<level>)

  • Description: A string for the expectation description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_EXPECT_W_TIME

MODALITY_PROBE_EXPECT_W_TIME(probe, event, expr, time_ns, ...)

Record an expectation with time, with metadata information for the CLI tooling. Expectations aid analysis by highlighting potential problems, impact certain metrics, and can influence the mutation planner.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • expr
    • Boolean expression for expectation success, true is passing.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Severity: MODALITY_SEVERITY(<level>)

  • Description: A string for the expectation description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_FAILURE

MODALITY_PROBE_FAILURE(probe, event, ...)

Record a failure with metadata information for the CLI tooling. Failures aid analysis by highlighting problems, impact certain metrics, and can influence the mutation planner.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Severity: MODALITY_SEVERITY(<level>)

  • Description: A string for the failure description.

Returns: One of the modality_probe_error error values.

# MODALITY_PROBE_FAILURE_W_TIME

MODALITY_PROBE_FAILURE_W_TIME(probe, event, time_ns, ...)

Record a failure with time, with metadata information for the CLI tooling. Failures aid analysis by highlighting problems, impact certain metrics, and can influence the mutation planner.

Parameters:

  • modality_probe *probe
    • The probe instance to use.
  • identifier event
    • Token to serve as the event identifier. The header-gen command will create a header file assigning an integer value to this token.
  • uint64_t time_ns
    • The wall clock time, limited to 61 bits of nanoseconds.

The trailing variadic no-op macro arguments accept (in any order):

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

  • Severity: MODALITY_SEVERITY(<level>)

  • Description: A string for the failure description.

Returns: One of the modality_probe_error error values.

# MODALITY_TAGS

#define MODALITY_TAGS(...)

Modality probe tags specifying macro. This is a no-op macro used from the function-like macros to expose tags to the CLI tooling. It accepts a comma separated list of tag strings. Note that tag strings must not contain any ( or ) characters.

# MODALITY_SEVERITY

#define MODALITY_SEVERITY(level)

Modality probe severity level specifying macro. This is a no-op macro used from the function-like macros to expose metadata to the CLI tooling. The levels are aligned with the FMEA severity ratings, going from one to ten, with one indicating negligible or nonexistent harm, and ten indicating a safety or regulatory hazard.

# MODALITY_PROBE_MACROS_ENABLED

#ifndef MODALITY_PROBE_MACROS_ENABLED
#define MODALITY_PROBE_MACROS_ENABLED 1
#endif

Modality probe macros are enabled by default. They can be disabled by defining MODALITY_PROBE_MACROS_ENABLED=0. This effectively makes the invocations a no-op, returning MODALITY_PROBE_ERROR_OK where a return code is expected.

# MODALITY_PROBE_NULL_INITIALIZER

#define MODALITY_PROBE_NULL_INITIALIZER (NULL)

A default NULL initializer value for a modality_probe pointer.

# MODALITY_PROBE_WALL_CLOCK_ID_LOCAL_ONLY

#define MODALITY_PROBE_WALL_CLOCK_ID_LOCAL_ONLY (0)

This time domain is local to the probe only.

# MODALITY_PROBE_TIME_RESOLUTION_UNSPECIFIED

#define MODALITY_PROBE_TIME_RESOLUTION_UNSPECIFIED (0)

Unspecified wall clock time resolution.

# MODALITY_PROBE_ID_BROADCAST

#define MODALITY_PROBE_ID_BROADCAST (0)

A control message will use this value to indicate that the message is intended to be broadcast to all probes.

# Functions

# modality_probe_report

size_t modality_probe_report(
        modality_probe *probe,
        uint8_t *log_report_destination,
        size_t log_report_destination_bytes,
        size_t *out_written_bytes);

Conduct necessary background activities, then write a report of recorded events and logical clock data to a supplied destination buffer.

Parameters:

  • probe
    • The probe instance to use.
  • log_report_destination
    • The destination buffer to be written to.
  • log_report_destination_bytes
    • Size of the destination buffer in bytes.
  • out_written_bytes
    • Number of bytes written to the destination buffer.

Returns: One of the modality_probe_error error values.

# modality_probe_produce_snapshot

size_t modality_probe_produce_snapshot(
        modality_probe *probe,
        modality_probe_causal_snapshot *snapshot);

Produce a transmittable summary of this probe's causal history for use by another probe elsewhere in the system. This snapshot should be merged by the receiving probe with modality_probe_merge_snapshot.

Parameters:

  • probe
    • The probe instance to use.
  • snapshot
    • The destination snapshot to receive this probe’s causal history summary.

Returns: One of the modality_probe_error error values.

# modality_probe_produce_snapshot_bytes

size_t modality_probe_produce_snapshot_bytes(
        modality_probe *probe,
        uint8_t *history_destination,
        size_t history_destination_bytes,
        size_t *out_written_bytes);

Produce a transmittable opaque blob of this probe's causal history for use by another probe elsewhere in the system. This function allows you to avoid parsing the snapshot data into the modality_probe_causal_snapshot type, instead encoding it in a system-architecture independent way. This snapshot should be merged by the receiving probe with modality_probe_merge_snapshot_bytes.

Parameters:

  • probe
    • The probe instance to use.
  • history_destination
    • The destination buffer to be written to.
  • history_destination_bytes
    • Size of the destination buffer in bytes.
  • out_written_bytes
    • Number of bytes written to the destination buffer.

Returns: One of the modality_probe_error error values.

# modality_probe_merge_snapshot

size_t modality_probe_merge_snapshot(
        modality_probe *probe,
        const modality_probe_causal_snapshot *snapshot);

Consume a causal history summary structure provided by some other probe.

Parameters:

  • probe
    • The probe instance to use.
  • snapshot
    • The snapshot to merge.

Returns: One of the modality_probe_error error values.

# modality_probe_merge_snapshot_bytes

size_t modality_probe_merge_snapshot_bytes(
        modality_probe *probe,
        const uint8_t *history_source,
        size_t history_source_bytes);

Consume an opaque causal history blob provided by some other probe.

Parameters:

  • probe
    • The probe instance to use.
  • history_source
    • The snapshot buffer to merge.
  • history_source_bytes
    • Size of the snapshot buffer in bytes.

Returns: One of the modality_probe_error error values.

# modality_probe_now

modality_probe_instant modality_probe_now(
        modality_probe *probe);

Capture the probe instance's moment in causal time for correlation with external systems.

Parameters:

  • probe
    • The probe instance to use. If null, returns an modality_probe_instant with its clock.id value set to the invalid probe id 0.

Returns: A modality_probe_instant.

# modality_probe_get_control_message_destination

size_t modality_probe_get_control_message_destination(
        const uint8_t *message_source,
        size_t message_source_bytes,
        uint32_t *target_probe_id);

Retrieve the target probe id from a control-message-containing buffer. The target probe id may be a specific probe id or MODALITY_PROBE_ID_BROADCAST for broadcast. Processing control messages is required for mutation functionality and for correlating your stimulus with events recorded in the SUT (e.g. scopes). The SUT should listen on the control connections listed in Modality.toml to receive and process messages.

Parameters:

  • message_source
    • The buffer containing a control message.
  • message_source_bytes
    • Size of the buffer in bytes.
  • target_probe_id
    • The destination probe id to be written to.

Returns: One of the modality_probe_error error values.

# modality_probe_process_control_message

size_t modality_probe_process_control_message(
        modality_probe *probe,
        const uint8_t *message_source,
        size_t message_source_bytes,
        size_t *should_forward);

Process a control message. If the message is meant for the probe passed as the first parameter it will be processed, otherwise it will be ignored. Processing control messages is required for mutation functionality and for correlating your stimulus with events recorded in the SUT (e.g. scopes). The SUT should listen on the control connections listed in Modality.toml to receive and process messages.

Parameters:

  • probe
    • The probe instance to use.
  • message_source
    • The control message buffer to process.
  • message_source_bytes
    • Size of the control message buffer in bytes.
  • should_forward
    • If the control message is targeting this probe, should_forward will be set to zero. Otherwise if this control message is broadcast (see MODALITY_PROBE_ID_BROADCAST) or targeting another probe, should_forward will be set to one.

Returns: One of the modality_probe_error error values.

# modality_probe_announce_mutators

size_t modality_probe_announce_mutators(
        modality_probe *probe,
        uint8_t *announcement_destination,
        size_t announcement_destination_size_bytes,
        size_t *out_written_bytes);

Write mutator announcement data to a supplied destination buffer. The mutator announcement data produced by this function must be sent to one of modalityd’s collector connections at least once per session. modalityd will gracefully handle receiving mutator announcement data multiple times.

Parameters:

  • probe
    • The probe instance to use.
  • announcement_destination
    • The destination buffer to be written to.
  • announcement_destination_size_bytes
    • Size of the destination buffer in bytes.
  • out_written_bytes
    • Number of bytes written to the destination buffer.

Returns: One of the modality_probe_error error values.

# Typedefs

# modality_probe_error

typedef enum {} modality_probe_error;

Modality probe error values.

Possible Values:

  • MODALITY_PROBE_ERROR_OK
    • Everything is okay.
  • MODALITY_PROBE_ERROR_NULL_POINTER
    • A null pointer was provided to the function.
  • MODALITY_PROBE_ERROR_INVALID_EVENT_ID
    • An event id outside of the allowed range was provided.
  • MODALITY_PROBE_ERROR_INVALID_PROBE_ID
    • A probe id outside of the allowed range was provided.
  • MODALITY_PROBE_ERROR_INSUFFICIENT_DESTINATION_BYTES
    • The size available for output bytes was insufficient to store a valid representation.
  • MODALITY_PROBE_ERROR_EXCEEDED_MAXIMUM_ADDRESSABLE_SIZE
    • Bumped into a pointer size limitation.
  • MODALITY_PROBE_ERROR_EXCEEDED_AVAILABLE_CLOCKS
    • The local probe does not have enough space to track all of direct neighbors attempting to communicate with it. Detected during merging.
  • MODALITY_PROBE_ERROR_INSUFFICIENT_SOURCE_BYTES
    • The external history source buffer we attempted to merge was insufficiently sized for a valid causal snapshot. Detected during merging.
  • MODALITY_PROBE_ERROR_INVALID_EXTERNAL_HISTORY_SEMANTICS
    • The provided external history violated a semantic rule of the protocol, such as by having a probe id outside of the allowed value range. Detected during merging.
  • MODALITY_PROBE_ERROR_RESTART_PERSISTENCE_SEQUENCE_ID_UNAVAILABLE
    • The user-supplied restart persistence counter failed to produce the next sequence id.
  • MODALITY_PROBE_ERROR_INVALID_WALL_CLOCK_TIME
    • A wall clock time outside of the allowed range was provided.
  • MODALITY_PROBE_ERROR_INTERNAL_ENCODING_ERROR
    • An unexpected error in internal data encoding occurred.
  • MODALITY_PROBE_ERROR_EXCEEDED_AVAILABLE_MUTATOR_SLOTS
    • The local probe does not have enough space to track the mutator that was just attempted to be registered.
  • MODALITY_PROBE_ERROR_MALFORMED_ANNOUNCEMENT
    • The announcement data was malformed. The local probe does not have enough space to track the mutator that was just attempted to be registered.

# modality_probe modality_probe

typedef struct modality_probe modality_probe;

Modality probe is the opaque type of a probe instance. Expected to be single-threaded.

# modality_probe_logical_clock

typedef struct modality_probe_logical_clock {
    uint32_t id;
    uint16_t epoch;
    uint16_t ticks;
} modality_probe_logical_clock;

A single logical clock, usable as an entry in a vector clock.

Fields:

  • id
    • The Modality probe that this clock is tracking.
  • epoch
    • Clock epoch.
  • ticks
    • Clock tick count.

# modality_probe_instant

typedef struct modality_probe_instant {
    modality_probe_logical_clock clock;
    uint32_t event_count;
} modality_probe_instant;

A situated moment in causal time.

Fields:

  • clock
    • The current probe's logical clock.
  • event_count
    • How many events have been seen since the source instance reached the associated clock's point in causal time.

# modality_probe_causal_snapshot

typedef struct modality_probe_causal_snapshot {
    modality_probe_logical_clock clock;
    uint8_t reserved_0[2];
    uint8_t reserved_1[2];
} modality_probe_causal_snapshot;

Snapshot of causal history for transmission around the system.

Fields:

  • clock
    • Probe id and tick-count at the probe which this history snapshot was created from.
  • reserved_0
    • Reserved field.
  • reserved_1
    • Reserved field.

# modality_probe_next_sequence_id_fn

typedef size_t (*modality_probe_next_sequence_id_fn)(
        uint32_t probe_id,
        void *user_state,
        uint16_t *out_sequence_id);

Function type for retrieving the next persistent sequence number.

This method is called when a probe initializes to get the initial epoch portion of the clock, and each time the ticks portion of the clock overflows during the probe's lifetime.

The function should return MODALITY_PROBE_ERROR_OK when the next sequence value could be retrieved and was used to populate the value at out_sequence_id.

The sequence number starts at zero, and should be monotonically increased by a step size of one after each retrieval.

When the sequence number reaches its maximum value (0xFFFF), it should wrap around to the value 0.

If no sequence number could be retrieved, the function should return MODALITY_PROBE_ERROR_RESTART_PERSISTENCE_SEQUENCE_ID_UNAVAILABLE.

Parameters:

  • probe_id
    • The probe identifier for the probe calling this function.
  • user_state
    • The user’s state passed from modality_probe_initialize.
  • out_sequence_id
    • The next user provided sequence identifier for the probe to use.

Returns: One of the modality_probe_error error values.

# Mutating

# Macros

The following macros are used to register mutators along with additional metadata for the CLI tooling, like mutator parameter definitional content, description and tag strings. The extra metadata is detected by the CLI for generating manifest information and mutator definitions, and compiles away.

# MODALITY_MUTATOR

MODALITY_MUTATOR(probe, mutator_token, param_token, param_def, data_ptr, data_size, ...)

Modality data mutator. This macro exposes arbitrary user data (local or global) as a parameter for mutation. Multiple invocations may be used for a given mutator_token to associate multiple data parameters under a single mutator, up to 6 parameters per mutator. The mutator-gen command will generate a corresponding mutator definition and implementation based on the information exposed in the macro invocation.

Parameters:

  • modality_probe *probe
    • The probe instance to use. The generated mutator will be automatically registered with this probe on the first call.
  • identifier mutator_token
    • The mutator identifier token. This will be used to name the mutator, where the name is converted to canonical form (a lower case hyphenated string).
  • identifier param_token
    • A parameter identifier token that uniquely identifiers this parameter within the mutator. Multiple invocations may be used for a given mutator_token to associate multiple data parameters under a single mutator, up to 6 parameters per mutator.
  • param_def
    • The mutator parameter definition. Specified using the MODALITY_PARAM_DEF macro.
  • data_ptr
    • A pointer to the user’s data to be exposed for mutation.
  • size_t data_size
    • The size of the user’s data to be exposed for mutation, in bytes.

The optional trailing variadic no-op macro argument accepts:

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

Returns: Void

# MODALITY_MUTATOR_DELAY_MS

MODALITY_MUTATOR_DELAY_MS(probe, mutator_token, unique_name, delay_def, delay_fn_ptr, ...)

Modality delay-milliseconds mutator. This macro exposes a delay-milliseconds value as a parameter for mutation, provided to a user-defined delay function. The Modality probe CLI will generate a corresponding mutator definition and implementation based on the information exposed in the macro invocation.

Parameters:

  • modality_probe *probe
    • The probe instance to use. The generated mutator will be automatically registered with this probe on the first call.
  • identifier mutator_token
    • The mutator identifier token. This will be used to name the mutator, where the name is converted to canonical form (a lower case hyphenated string).
  • identifier unique_name
    • A parameter identifier token that uniquely identifiers this parameter within the mutator. Multiple invocations may be used for a given mutator_token to associate multiple data parameters under a single mutator.
  • delay_def
  • delay_fn_ptr
    • A pointer to the user’s delay-milliseconds function. The function prototype is void my_delay_ms(const uint32_t ms).

The optional trailing variadic no-op macro argument accepts:

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

Returns: Void

# MODALITY_MUTATOR_FN_CALL

MODALITY_MUTATOR_FN_CALL(probe, mutator_token, unique_name, fn_ptr, ...)

Modality function-call mutator. This macro provides a convenient way to generate a mutator that calls an arbitrary user defined function as a mutation. The Modality probe CLI will generate a corresponding mutator definition and implementation based on the information exposed in the macro invocation.

Parameters:

  • modality_probe *probe
    • The probe instance to use. The generated mutator will be automatically registered with this probe on the first call.
  • identifier mutator_token
    • The mutator identifier token. This will be used to name the mutator, where the name is converted to canonical form (a lower case hyphenated string).
  • identifier unique_name
    • A parameter identifier token that uniquely identifiers this parameter within the mutator. Multiple invocations may be used for a given mutator_token to associate multiple data parameters under a single mutator.
  • fn_ptr
    • A pointer to the user’s function to be called when a mutation is injected. The function prototype is void my_fn(void).

The optional trailing variadic no-op macro argument accepts:

  • Tags: MODALITY_TAGS(“<tag>”[,”<tag>”])

Returns: Void

# MODALITY_PARAM_DEF

#define MODALITY_PARAM_DEF(...)

A no-op macro used to define a Modality mutator parameter definition parsed by the Modality probe CLI.

Parameters for primitive types:

  • Parameter type
    • I8 - signed 8-bit integer
    • I16 - signed 16-bit integer
    • I32 - signed 32-bit integer
    • I64 - signed 64-bit integer
    • U8 - unsigned 8-bit integer
    • U16 - unsigned 16-bit integer
    • U32 - unsigned 32-bit integer
    • U64 - unsigned 64-bit integer
    • F32 - 32-bit float
    • F64 - 64-bit float
  • Minimum effect value
    • Value for the parameter which is expected to have the least impact on the system under test.
  • Nominal range
    • Specified using the NOMINAL(inclusive_start, inclusive_end) format
  • Safety range
    • Specified using the SAFETY(inclusive_start, inclusive_end) format
  • Hard range
    • Specified using the HARD(inclusive_start, inclusive_end) format

Parameters for boolean types:

  • Parameter type, must be BOOLEAN
  • Minimum effect value
    • Must be true or false.
    • Value for the parameter which is expected to have the least impact on the system under test.

Parameters for enum types:

  • Parameter type, must be ENUM
  • Minimum effect value
    • Must be one of the supplied enum variant values.
    • Value for the parameter which is expected to have the least impact on the system under test.
  • One or more enum value and name pairs
    • Specified using the ENUM_VALUE_NAME(value, "ENUM_VALUE_NAME") format.
    • Note that enum values are limited to the range of an i32.

Parameters for byte blob types:

  • Parameter type, must be BYTE_BLOB
  • Minimum effect value
    • Value for the parameter which is expected to have the least impact on the system under test.
  • Nominal range
    • Specified using the NOMINAL(inclusive_start, inclusive_end) format.
  • Safety range
    • Specified using the SAFETY(inclusive_start, inclusive_end) format.
  • Hard range
    • Specified using the HARD(inclusive_start, inclusive_end) format.

Note that byte blob range constraints specify the number of bytes to generate, limited to the range of a u32.

# MODALITY_DELAY_MS_DEF

#define MODALITY_DELAY_MS_DEF(...)

A no-op macro used to define a Modality delay-milliseconds mutator parameter definition parsed by the Modality probe CLI.

Parameters:

  • Minimum effect value
    • Value for the parameter which is expected to have the least impact on the system under test.
  • Nominal range
    • Specified using the NOMINAL(inclusive_start, inclusive_end) format.
  • Safety range
    • Specified using the SAFETY(inclusive_start, inclusive_end) format.
  • Hard range
    • Specified using the HARD(inclusive_start, inclusive_end) format.

Note that the minimum effect value and range constraints are limited to the range of a u32.

# MODALITY_MUTATOR_MACROS_ENABLED

#ifndef MODALITY_MUTATOR_MACROS_ENABLED
#define MODALITY_MUTATOR_MACROS_ENABLED 1
#endif

Modality mutator macros are enabled by default. They can be disabled by defining MODALITY_MUTATOR_MACROS_ENABLED=0. This effectively makes the invocations a no-op.