Annotate v3 (DS-5 v5.22) Protocol
Index
Introduction
This document describes the TCP/IP protocol used by clients to communicate with gator v22 or later. This protocol is encapsulated in the gator frames sent to Streamline. Like the gator-Streamline protocol, the source code acts as a reference implementation. The protocol may change with future releases of Streamline, but Streamline and gator will maintain backwards compatibility with this version of the protocol so that clients need only implement one version of the protocol.
Changes in v3 (DS-5 v5.22)
Annotate v3, the version shipped with Streamline version 5.22, has a few important updates that you should familiarize yourself with before implementing or updating your own customized Annotate protocol
- Documentation fixes with respect to rendering_type and series_composition along with support for the log10 series composition
- Added a flag to the Setup Message to indicate that counter keys should not be mangled by Streamline to be unique.
Types
- int32
- 4-byte signed little endian
- packed32
- variable length packed 4-byte signed value, see Packed Values
- packed64
- variable length packed 8-byte signed value, see Packed Values
- UTF-8 chars
- Some number of UTF-8 characters, not null terminated unless explicitly indicated. Length is usually derived from the message size.
- #
- A constant packed32 value of #, ex: 5 is the packed32 number 5
- timestamp
- packed64 monotonic time value in nanoseconds using the same monotonic clock used by the gator protocol without applying the monotonic delta.
- color
- four unpacked bytes, 0xRR 0xGG 0xBB 0xTT, where TT represents 4 predefined template colors (1-4); TT of 0 cycles between the template colors; TT >= 5 uses the RRGGBB component.
Packed Values
To reduce their size, integers are packed. This is done by avoiding the transmission of duplicate high bits. The value is split into 7 bit bytes in little endian order. The most significant bit of the byte is set to 1, if there is a subsequent byte for this value. On the last byte, the most significant bit is set to 0. For positive values, the most significant encoded bit must be 0 and for negative numbers it must be 1. This is very similar to signed LEB128 used in DWARF.
| Bits |
Last value |
Byte 1 |
Byte 2 |
Byte 3 |
Byte 4 |
Byte 5 |
| 31 |
-2147483648 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
01111XXXb |
| 27 |
-134217728 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 20 |
-1048576 |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 13 |
-8192 |
1XXXXXXXb |
01XXXXXXb |
|
| 6 |
-64 |
01XXXXXXb |
|
| 6 |
63 |
00XXXXXXb |
|
| 13 |
8191 |
1XXXXXXXb |
00XXXXXXb |
|
| 20 |
1048575 |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 27 |
134217727 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 31 |
2147483647 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
00000XXXb |
For example, 429389 (01101000110101001101b) would be encoded as 0xCD (11001101b) 0x9A (10011010b) 0x1A (00011010b)
Packed 64 values work in much the same way:
| Bits |
Last value |
Byte 1 |
Byte 2 |
Byte 3 |
Byte 4 |
Byte 5 |
Byte 6 |
Byte 7 |
Byte 8 |
Byte 9 |
Byte 10 |
| 63 |
-9223372036854775808 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
0111111Xb |
| 62 |
-4611686018427387904 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 55 |
-36028797018963968 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 48 |
-281474976710656 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 41 |
-2199023255552 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 34 |
-17179869184 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 27 |
-134217728 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 20 |
-1048576 |
1XXXXXXXb |
1XXXXXXXb |
01XXXXXXb |
|
| 13 |
-8192 |
1XXXXXXXb |
01XXXXXXb |
|
| 6 |
-64 |
01XXXXXXb |
|
| 6 |
63 |
00XXXXXXb |
|
| 13 |
8191 |
1XXXXXXXb |
00XXXXXXb |
|
| 20 |
1048575 |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 27 |
134217727 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 34 |
17179869183 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 41 |
2199023255551 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 48 |
281474976710655 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 55 |
36028797018963967 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 62 |
4611686018427387903 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
00XXXXXXb |
|
| 63 |
9223372036854775807 |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
1XXXXXXXb |
0000000Xb |
For example, -4758616141418899142 would be encoded as 0xBA 0xB2 0xA5 0xA2 0xCE 0xFA 0xFF 0xFA 0xBD 0x7F.
Setup Message
This message is the first message sent by any source and is never sent again; it is used to initialize the source.
| Name |
Type |
Description |
| Magic |
String |
Value must always be ANNOTATE 3\n |
| tid |
int32 |
Thread ID. In the Linux kernel, this is the PID. |
| pid |
int32 |
Process ID. In the Linux kernel, this is the Thread Group ID |
| Don't mangle keys |
int8 |
Streamline add per-process information to keys received by annotation clients to ensure they are globally unique. If this value nonzero, then no mangling is done. |
String Messages
UTF-8 String Message
This is used to add a line in the Log tab.
| Name |
Type |
Description |
| Marker Code |
0x1 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| Channel |
packed32 |
Channel the annotation belongs to |
| UTF-8 String |
UTF-8 chars |
Text annotation |
UTF-8 Color String Message
This is used to add a line in the Log tab.
| Name |
Type |
Description |
| Marker Code |
0x2 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| Channel |
packed32 |
Channel the annotation belongs to |
| Color |
color |
|
| UTF-8 String |
UTF-8 chars |
Text annotation |
Create Channel Message
This is used to name a channel in the Thread Disclosure
| Name |
Type |
Description |
| Marker Code |
0x3 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| Channel |
packed32 |
|
| Group |
packed32 |
Group the channel belongs to |
| UTF-8 String |
UTF-8 chars |
Channel name |
Create Group Message
This is used to name a group in the Thread Disclosure
| Name |
Type |
Description |
| Marker Code |
0x4 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| Group |
packed32 |
|
| UTF-8 String |
UTF-8 chars |
Group name |
Visual Messages
Visual Message
This is used to add a line in the Log tab and an image to the Visual Annotation Chart.
| Name |
Type |
Description |
| Marker Code |
0x5 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| UTF-8 String |
UTF-8 chars, null terminated |
Text annotation |
| Image Data |
Image bytes |
|
Marker Messages
Marker Message
This is used to add a Bookmark
| Name |
Type |
Description |
| Marker Code |
0x6 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| UTF-8 String |
UTF-8 chars |
Text annotation |
Marker Color Message
This is used to add a Bookmark
| Name |
Type |
Description |
| Marker Code |
0x7 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| Color |
color |
|
| UTF-8 String |
UTF-8 chars |
Text annotation |
Counter Messages
Counter Message
Create a counter to use with a counter value or activity switch annotation, see the event node for more details
| Name |
Type |
Description |
| Marker Code |
0x8 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| key |
packed32 |
Key for this counter, unique in the process |
| per_cpu |
packed32 |
|
| class |
packed32 |
| 1 | = delta |
| 2 | = absolute |
| 3 | = activity |
| 4 | = incident |
|
| display |
packed32 |
| 1 | = average |
| 2 | = accumulate |
| 3 | = hertz |
| 4 | = maximum |
| 5 | = minimum |
|
| modifier |
packed32 |
|
| series_composition |
packed32 |
| 1 | = stacked |
| 2 | = overlay |
| 3 | = log10 |
|
| rendering_type |
packed32 |
|
| average_selection |
packed32 |
|
| average_cores |
packed32 |
|
| percentage |
packed32 |
|
| activity_count |
packed32 |
Number of activities and activity_colors |
| cores |
packed32 |
|
| Color |
color |
|
| activities |
activity_count occurances of UTF-8 chars, null terminated and 4 bytes (RR, GG, BB, TT) pairs |
|
| title |
UTF-8 chars, null terminated |
|
| name |
UTF-8 chars, null terminated |
|
| units |
UTF-8 chars, null terminated |
|
| description |
UTF-8 chars |
|
Counter Value Message
Emit a counter value similar to Counter Frame from the gator protocol
| Name |
Type |
Description |
| Marker Code |
0x9 |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| Core |
packed32 |
Core to which this counter applies |
| Key |
packed32 |
Key used when the counter was created |
| Value |
packed64 |
Value of the specified counter |
Activity Switch Message
Emit a sched switch similar to Activity Switch from the gator protocol
| Name |
Type |
Description |
| Marker Code |
0xa |
|
| Length |
int32 |
Number of bytes in the body after the length |
| Timestamp |
timestamp |
|
| Core |
packed32 |
Core on which this activity occurred |
| Key |
packed32 |
Key used when the counter was created |
| Activity |
packed32 |
One of the activity types defined when the counter was created or zero for idle |
| tid |
packed32 |
CPU thread ID (in the Linux kernel this is the PID) associated with this activity, use -1 if no tid association is desired |
Custom Activity Map Messages
Custom Activity Map Track
This is used to define a track on which jobs execute.
| Name |
Type |
Description |
| Marker Code |
0xb |
|
| Length |
int32 |
Number of bytes in the body after the length |
| ViewUID |
packed32 |
The unique id for the view, it is recommended to pick a random number to obtain the view uid |
| TrackUID |
packed32 |
A unique track id, zero is reserved for no track. The initial order of the tracks is determined by the TrackUID. |
| ParentTrack |
packed32 |
The TrackUID of the parent track or -1 if it is a root track with no parent |
| Name |
UTF-8 chars |
The name of the track |
Custom Activity Map Job
This is used to define a job within the Custom Activity Map timeline.
| Name |
Type |
Description |
| Marker Code |
0xc |
|
| Length |
int32 |
Number of bytes in the body after the length |
| ViewUID |
packed32 |
The unique id for the view, it is recommended to pick a random number to obtain the view uid |
| JobUID |
packed32 |
A unique job id |
| Track |
packed32 |
The TrackUID on which this job executes |
| StartTime |
Timestamp |
The start time of the job |
| Duration |
Timestamp |
The duration of the job |
| Color |
color |
|
| Primary Dependency |
packed32 |
The JobUID of the primary dependency. A value of -1 indicates no primary dependency. |
| Number of Dependencies |
packed32 |
The number N of dependencies to follow |
| Dependency (repeated N times) |
packed32 |
The JobUID of the dependency. A dependency is a job that must complete prior to this job running. Only direct dependencies need to be tracked. |
| Name |
UTF-8 chars |
The string name for the job |
Custom Activity Map View Name
The name for this Custom Activity Map view.
| Name |
Type |
Description |
| Marker Code |
0xd |
|
| Length |
int32 |
Number of bytes in the body after the length |
| ViewUID |
packed32 |
The unique id for the view, it is recommended to pick a random number to obtain the view uid |
| View Name |
UTF-8 chars |
The name for the view that is being described, this will be the view’s title in the UI and folder on disk. As such, the name must be a valid file system folder name. |