/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * counter.h: simple and packet/byte counters
 *
 * Copyright (c) 2008 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef included_vlib_counter_h
#define included_vlib_counter_h

#include <vlib/counter_types.h>

/** \file

    Optimized thread-safe counters.

    Each vlib_[simple|combined]_counter_main_t consists of a per-thread
    vector of per-object counters.

    The idea is to drastically eliminate atomic operations.
*/

/** A collection of simple counters */

typedef struct
{
  counter_t **counters;	 /**< Per-thread u64 non-atomic counters */
  char *name;			/**< The counter collection's name. */
  char *stat_segment_name;    /**< Name in stat segment directory */
} vlib_simple_counter_main_t;

/** The number of counters (not the number of per-thread counters) */
u32 vlib_simple_counter_n_counters (const vlib_simple_counter_main_t * cm);

/** Increment a simple counter
    @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
    @param thread_index - (u32) the current cpu index
    @param index - (u32) index of the counter to increment
    @param increment - (u64) quantitiy to add to the counter
*/
always_inline void
vlib_increment_simple_counter (vlib_simple_counter_main_t * cm,
			       u32 thread_index, u32 index, u64 increment)
{
  counter_t *my_counters;

  my_counters = cm->counters[thread_index];
  my_counters[index] += increment;
}

/** Decrement a simple counter
    @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
    @param thread_index - (u32) the current cpu index
    @param index - (u32) index of the counter to increment
    @param increment - (u64) quantitiy remove from the counter value
*/
always_inline void
vlib_decrement_simple_counter (vlib_simple_counter_main_t * cm,
			       u32 thread_index, u32 index, u64 decrement)
{
  counter_t *my_counters;

  my_counters = cm->counters[thread_index];

  ASSERT (my_counters[index] >= decrement);

  my_counters[index] -= decrement;
}

/** Set a simple counter
    @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
    @param thread_index - (u32) the current cpu index
    @param index - (u32) index of the counter to increment
    @param value - (u64) quantitiy to set to the counter
*/
always_inline void
vlib_set_simple_counter (vlib_simple_counter_main_t * cm,
			 u32 thread_index, u32 index, u64 value)
{
  counter_t *my_counters;

  my_counters = cm->counters[thread_index];
  my_counters[index] = value;
}

/** Get the value of a simple counter
    Scrapes the entire set of per-thread counters. Innacurate unless
    worker threads which might increment the counter are
    barrier-synchronized

    @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
    @param index - (u32) index of the counter to fetch
    @returns - (u64) current counter value
*/
always_inline counter_t
vlib_get_simple_counter (vlib_simple_counter_main_t * cm, u32 index)
{
  counter_t *my_counters;
  counter_t v;
  int i;

  ASSERT (index < vlib_simple_counter_n_counters (cm));

  v = 0;

  for (i = 0; i < vec_len (cm->counters); i++)
    {
      my_counters = cm->counters[i];
      v += my_counters[index];
    }

  return v;
}

/** Clear a simple counter
    Clears the set of per-thread u16 counters, and the u64 counter

    @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
    @param index - (u32) index of the counter to clear
*/
always_inline void
vlib_zero_simple_counter (vlib_simple_counter_main_t * cm, u32 index)
{
  counter_t *my_counters;
  int i;

  ASSERT (index < vlib_simple_counter_n_counters (cm));

  for (i = 0; i < vec_len (cm->counters); i++)
    {
      my_counters = cm->counters[i];
      my_counters[index] = 0;
    }
}

/** Add two combined counters, results in the first counter
    @param [in,out] a - (vlib_counter_t *) dst counter
    @param b - (vlib_counter_t *) src counter
*/

always_inline void
vlib_counter_add (vlib_counter_t * a, vlib_counter_t * b)
{
  a->packets += b->packets;
  a->bytes += b->bytes;
}

/** Subtract combined counters, results in the first counter
    @param [in,out] a - (vlib_counter_t *) dst counter
    @param b - (vlib_counter_t *) src counter
*/
always_inline void
vlib_counter_sub (vlib_counter_t * a, vlib_counter_t * b)
{
  ASSERT (a->packets >= b->packets);
  ASSERT (a->bytes >= b->bytes);
  a->packets -= b->packets;
  a->bytes -= b->bytes;
}

/** Clear a combined counter
    @param a - (vlib_counter_t *) counter to clear
*/
always_inline void
vlib_counter_zero (vlib_counter_t * a)
{
  a->packets = a->bytes = 0;
}

/** A collection of combined counters */
typedef struct
{
  vlib_counter_t **counters;	/**< Per-thread u64 non-atomic counter pairs */
  char *name; /**< The counter collection's name. */
  char *stat_segment_name;	/**< Name in stat segment directory */
} vlib_combined_counter_main_t;

/** The number of counters (not the number of per-thread counters) */
u32 vlib_combined_counter_n_counters (const vlib_combined_counter_main_t *
				      cm);

/** Clear a collection of simple counters
    @param cm - (vlib_simple_counter_main_t *) collection to clear
*/
void vlib_clear_simple_counters (vlib_simple_counter_main_t * cm);

/** Clear a collection of combined counters
    @param cm - (vlib_combined_counter_main_t *) collection to clear
*/
void vlib_clear_combined_counters (vlib_combined_counter_main_t * cm);

/** Increment a combined counter
    @param cm - (vlib_combined_counter_main_t *) comined counter main pointer
    @param thread_index - (u32) the current cpu index
    @param index - (u32) index of the counter to increment
    @param packet_increment - (u64) number of packets to add to the counter
    @param byte_increment - (u64) number of bytes to add to the counter
*/

always_inline void
vlib_increment_combined_counter (vlib_combined_counter_main_t * cm,
				 u32 thread_index,
				 u32 index, u64 n_packets, u64 n_bytes)
{
  vlib_counter_t *my_counters;

  /* Use this CPU's counter array */
  my_counters = cm->counters[thread_index];

  my_counters[index].packets += n_packets;
  my_counters[index].bytes += n_bytes;
}

/** Pre-fetch a per-thread combined counter for the given object index */
always_inline void
vlib_prefetch_combined_counter (const vlib_combined_counter_main_t * cm,
				u32 thread_index, u32 index)
{
  vlib_counter_t *cpu_counters;

  /*
   * This CPU's index is assumed to already be in cache
   */
  cpu_counters = cm->counters[thread_index];
  CLIB_PREFETCH (cpu_counters + index, CLIB_CACHE_LINE_BYTES, STORE);
}


/** Get the value of a combined counter, never called in the speed path
    Scrapes the entire set of per-thread counters. Innacurate unless
    worker threads which might increment the counter are
    barrier-synchronized

    @param cm - (vlib_combined_counter_main_t *) combined counter main pointer
    @param index - (u32) index of the combined counter to fetch
    @param result [out] - (vlib_counter_t *) result stored here
*/

static inline void
vlib_get_combined_counter (const vlib_combined_counter_main_t * cm,
			   u32 index, vlib_counter_t * result)
{
  vlib_counter_t *my_counters, *counter;
  int i;

  result->packets = 0;
  result->bytes = 0;

  for (i = 0; i < vec_len (cm->counters); i++)
    {
      my_counters = cm->counters[i];

      counter = vec_elt_at_index (my_counters, index);
      result->packets += counter->packets;
      result->bytes += counter->bytes;
    }
}

/** Clear a combined counter
    Clears the set of per-thread counters.

    @param cm - (vlib_combined_counter_main_t *) combined counter main pointer
    @param index - (u32) index of the counter to clear
*/
always_inline void
vlib_zero_combined_counter (vlib_combined_counter_main_t * cm, u32 index)
{
  vlib_counter_t *my_counters, *counter;
  int i;

  for (i = 0; i < vec_len (cm->counters); i++)
    {
      my_counters = cm->counters[i];

      counter = vec_elt_at_index (my_counters, index);
      counter->packets = 0;
      counter->bytes = 0;
    }
}

/** validate a simple counter
    @param cm - (vlib_simple_counter_main_t *) pointer to the counter collection
    @param index - (u32) index of the counter to validate
*/

void vlib_validate_simple_counter (vlib_simple_counter_main_t * cm,
				   u32 index);
void vlib_free_simple_counter (vlib_simple_counter_main_t * cm);

/** validate a combined counter
    @param cm - (vlib_combined_counter_main_t *) pointer to the counter
    collection
    @param index - (u32) index of the counter to validate
*/

void vlib_validate_combined_counter (vlib_combined_counter_main_t * cm,
				     u32 index);
int vlib_validate_combined_counter_will_expand
  (vlib_combined_counter_main_t * cm, u32 index);

void vlib_free_combined_counter (vlib_combined_counter_main_t * cm);

/** Obtain the number of simple or combined counters allocated.
    A macro which reduces to to vec_len(cm->maxi), the answer in either
    case.

    @param cm - (vlib_simple_counter_main_t) or
    (vlib_combined_counter_main_t) the counter collection to interrogate
    @returns vec_len(cm->maxi)
*/
#define vlib_counter_len(cm) vec_len((cm)->maxi)

#endif /* included_vlib_counter_h */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
