/*
<:copyright-BRCM:2014:proprietary:standard
 
   Copyright (c) 2014 Broadcom Corporation
   All Rights Reserved
 
This program is the proprietary software of Broadcom Corporation and/or its
licensors, and may only be used, duplicated, modified or distributed pursuant
to the terms and conditions of a separate, written license agreement executed
between you and Broadcom (an "Authorized License").  Except as set forth in
an Authorized License, Broadcom grants no license (express or implied), right
to use, or waiver of any kind with respect to the Software, and Broadcom
expressly reserves all rights in and to the Software and all intellectual
property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE
NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY
BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
 
Except as expressly set forth in the Authorized License,
 
1. This program, including its structure, sequence and organization,
    constitutes the valuable trade secrets of Broadcom, and you shall use
    all reasonable efforts to protect the confidentiality thereof, and to
    use this information only in connection with your use of Broadcom
    integrated circuit products.
 
2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
    AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
    WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
    RESPECT TO THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND
    ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT,
    FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
    COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE
    TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF USE OR
    PERFORMANCE OF THE SOFTWARE.
 
3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
    ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL,
    INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY
    WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
    IF BROADCOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES;
    OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
    SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS
    SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
    LIMITED REMEDY.
:>
*/

#include <bcmos_system.h>
#include "bcmolt_time_measurement.h"

typedef struct
{
    dev_log_id log_id;
    uint32_t num_cycles_for_average;
    F_bcmolt_time_measurement_ticks_to_ns ticks_to_ns;
    F_bcmolt_time_measurement_avg_done avg_done;
    uint32_t cycle_num;
} bcmolt_time_measurement_context;

static bcmolt_time_measurement_context time_measurement_context = { DEV_LOG_INVALID_ID, 0, NULL, NULL, 0 };

void bcmolt_time_measurement_init(
    dev_log_id log_id,
    uint32_t num_cycles_for_average,
    F_bcmolt_time_measurement_ticks_to_ns ticks_to_ns,
    F_bcmolt_time_measurement_avg_done avg_done)
{
    time_measurement_context = (bcmolt_time_measurement_context)
        { log_id, num_cycles_for_average, ticks_to_ns, avg_done, 0 };
}

void bcmolt_time_measurement_sample_end(uint64_t *total_ticks, uint32_t *num_of_samples, const char *measurement_name)
{
    /* Don't do anything if we haven't run enough cycles to produce an average. */
    if (time_measurement_context.cycle_num < (time_measurement_context.num_cycles_for_average - 1))
    {
        return;
    }

    if (*num_of_samples != 0 && time_measurement_context.ticks_to_ns != NULL)
    {
        /* Convert the sample time from ticks to ns. */
        uint64_t duration_average_ns = time_measurement_context.ticks_to_ns(*total_ticks / *num_of_samples);

        /* The ":" is used as delimiter when importing to excel. */
        BCM_LOG(
            DEBUG,
            time_measurement_context.log_id,
            ":%s: %llu.%03llu us (%u hits)\n",
            measurement_name,
            (long long unsigned int)(duration_average_ns / 1000),
            (long long unsigned int)(duration_average_ns % 1000),
            *num_of_samples);
    }

    *total_ticks = 0;
    *num_of_samples = 0;
}

void bcmolt_time_measurement_cycle_end(void)
{
    if (time_measurement_context.cycle_num == (time_measurement_context.num_cycles_for_average - 1))
    {
        if (time_measurement_context.avg_done != NULL)
        {
            time_measurement_context.avg_done();
        }

        /* Print a delimiting line. */
        BCM_LOG(DEBUG, time_measurement_context.log_id, "\n");
        time_measurement_context.cycle_num = 0;
    }
    else
    {
        ++time_measurement_context.cycle_num;
    }
}
