/*
 * Simple trace backend
 *
 * Copyright IBM, Corp. 2010
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
 */

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <pthread.h>
#include "qemu-timer.h"
#include "trace.h"

/** Trace file header event ID */
#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */

/** Trace file magic number */
#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL

/** Trace file version number, bump if format changes */
#define HEADER_VERSION 0

/** Records were dropped event ID */
#define DROPPED_EVENT_ID (~(uint64_t)0 - 1)

/** Trace record is valid */
#define TRACE_RECORD_VALID ((uint64_t)1 << 63)

/** Trace buffer entry */
typedef struct {
    uint64_t event;
    uint64_t timestamp_ns;
    uint64_t x1;
    uint64_t x2;
    uint64_t x3;
    uint64_t x4;
    uint64_t x5;
    uint64_t x6;
} TraceRecord;

enum {
    TRACE_BUF_LEN = 4096,
    TRACE_BUF_FLUSH_THRESHOLD = TRACE_BUF_LEN / 4,
};

/*
 * Trace records are written out by a dedicated thread.  The thread waits for
 * records to become available, writes them out, and then waits again.
 */
static pthread_mutex_t trace_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t trace_available_cond = PTHREAD_COND_INITIALIZER;
static pthread_cond_t trace_empty_cond = PTHREAD_COND_INITIALIZER;
static bool trace_available;
static bool trace_writeout_enabled;

static TraceRecord trace_buf[TRACE_BUF_LEN];
static unsigned int trace_idx;
static FILE *trace_fp;
static char *trace_file_name = NULL;

/**
 * Read a trace record from the trace buffer
 *
 * @idx         Trace buffer index
 * @record      Trace record to fill
 *
 * Returns false if the record is not valid.
 */
static bool get_trace_record(unsigned int idx, TraceRecord *record)
{
    if (!(trace_buf[idx].event & TRACE_RECORD_VALID)) {
        return false;
    }

    __sync_synchronize(); /* read memory barrier before accessing record */

    *record = trace_buf[idx];
    record->event &= ~TRACE_RECORD_VALID;
    return true;
}

/**
 * Kick writeout thread
 *
 * @wait        Whether to wait for writeout thread to complete
 */
static void flush_trace_file(bool wait)
{
    pthread_mutex_lock(&trace_lock);
    trace_available = true;
    pthread_cond_signal(&trace_available_cond);

    if (wait) {
        pthread_cond_wait(&trace_empty_cond, &trace_lock);
    }

    pthread_mutex_unlock(&trace_lock);
}

static void wait_for_trace_records_available(void)
{
    pthread_mutex_lock(&trace_lock);
    while (!(trace_available && trace_writeout_enabled)) {
        pthread_cond_signal(&trace_empty_cond);
        pthread_cond_wait(&trace_available_cond, &trace_lock);
    }
    trace_available = false;
    pthread_mutex_unlock(&trace_lock);
}

static void *writeout_thread(void *opaque)
{
    TraceRecord record;
    unsigned int writeout_idx = 0;
    unsigned int num_available, idx;
    size_t unused;

    for (;;) {
        wait_for_trace_records_available();

        num_available = trace_idx - writeout_idx;
        if (num_available > TRACE_BUF_LEN) {
            record = (TraceRecord){
                .event = DROPPED_EVENT_ID,
                .x1 = num_available,
            };
            unused = fwrite(&record, sizeof(record), 1, trace_fp);
            writeout_idx += num_available;
        }

        idx = writeout_idx % TRACE_BUF_LEN;
        while (get_trace_record(idx, &record)) {
            trace_buf[idx].event = 0; /* clear valid bit */
            unused = fwrite(&record, sizeof(record), 1, trace_fp);
            idx = ++writeout_idx % TRACE_BUF_LEN;
        }

        fflush(trace_fp);
    }
    return NULL;
}

static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
                  uint64_t x4, uint64_t x5, uint64_t x6)
{
    unsigned int idx;
    uint64_t timestamp;

    if (!trace_list[event].state) {
        return;
    }

    timestamp = get_clock();

    idx = __sync_fetch_and_add(&trace_idx, 1) % TRACE_BUF_LEN;
    trace_buf[idx] = (TraceRecord){
        .event = event,
        .timestamp_ns = timestamp,
        .x1 = x1,
        .x2 = x2,
        .x3 = x3,
        .x4 = x4,
        .x5 = x5,
        .x6 = x6,
    };
    __sync_synchronize(); /* write barrier before marking as valid */
    trace_buf[idx].event |= TRACE_RECORD_VALID;

    if ((idx + 1) % TRACE_BUF_FLUSH_THRESHOLD == 0) {
        flush_trace_file(false);
    }
}

void trace0(TraceEventID event)
{
    trace(event, 0, 0, 0, 0, 0, 0);
}

void trace1(TraceEventID event, uint64_t x1)
{
    trace(event, x1, 0, 0, 0, 0, 0);
}

void trace2(TraceEventID event, uint64_t x1, uint64_t x2)
{
    trace(event, x1, x2, 0, 0, 0, 0);
}

void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3)
{
    trace(event, x1, x2, x3, 0, 0, 0);
}

void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
{
    trace(event, x1, x2, x3, x4, 0, 0);
}

void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5)
{
    trace(event, x1, x2, x3, x4, x5, 0);
}

void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6)
{
    trace(event, x1, x2, x3, x4, x5, x6);
}

void st_set_trace_file_enabled(bool enable)
{
    if (enable == !!trace_fp) {
        return; /* no change */
    }

    /* Halt trace writeout */
    flush_trace_file(true);
    trace_writeout_enabled = false;
    flush_trace_file(true);

    if (enable) {
        static const TraceRecord header = {
            .event = HEADER_EVENT_ID,
            .timestamp_ns = HEADER_MAGIC,
            .x1 = HEADER_VERSION,
        };

        trace_fp = fopen(trace_file_name, "w");
        if (!trace_fp) {
            return;
        }

        if (fwrite(&header, sizeof header, 1, trace_fp) != 1) {
            fclose(trace_fp);
            trace_fp = NULL;
            return;
        }

        /* Resume trace writeout */
        trace_writeout_enabled = true;
        flush_trace_file(false);
    } else {
        fclose(trace_fp);
        trace_fp = NULL;
    }
}

/**
 * Set the name of a trace file
 *
 * @file        The trace file name or NULL for the default name-<pid> set at
 *              config time
 */
bool st_set_trace_file(const char *file)
{
    st_set_trace_file_enabled(false);

    free(trace_file_name);

    if (!file) {
        if (asprintf(&trace_file_name, CONFIG_TRACE_FILE, getpid()) < 0) {
            trace_file_name = NULL;
            return false;
        }
    } else {
        if (asprintf(&trace_file_name, "%s", file) < 0) {
            trace_file_name = NULL;
            return false;
        }
    }

    st_set_trace_file_enabled(true);
    return true;
}

void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
{
    stream_printf(stream, "Trace file \"%s\" %s.\n",
                  trace_file_name, trace_fp ? "on" : "off");
}

void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
{
    unsigned int i;

    for (i = 0; i < TRACE_BUF_LEN; i++) {
        TraceRecord record;

        if (!get_trace_record(i, &record)) {
            continue;
        }
        stream_printf(stream, "Event %" PRIu64 " : %" PRIx64 " %" PRIx64
                      " %" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 "\n",
                      record.event, record.x1, record.x2,
                      record.x3, record.x4, record.x5,
                      record.x6);
    }
}

void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
{
    unsigned int i;

    for (i = 0; i < NR_TRACE_EVENTS; i++) {
        stream_printf(stream, "%s [Event ID %u] : state %u\n",
                      trace_list[i].tp_name, i, trace_list[i].state);
    }
}

bool st_change_trace_event_state(const char *name, bool enabled)
{
    unsigned int i;

    for (i = 0; i < NR_TRACE_EVENTS; i++) {
        if (!strcmp(trace_list[i].tp_name, name)) {
            trace_list[i].state = enabled;
            return true;
        }
    }
    return false;
}

void st_flush_trace_buffer(void)
{
    flush_trace_file(true);
}

bool st_init(const char *file)
{
    pthread_t thread;
    pthread_attr_t attr;
    sigset_t set, oldset;
    int ret;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    sigfillset(&set);
    pthread_sigmask(SIG_SETMASK, &set, &oldset);
    ret = pthread_create(&thread, &attr, writeout_thread, NULL);
    pthread_sigmask(SIG_SETMASK, &oldset, NULL);

    if (ret != 0) {
        return false;
    }

    atexit(st_flush_trace_buffer);
    st_set_trace_file(file);
    return true;
}
