1
1
openmpi/ompi/mca/btl/pcie/btl_pcie_fifo.h
Ralph Castain 4d3aa5a8a4 Once again, into the breach!
Yes, friends, our favorite PCIE BTL has resurfaced as mgmt vacillates over its existence. This is an updated version that actually mostly works, in its final stages of debugging.

Some generalization still remains to be done...

This commit was SVN r21358.
2009-06-02 22:26:36 +00:00

172 строки
4.7 KiB
C

/*
* Copyright (c) 2007 Los Alamos National Security, LLC.
* All righs reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef BTL_PCIE_FIFO_H
#define BTL_PCIE_FIFO_H
#include "ompi_config.h"
#include "ompi/constants.h"
#include "opal/threads/mutex.h"
#include "opal/types.h"
#include "ompi/mca/btl/base/btl_base_error.h"
BEGIN_C_DECLS
typedef uint64_t btl_pcie_fifo_entry_t;
#define BTL_PCIE_FIFO_TYPE_MASK 0x8000000000000000
#define BTL_PCIE_FIFO_DATA_MASK 0x7FFFFFFFFFFFFFFF
#define BTL_PCIE_FIFO_TYPE_ACK 0x0000000000000000
#define BTL_PCIE_FIFO_TYPE_SEND 0x8000000000000000
struct btl_pcie_fifo_t {
/* number of entries in queue */
uint32_t fifo_len;
/* for sender: next place to write
* for receiver: next place to read */
uint32_t current_index;
/* for sender: number of entries "in flight". Must always be less
than or equal to fifo_len */
uint32_t num_outstanding;
uint32_t mask;
/* the actual buffer */
btl_pcie_fifo_entry_t* queue;
};
typedef struct btl_pcie_fifo_t btl_pcie_fifo_t;
/**
* Initialize fifo structure
*
* Initialize send/recv fifo structure. The fifo structure does
* double duty of maintaining both the sender and receiver. This
* function initializes the send view of the fifo structure, for
* use to receive messages. fifo_get_msg() should not be called on
* this fifo.
*
* @note fifo_len must match the value given to the matching
* fifo_init_recv(), although there are no checks to verify this.
*
* @param[in] fifo A pointer to a fifo structure to be
* initialized
* @param[in] fifo_len Requested length of the fifo queue
* @param[in] queue_space Space for the receive queue (remote pointer)
*
* @retval OMPI_SUCCESS Everything worked
* @retval OMPI_ERROR Good luck!
*/
int ompi_btl_pcie_fifo_init_send(btl_pcie_fifo_t *fifo,
unsigned int fifo_len,
void *queue_space);
/**
* Initialize fifo structure
*
* Initialize send/recv fifo structure. The fifo structure does
* double duty of maintaining both the sender and receiver. This
* function initializes the receive view of the fifo structure, for
* use to receive messages. fifo_set_msg() should not be called on
* this fifo.
*
* @note fifo_len must match the value given to the matching
* fifo_init_send(), although there are no checks to verify this.
*
* @param[in] fifo A pointer to a fifo structure to be
* initialized
* @param[in] fifo_len Requested length of the fifo queue
* @param[in] queue_space Space for the receive queue (local pointer)
* @param[in] queue_space_len Length of queue_space
*
* @retval OMPI_SUCCESS Everything worked
* @retval OMPI_ERROR Good luck!
*/
int ompi_btl_pcie_fifo_init_recv(btl_pcie_fifo_t *fifo,
unsigned int fifo_len,
void *queue_space,
size_t queue_space_len);
int ompi_btl_pcie_fifo_finalize(btl_pcie_fifo_t *fifo);
/**
* Read a message from the queue
*
* Read a message from the queue
*
* @param[in] fifo The receive view of the fifo
*
* @return A non-zero message or 0 if no new messages are
* available.
*/
static inline btl_pcie_fifo_entry_t
ompi_btl_pcie_fifo_get_msg(btl_pcie_fifo_t *fifo)
{
/* BWB - TODO - if we ever want to be multi-threaded, we'll
need to fix this */
btl_pcie_fifo_entry_t ret = 0;
if (0 != (ret = fifo->queue[fifo->current_index])) {
fifo->queue[fifo->current_index] = 0;
fifo->current_index++;
fifo->current_index &= fifo->mask;
}
return ret;
}
/**
* Write a message pointer into the queue
*
* Write a message pointer into the send queue view of the fifo.
*
* @param[in] fifo The send view of the fifo
* @param[in] msg The index to the payload to deliver
*
* @retval OMPI_SUCCESS Fifo successfully updated
* @retval OMPI_ERR_RESOURCE_BUSY There was no space in the fifo
*/
static inline int
ompi_btl_pcie_fifo_set_msg(btl_pcie_fifo_t *fifo, btl_pcie_fifo_entry_t msg)
{
uint32_t outstanding;
/* see if we have a slot */
outstanding = OPAL_THREAD_ADD32(&fifo->num_outstanding, 1);
if (outstanding > fifo->fifo_len) {
OPAL_THREAD_ADD32(&fifo->num_outstanding, -1);
return OMPI_ERR_RESOURCE_BUSY;
}
/* now that we have a slot, figure out where it is. Allow the
outstanding to wrap around forever - just mask out the bits we
don't care about. */
outstanding = OPAL_THREAD_ADD32(&fifo->current_index, 1);
outstanding &= fifo->mask;
fifo->queue[outstanding] = msg;
return OMPI_SUCCESS;
}
static inline int
ompi_btl_pcie_fifo_complete_msg(btl_pcie_fifo_t *fifo,
unsigned int num_msgs)
{
OPAL_THREAD_ADD32(&fifo->num_outstanding, -num_msgs);
return OMPI_SUCCESS;
}
END_C_DECLS
#endif /* BTL_PCIE_FIFO_H */