// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//
// Types, constants, and inline functions used to encode and decode trace records.
//

#pragma once

#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>

__BEGIN_CDECLS

// Timebase recorded into trace files, as returned by zx_ticks_get().
typedef uint64_t trace_ticks_t;

// The ids used to correlate related counters, asynchronous operations, and flows.
typedef uint64_t trace_counter_id_t;
typedef uint64_t trace_async_id_t;
typedef uint64_t trace_flow_id_t;

// Specifies the scope of instant events.
typedef enum {
    // The event is only relevant to the thread it occurred on.
    TRACE_SCOPE_THREAD = 0,
    // The event is only relevant to the process in which it occurred.
    TRACE_SCOPE_PROCESS = 1,
    // The event is globally relevant.
    TRACE_SCOPE_GLOBAL = 2,
} trace_scope_t;

// Thread states used to describe context switches.
// Use the |ZX_THREAD_STATE_XXX| values defined in <zircon/syscalls/object.h>.
typedef uint32_t trace_thread_state_t;

// Identifies a particular CPU in a context switch trace record.
typedef uint32_t trace_cpu_number_t;

// Contains a thread's priority in a context switch trace record.
typedef uint32_t trace_thread_priority_t;

// Represents an index into the string table.
typedef uint32_t trace_string_index_t;

// Represents the encoded form of string references.
typedef uint32_t trace_encoded_string_ref_t;
#define TRACE_ENCODED_STRING_REF_EMPTY ((trace_encoded_string_ref_t)0u)
#define TRACE_ENCODED_STRING_REF_INLINE_FLAG ((trace_encoded_string_ref_t)0x8000u)
#define TRACE_ENCODED_STRING_REF_LENGTH_MASK ((trace_encoded_string_ref_t)0x7fffu)
#define TRACE_ENCODED_STRING_REF_MAX_LENGTH ((trace_encoded_string_ref_t)32000)
#define TRACE_ENCODED_STRING_REF_MIN_INDEX ((trace_encoded_string_ref_t)0x1u)
#define TRACE_ENCODED_STRING_REF_MAX_INDEX ((trace_encoded_string_ref_t)0x7fffu)

// Represents an index into the thread table.
typedef uint32_t trace_thread_index_t;

// Represents the encoded form of thread references.
typedef uint32_t trace_encoded_thread_ref_t;
#define TRACE_ENCODED_THREAD_REF_INLINE ((trace_encoded_thread_ref_t)0u)
#define TRACE_ENCODED_THREAD_REF_MIN_INDEX ((trace_encoded_thread_ref_t)0x01)
#define TRACE_ENCODED_THREAD_REF_MAX_INDEX ((trace_encoded_thread_ref_t)0xff)

// A string reference which is either encoded inline or indirectly by string table index.
typedef struct trace_string_ref {
    trace_encoded_string_ref_t encoded_value;
    const char* inline_string; // only non-null for inline strings
} trace_string_ref_t;

// Makes true if the string ref's content is empty.
inline bool trace_is_empty_string_ref(const trace_string_ref_t* string_ref) {
    return string_ref->encoded_value == TRACE_ENCODED_STRING_REF_EMPTY;
}

// Returns true if the string ref's content is stored inline (rather than empty or indexed).
inline bool trace_is_inline_string_ref(const trace_string_ref_t* string_ref) {
    return string_ref->encoded_value & TRACE_ENCODED_STRING_REF_INLINE_FLAG;
}

// Returns true if the string ref's content is stored as an index into the string table.
inline bool trace_is_indexed_string_ref(const trace_string_ref_t* string_ref) {
    return string_ref->encoded_value >= TRACE_ENCODED_STRING_REF_MIN_INDEX &&
           string_ref->encoded_value <= TRACE_ENCODED_STRING_REF_MAX_INDEX;
}

// Returns the length of an inline string.
// Only valid for inline strings.
inline size_t trace_inline_string_ref_length(const trace_string_ref_t* string_ref) {
    return string_ref->encoded_value & TRACE_ENCODED_STRING_REF_LENGTH_MASK;
}

// Makes an empty string ref.
inline trace_string_ref_t trace_make_empty_string_ref(void) {
    trace_string_ref_t ref = {
        .encoded_value = TRACE_ENCODED_STRING_REF_EMPTY,
        .inline_string = NULL};
    return ref;
}

// Makes an inline or empty string ref from a string with given size.
// The |string| does not need to be null-terminated because its length is provided.
// The |string| must not be null if length is non-zero.
// The |string| is truncated if longer than |TRACE_ENCODED_STRING_REF_MAX_LENGTH|.
inline trace_string_ref_t trace_make_inline_string_ref(
    const char* string, size_t length) {
    if (!length)
        return trace_make_empty_string_ref();

    ZX_DEBUG_ASSERT(string != NULL);
    if (length > TRACE_ENCODED_STRING_REF_MAX_LENGTH)
        length = TRACE_ENCODED_STRING_REF_MAX_LENGTH;
    trace_string_ref_t ref = {
        .encoded_value = TRACE_ENCODED_STRING_REF_INLINE_FLAG |
                         (trace_encoded_string_ref_t)length,
        .inline_string = string};
    return ref;
}

// Makes an inline or empty string ref from a null-terminated string.
// The |string| is truncated if longer than |TRACE_ENCODED_STRING_REF_MAX_LENGTH|.
inline trace_string_ref_t trace_make_inline_c_string_ref(const char* string) {
    return trace_make_inline_string_ref(string,
                                        string ? strlen(string) : 0u);
}

// Makes an indexed string ref.
// The |index| must be >= |TRACE_ENCODED_STRING_REF_MIN_INDEX|
// and <= |TRACE_ENCODED_STRING_REF_MAX_INDEX|.
inline trace_string_ref_t trace_make_indexed_string_ref(trace_string_index_t index) {
    ZX_DEBUG_ASSERT(index >= TRACE_ENCODED_STRING_REF_MIN_INDEX &&
                    index <= TRACE_ENCODED_STRING_REF_MAX_INDEX);
    trace_string_ref_t ref = {
        .encoded_value = index,
        .inline_string = NULL};
    return ref;
}

// A thread reference which is either encoded inline or indirectly by thread table index.
typedef struct trace_thread_ref {
    trace_encoded_thread_ref_t encoded_value;
    zx_koid_t inline_process_koid;
    zx_koid_t inline_thread_koid;
} trace_thread_ref_t;

// Returns true if the thread ref's value is unknown.
inline bool trace_is_unknown_thread_ref(const trace_thread_ref_t* thread_ref) {
    return thread_ref->encoded_value == TRACE_ENCODED_THREAD_REF_INLINE &&
           thread_ref->inline_process_koid == ZX_KOID_INVALID &&
           thread_ref->inline_thread_koid == ZX_KOID_INVALID;
}

// Returns true if the thread ref's content is stored as an index into the thread table.
inline bool trace_is_indexed_thread_ref(const trace_thread_ref_t* thread_ref) {
    return thread_ref->encoded_value >= TRACE_ENCODED_THREAD_REF_MIN_INDEX &&
           thread_ref->encoded_value <= TRACE_ENCODED_THREAD_REF_MAX_INDEX;
}

// Returns true if the thread ref's value is stored inline (rather than unknown or indexed).
inline bool trace_is_inline_thread_ref(const trace_thread_ref_t* thread_ref) {
    return thread_ref->encoded_value == TRACE_ENCODED_THREAD_REF_INLINE &&
           (thread_ref->inline_process_koid != ZX_KOID_INVALID ||
            thread_ref->inline_thread_koid != ZX_KOID_INVALID);
}

// Makes a thread ref representing an unknown thread.
// TODO(ZX-1030): Reserve thread ref index 0 for unknown threads,
// use thread ref index 255 for inline threads.
inline trace_thread_ref_t trace_make_unknown_thread_ref(void) {
    trace_thread_ref_t ref = {
        .encoded_value = TRACE_ENCODED_THREAD_REF_INLINE,
        .inline_process_koid = ZX_KOID_INVALID,
        .inline_thread_koid = ZX_KOID_INVALID};
    return ref;
}

// Makes a thread ref with an inline value.
// The process and thread koids must not both be invalid.
inline trace_thread_ref_t trace_make_inline_thread_ref(zx_koid_t process_koid,
                                                       zx_koid_t thread_koid) {
    ZX_DEBUG_ASSERT(process_koid != ZX_KOID_INVALID ||
                    thread_koid != ZX_KOID_INVALID);
    trace_thread_ref_t ref = {
        .encoded_value = TRACE_ENCODED_THREAD_REF_INLINE,
        .inline_process_koid = process_koid,
        .inline_thread_koid = thread_koid};
    return ref;
}

// Makes an indexed thread ref.
// The index must be >= |TRACE_ENCODED_THREAD_REF_MIN_INDEX|
// and <= |TRACE_ENCODED_THREAD_REF_MAX_INDEX|.
inline trace_thread_ref_t trace_make_indexed_thread_ref(trace_thread_index_t index) {
    ZX_DEBUG_ASSERT(index >= TRACE_ENCODED_THREAD_REF_MIN_INDEX &&
                    index <= TRACE_ENCODED_THREAD_REF_MAX_INDEX);
    trace_thread_ref_t ref = {
        .encoded_value = (trace_encoded_thread_ref_t)index,
        .inline_process_koid = ZX_KOID_INVALID,
        .inline_thread_koid = ZX_KOID_INVALID};
    return ref;
}

// The maximum length of a trace record in bytes.
// This is constrained by the number of bits used to encode the length in
// the record header.
#define TRACE_ENCODED_RECORD_MAX_LENGTH ((size_t)32760u)

// Enumerates all known argument types.
typedef enum {
    TRACE_ARG_NULL = 0,
    TRACE_ARG_INT32 = 1,
    TRACE_ARG_UINT32 = 2,
    TRACE_ARG_INT64 = 3,
    TRACE_ARG_UINT64 = 4,
    TRACE_ARG_DOUBLE = 5,
    TRACE_ARG_STRING = 6,
    TRACE_ARG_POINTER = 7,
    TRACE_ARG_KOID = 8,
} trace_arg_type_t;

// A typed argument value.
typedef struct {
    trace_arg_type_t type;
    union {
        int32_t int32_value;
        uint32_t uint32_value;
        int64_t int64_value;
        uint64_t uint64_value;
        double double_value;
        trace_string_ref_t string_value_ref;
        uintptr_t pointer_value;
        zx_koid_t koid_value;
        uintptr_t reserved_for_future_expansion[2];
    };
} trace_arg_value_t;

// Makes a null argument value.
inline trace_arg_value_t trace_make_null_arg_value(void) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_NULL, {}};
    return arg_value;
}

// Makes a signed 32-bit integer argument value.
inline trace_arg_value_t trace_make_int32_arg_value(int32_t value) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_INT32,
                                   {.int32_value = value}};
    return arg_value;
}

// Makes an unsigned 32-bit integer argument value.
inline trace_arg_value_t trace_make_uint32_arg_value(uint32_t value) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_UINT32,
                                   {.uint32_value = value}};
    return arg_value;
}

// Makes a signed 64-bit integer argument value.
inline trace_arg_value_t trace_make_int64_arg_value(int64_t value) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_INT64,
                                   {.int64_value = value}};
    return arg_value;
}

// Makes an unsigned 64-bit integer argument value.
inline trace_arg_value_t trace_make_uint64_arg_value(uint64_t value) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_UINT64,
                                   {.uint64_value = value}};
    return arg_value;
}

// Makes a double-precision floating point argument value.
inline trace_arg_value_t trace_make_double_arg_value(double value) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_DOUBLE,
                                   {.double_value = value}};
    return arg_value;
}

// Makes a string argument value.
inline trace_arg_value_t trace_make_string_arg_value(trace_string_ref_t value_ref) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_STRING,
                                   {.string_value_ref = value_ref}};
    return arg_value;
}

// Makes a pointer argument value.
inline trace_arg_value_t trace_make_pointer_arg_value(uintptr_t value) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_POINTER,
                                   {.pointer_value = value}};
    return arg_value;
}

// Makes a koid argument value.
inline trace_arg_value_t trace_make_koid_arg_value(zx_koid_t value) {
    trace_arg_value_t arg_value = {.type = TRACE_ARG_KOID,
                                   {.koid_value = value}};
    return arg_value;
}

// A named argument and value.
// Often packed into an array to form an argument list when writing records.
typedef struct {
    trace_string_ref_t name_ref;
    trace_arg_value_t value;
} trace_arg_t;

// Makes an argument with name and value.
inline trace_arg_t trace_make_arg(trace_string_ref_t name_ref,
                                  trace_arg_value_t value) {
    trace_arg_t arg = {.name_ref = name_ref, .value = value};
    return arg;
}

// The trace format specified maximum number of args for a record.
#define TRACE_MAX_ARGS ((size_t)15u)

// BlobType enumerates all known trace blob types.
typedef enum {
    TRACE_BLOB_TYPE_DATA = 1,
} trace_blob_type_t;

// The maximum size of a blob.
// This is slightly less than the actual maximum ((= 0xfff * 8) - header size)
// to allow room for reasonably sized blob names should they get inlined.
#define TRACE_MAX_BLOB_SIZE ((size_t)32000u)

__END_CDECLS

#ifdef __cplusplus

namespace trace {

// Enumerates all known record types.
enum class RecordType {
    kMetadata = 0,
    kInitialization = 1,
    kString = 2,
    kThread = 3,
    kEvent = 4,
    kBlob = 5,
    kKernelObject = 7,
    kContextSwitch = 8,
    kLog = 9,
};

// MetadataType enumerates all known trace metadata types.
enum class MetadataType {
    kProviderInfo = 1,
    kProviderSection = 2,
    kProviderEvent = 3,
};

// Enumerates all provider events.
enum class ProviderEventType {
    kBufferOverflow = 0,
};

// Enumerates all known argument types.
enum class ArgumentType {
    kNull = TRACE_ARG_NULL,
    kInt32 = TRACE_ARG_INT32,
    kUint32 = TRACE_ARG_UINT32,
    kInt64 = TRACE_ARG_INT64,
    kUint64 = TRACE_ARG_UINT64,
    kDouble = TRACE_ARG_DOUBLE,
    kString = TRACE_ARG_STRING,
    kPointer = TRACE_ARG_POINTER,
    kKoid = TRACE_ARG_KOID,
};

// EventType enumerates all known trace event types.
enum class EventType {
    kInstant = 0,
    kCounter = 1,
    kDurationBegin = 2,
    kDurationEnd = 3,
    kAsyncBegin = 4,
    kAsyncInstant = 5,
    kAsyncEnd = 6,
    kFlowBegin = 7,
    kFlowStep = 8,
    kFlowEnd = 9,
};

// Specifies the scope of instant events.
enum class EventScope {
    kThread = TRACE_SCOPE_THREAD,
    kProcess = TRACE_SCOPE_PROCESS,
    kGlobal = TRACE_SCOPE_GLOBAL,
};

// Trace provider id in a trace session.
using ProviderId = uint32_t;

// Thread states used to describe context switches.
enum class ThreadState {
    kNew = ZX_THREAD_STATE_NEW,
    kRunning = ZX_THREAD_STATE_RUNNING,
    kSuspended = ZX_THREAD_STATE_SUSPENDED,
    kBlocked = ZX_THREAD_STATE_BLOCKED,
    kDying = ZX_THREAD_STATE_DYING,
    kDead = ZX_THREAD_STATE_DEAD,
};

using ArgumentHeader = uint64_t;
using RecordHeader = uint64_t;

} // namespace trace

#endif // __cplusplus
