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

#ifndef included_vlibmemory_api_common_h
#define included_vlibmemory_api_common_h

#include <svm/svm_common.h>
#include <vlibapi/api.h>
#include <vlibmemory/memory_api.h>
#include <vlibmemory/memory_client.h>
#include <vlibmemory/socket_api.h>
#include <vlibmemory/socket_client.h>

void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
void vl_api_force_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
u16 vl_client_get_first_plugin_msg_id (const char *plugin_name);
u8 *vl_api_serialize_message_table (api_main_t * am, u8 * vector);

always_inline void
vl_api_send_msg (vl_api_registration_t * rp, u8 * elem)
{
  if (PREDICT_FALSE (rp->registration_type > REGISTRATION_TYPE_SHMEM))
    {
      vl_socket_api_send (rp, elem);
    }
  else
    {
      vl_msg_api_send_shmem (rp->vl_input_queue, (u8 *) & elem);
    }
}

always_inline int
vl_api_can_send_msg (vl_api_registration_t * rp)
{
  if (PREDICT_FALSE (rp->registration_type > REGISTRATION_TYPE_SHMEM))
    return 1;
  else
    return vl_mem_api_can_send (rp->vl_input_queue);
}

/*
 * Suggests to an API handler to relinguish control. Currently limits
 * an handler to a maximum of 1ms or it earlier if the client queue is
 * full.
 *
 * May be enhanced in the future based on other performance
 * characteristics of the main thread.
 */
#define VL_API_MAX_TIME_IN_HANDLER 0.001	/* 1 ms */
always_inline int
vl_api_process_may_suspend (vlib_main_t * vm, vl_api_registration_t * rp,
			    f64 start)
{
  /* Is client queue full (leave space for reply message) */
  if (rp->registration_type <= REGISTRATION_TYPE_SHMEM &&
      rp->vl_input_queue->cursize + 1 >= rp->vl_input_queue->maxsize)
    return true;
  if (vlib_time_now (vm) > start + VL_API_MAX_TIME_IN_HANDLER)
    return true;
  return false;
}

always_inline vl_api_registration_t *
vl_api_client_index_to_registration (u32 index)
{
  if (vl_socket_api_registration_handle_is_valid (ntohl (index)))
    return vl_socket_api_client_handle_to_registration (ntohl (index));
  return vl_mem_api_client_index_to_registration (index);
}

always_inline u32
vl_api_registration_file_index (vl_api_registration_t * reg)
{
  return reg->clib_file_index;
}

always_inline clib_file_t *
vl_api_registration_file (vl_api_registration_t * reg)
{
  return clib_file_get (&file_main, vl_api_registration_file_index (reg));
}

always_inline void
vl_api_registration_del_file (vl_api_registration_t * reg)
{
  clib_file_t *cf = vl_api_registration_file (reg);
  if (cf)
    clib_file_del (&file_main, cf);
}

always_inline clib_error_t *
vl_api_send_fd_msg (vl_api_registration_t * reg, int fds[], int n_fds)
{
  clib_file_t *cf = vl_api_registration_file (reg);
  if (cf)
    return vl_sock_api_send_fd_msg (cf->file_descriptor, fds, n_fds);
  return 0;
}

always_inline clib_error_t *
vl_api_recv_fd_msg (vl_api_registration_t * reg, int fds[], int n_fds,
		    u32 wait)
{
  clib_file_t *cf = vl_api_registration_file (reg);
  if (cf)
    return vl_sock_api_recv_fd_msg (cf->file_descriptor, fds, n_fds, wait);
  return 0;
}

/*
 * vl_api_clnt process data used by transports (socket api in particular)
 */
extern vlib_node_registration_t vl_api_clnt_node;
extern volatile int **vl_api_queue_cursizes;

typedef enum vl_api_clnt_process_events
{
  QUEUE_SIGNAL_EVENT = 1,
  SOCKET_READ_EVENT
} vl_api_clnt_process_events_t;

#define foreach_histogram_bucket                \
_(400)                                          \
_(200)                                          \
_(100)                                          \
_(10)

typedef enum
{
#define _(n) SLEEP_##n##_US,
  foreach_histogram_bucket
#undef _
    SLEEP_N_BUCKETS,
} histogram_index_t;

extern u64 vector_rate_histogram[];

/*
 * sockclnt APIs XXX are these actually used anywhere?
 */
vl_api_registration_t *sockclnt_get_registration (u32 index);
void socksvr_add_pending_output (struct clib_file *uf,
				 struct vl_api_registration_ *cf,
				 u8 * buffer, uword buffer_bytes);
void vl_socket_process_msg (struct clib_file *uf,
			    struct vl_api_registration_ *rp, i8 * input_v);
u32 sockclnt_open_index (char *client_name, char *hostname, int port);
void sockclnt_close_index (u32 index);
void vl_client_msg_api_send (vl_api_registration_t * cm, u8 * elem);

#endif /* included_vlibmemory_api_common_h */

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