/*
 * Copyright (c) 2016 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.
 */

/*
 * vlib provides lock-free counters but those
 * - Have 16bits per-CPU counter, which may overflow.
 * - Would only increment.
 *
 * This is very similar to vlib counters, but may be used to count reference.
 * Such a counter includes an arbitrary number of counters. Each counter
 * is identified by its index. This is used to aggregate per-cpu memory.
 *
 * Warning:
 *   This reference counter is lock-free but is not race-condition free.
 *   The counting result is approximate and another mechanism needs to be used
 *   in order to ensure that an object may be freed.
 *
 */

#include <vnet/vnet.h>

/*
 * Reference counting
 * A specific reference counter is used. The design is quite
 * similar to vlib counters but:
 *   - It is possible to decrease the value
 *   - Summing will not zero the per-thread counters
 *   - Only the thread can reallocate its own counters vector (to avoid concurrency issues)
*/
typedef struct {
  u32 *counters;
  volatile u32 *counter_lock;
  CLIB_CACHE_LINE_ALIGN_MARK(o);
} vlib_refcount_per_cpu_t;

typedef struct {
  vlib_refcount_per_cpu_t *per_cpu;
} vlib_refcount_t;

static_always_inline
void vlib_refcount_lock (volatile u32 *counter_lock)
{
  while (clib_atomic_test_and_set (counter_lock))
    ;
}

static_always_inline
void vlib_refcount_unlock (volatile u32 *counter_lock)
{
  clib_atomic_release(counter_lock);
}

void __vlib_refcount_resize(vlib_refcount_per_cpu_t *per_cpu, u32 size);

static_always_inline
void vlib_refcount_add(vlib_refcount_t *r, u32 thread_index, u32 counter_index, i32 v)
{
  vlib_refcount_per_cpu_t *per_cpu = &r->per_cpu[thread_index];
  if (PREDICT_FALSE(counter_index >= vec_len(per_cpu->counters)))
    __vlib_refcount_resize(per_cpu, clib_max(counter_index + 16,(vec_len(per_cpu->counters)) * 2));

  per_cpu->counters[counter_index] += v;
}

u64 vlib_refcount_get(vlib_refcount_t *r, u32 index);

static_always_inline
void vlib_refcount_init(vlib_refcount_t *r)
{
  vlib_thread_main_t *tm = vlib_get_thread_main ();
  u32 thread_index;
  r->per_cpu = 0;
  vec_validate (r->per_cpu, tm->n_vlib_mains - 1);

  for (thread_index = 0; thread_index < tm->n_vlib_mains; thread_index++)
    {
      r->per_cpu[thread_index].counter_lock =
	  clib_mem_alloc_aligned(CLIB_CACHE_LINE_BYTES,CLIB_CACHE_LINE_BYTES);
      r->per_cpu[thread_index].counter_lock[0] = 0;
    }
}


