ovni/doc/user/runtime/mark.md

5.4 KiB

Mark API

The mark API allows you to add arbitrary events in a trace to mark regions of interest while debugging or developing a new program or library. The events are processed by the emulator to generate a timeline.

Usage in runtime

Follow these steps to correctly use the API. Most problems will be detected in emulation and cause a panic if you are not careful.

Create a mark type

You can create up to 100 types of marks, each will be shown in its own Paraver timeline. To create a new type, use the following call:

void ovni_mark_type(int32_t type, long flags, const char *title);

The numeric value type must be a number between 0 and 99 (both included). The title will be used to give a name to the Paraver timeline.

The default with flags set to zero, is to create a channel that can hold a single value only (see channels). To use a stack of values add the OVNI_MARK_STACK value to the flags.

Define labels (optional)

The values that are written to the channel can have labels to display in the Paraver timeline. The labels are optional, if not given the numeric value will be shown in Paraver.

Use the following call to register a label for a value in a given type.

void ovni_mark_label(int32_t type, int64_t value, const char *label);

Emit events

All mark channels begin with the default value null, which is not shown in Paraver and will be displayed as the usual empty space. The value of the channel can be changed over time with the following functions.

!!! warning

The value 0 is forbidden, as it is used by Paraver to represent the
"empty" state.

If you have used a single channel (without OVNI_MARK_STACK), then you must use the following call to emit events at runtime:

void ovni_mark_set(int32_t type, int64_t value);

It will update the value of the channel to the given value.

If you have used a stack channel (with OVNI_MARK_STACK), then you must use the push/pop set of calls:

void ovni_mark_push(int32_t type, int64_t value);
void ovni_mark_pop(int32_t type, int64_t value);

The value in the pop call must match the previous pushed value.

Usage in Paraver

Each thread holds a channel for each mark type that you have defined. The information of the mark channels is propagated to the Paraver timeline in Thread and CPU views.

When a thread is not running, the value of the mark channels is not shown in Paraver. In the case of the CPU timeline, only the values of the running thread are shown. If there are no running threads, nothing is shown.

Follow the next steps to create a configuration to suit your needs. You only need to do it once, then you can save the configuration file and reuse it for future traces.

Filtering the type

To see a mark type, you will have to create a Paraver configuration that matches the type that you have created. The mark type value gets converted into a PRV type by adding 100 (as values from 0 to 99 are reserved).

You can use the cpu/ovni/mark.cfg and thread/ovni/mark.cfg configurations as a starting point to create your own.

Go to "Window Properties" (the second button under "Files & Window Properties") and then go to Filter > Events > Event type. Set Function to = and click the Types value to display the [...] button, which will allow you to choose which type to display.

In the "Events Selection" window, ensure that only one type is selected, and the "Values" panel shows Function "All", to see all values for the selected type.

Setting the title

In the "Window Properties" adjust the Name so it reflects what you are seeing. This will be shown in the saved images, so it is good to use a proper description.

Configure the display method

By default, the timeline will display the values as "Code color". To switch to a gradient or other methods, left-click in the timeline and go to "Paint As" and select "Gradient" (or others).

You may also want to adjust the "Drawmode" which determines what happens when there are multiple values under a given pixel. This is specially important when you are viewing the trace with a large time range, before zooming into a given region.

By default, the "Random not zero" mode is selected, which will select a random value from the ones under each pixel, disregarding the occurrences of each value. This mode will give importance to rare values, so it is usually a safe starting point. The "Last" mode will show the last value in that pixel, which is more or less fair, but will often hide rare values.

To change in both horizontal (Time) and in vertical (Objects) directions, go to: left click on timeline > Drawmode > Both > Last.

Ensure the range is good

Paraver will only display values in the timeline that are in the Semantic range. If you see a red triangle in the lower left corner then there are values outside the range that are not being displayed. You can click on this button to expand the range to cover all values in the current view.

The opposite may also happen, where the range is too big for the current values. You can also click on the same spot (even if the triangle is not shown) to shrink the range to cover the values in the view, or go to the Window Properties and modify the "Semantic Minimum" and "Semantic Maximum" values manually.

Save the configuration

Once you finish configuring the timeline, save the configuration by left-clicking the view and then "Save > Configuration...". You can use this configuration in future traces to avoid doing these steps again.