/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

#ifndef MPIDI_CH3_IMPL_H_INCLUDED
#define MPIDI_CH3_IMPL_H_INCLUDED

#include "mpidimpl.h"
#include "ch3usock.h"

/* This is all socket connection definitions */

    /* MT - not thread safe! */

/* The SendQ will add a reference to the request in order to prevent
 * manipulating the next field after the request has been destroyed.  This
 * ref will be dropped after dequeueing.  (tt#1038) */

#define MPIDI_CH3I_SendQ_enqueue(vcch, req)				\
{									\
    MPL_DBG_MSG(MPIDI_CH3_DBG_MSG,TYPICAL,"Enqueuing this request");\
    MPIR_Request_add_ref(req);                                          \
    req->next = NULL;						\
    if (vcch->sendq_tail != NULL)					\
    {									\
	vcch->sendq_tail->next = req;				\
    }									\
    else								\
    {									\
	vcch->sendq_head = req;					\
    }									\
    vcch->sendq_tail = req;						\
}

    /* MT - not thread safe! */
#define MPIDI_CH3I_SendQ_enqueue_head(vcch, req)			\
{									\
    MPL_DBG_MSG(MPIDI_CH3_DBG_MSG,TYPICAL,"Enqueuing this request at head");\
    MPIR_Request_add_ref(req);                                          \
    req->next = vcch->sendq_head;					\
    if (vcch->sendq_tail == NULL)					\
    {									\
	vcch->sendq_tail = req;					\
    }									\
    vcch->sendq_head = req;						\
}

    /* MT - not thread safe! */
#define MPIDI_CH3I_SendQ_dequeue(vcch)					\
{									\
    MPIR_Request *req_ = vcch->sendq_head;                              \
    MPL_DBG_MSG(MPIDI_CH3_DBG_MSG,TYPICAL,"Dequeuing this request");\
    vcch->sendq_head = vcch->sendq_head->next;			\
    if (vcch->sendq_head == NULL)					\
    {									\
	vcch->sendq_tail = NULL;					\
    }									\
    MPIR_Request_free(req_);                                         \
}


#define MPIDI_CH3I_SendQ_head(vcch) (vcch->sendq_head)

#define MPIDI_CH3I_SendQ_empty(vcch) (vcch->sendq_head == NULL)

/* End of connection-related macros */

/* FIXME: Any of these used in the ch3->channel interface should be
   defined in a header file in ch3/include that defines the
   channel interface */
int MPIDI_CH3I_Progress_init(void);
int MPIDI_CH3I_Progress_finalize(void);
int MPIDI_CH3I_VC_post_connect(MPIDI_VC_t *);

/* Shared memory window atomic/accumulate mutex implementation */

#define MPIDI_CH3I_SHM_MUTEX_LOCK(win_ptr)
#define MPIDI_CH3I_SHM_MUTEX_UNLOCK(win_ptr)
#define MPIDI_CH3I_SHM_MUTEX_INIT(win_ptr)
#define MPIDI_CH3I_SHM_MUTEX_DESTROY(win_ptr)

#endif /* MPIDI_CH3_IMPL_H_INCLUDED */
