Program Listing for File memory_registration.c

Return to documentation for file (memory_registration.c)

#include "netio/netio.h"

#include <string.h>
#include <stdio.h>
#include "log.h"

#if defined DEBUG || defined DEBUG_MR
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#define log_dbg(...) log_log(LOG_DEBUG, __FILENAME__, __LINE__, __VA_ARGS__)
#define log_trc(...) log_log(LOG_TRACE, __FILENAME__, __LINE__, __VA_ARGS__)
#else
#define log_dbg(...)
#define log_trc(...)
#endif


static void
init_bufferstack(struct netio_buffer_stack* stack, unsigned num, size_t bufsize)
{
  stack->buffers = malloc(num*sizeof(struct netio_buffer*));
  stack->buffer_addresses = malloc(num*sizeof(struct netio_buffer*));
  stack->num_buffers = num;
  stack->available_buffers = num;
  for(unsigned int i=0; i<num; i++) {
    stack->buffers[i] = malloc(sizeof(struct netio_buffer));
    stack->buffers[i]->data = malloc(bufsize);
    stack->buffers[i]->size = bufsize;
    stack->buffers[i]->mr = NULL;
    stack->buffer_addresses[i] = stack->buffers[i];
  }

}


void netio_register_recv_buffer(struct netio_recv_socket* socket, struct netio_buffer* buf, uint64_t  flags)
{
  if (socket->tcp_fi_mode != NETIO_MODE_LIBFABRIC) {
    return;
  }

  log_trc("registering recv buffer number: %d", socket->reg_mr);
  uint64_t access = FI_RECV;
  int ret = 0;
  if((ret = fi_mr_reg(socket->domain, buf->data, buf->size, access, 0, socket->req_key++, 0, &buf->mr, NULL)))
  {
    log_fatal("Failed to register recv buffer (key %lu) failed. Error %d: %s",socket->req_key, ret, fi_strerror(-ret));
    //exit(2);
  }
  if(ret==0){
    if (socket->reg_mr >= NETIO_DOMAIN_MAX_MR){
      log_fatal("Trying to register recv buffer number %u. MR array size %lu.", socket->reg_mr, NETIO_DOMAIN_MAX_MR);
      exit(1);
    }
    socket->mr[socket->reg_mr]=&buf->mr->fid;
    socket->reg_mr+=1;
  }
}


void netio_register_send_buffer(struct netio_send_socket* socket, struct netio_buffer* buf, uint64_t flags)
{
  if (socket->tcp_fi_mode != NETIO_MODE_LIBFABRIC) {
    return;
  }

  uint64_t access = FI_SEND;
  int ret = 0;
  if((ret = fi_mr_reg(socket->domain->domain, buf->data, buf->size, access, 0, socket->domain->req_key++, 0, &buf->mr, NULL)))
  {
    log_fatal("Failed to register send buffer failed. Error %d: %s.", ret, fi_strerror(-ret));
    exit(2);
  }
  if(ret==0){
    if (socket->domain->reg_mr >= NETIO_DOMAIN_MAX_MR){
      log_fatal("Trying to register send buffer number %u. MR array size %lu.", socket->domain->reg_mr, NETIO_DOMAIN_MAX_MR);
      exit(1);
    }
    socket->domain->mr[socket->domain->reg_mr]=&buf->mr->fid;
    socket->domain->reg_mr+=1;
  }
}


void
netio_bufferstack_send_init(struct netio_buffer_stack* stack, struct netio_send_socket* socket, size_t num, size_t bufsize, uint64_t flags)
{
  log_dbg("Initializing memory: %d pages", num);
  init_bufferstack(stack, num, bufsize);
  if (socket->tcp_fi_mode==NETIO_MODE_LIBFABRIC) {
    socket->domain->reg_mr=0;
    for(unsigned i=0; i<num; i++) {
      netio_register_send_buffer(socket, stack->buffers[i], flags);
    }
  }
}

void
netio_bufferstack_close(struct netio_buffer_stack* stack, size_t num)
{
  log_dbg("Freeing memory: %d pages", num);
  for(unsigned int i=0; i < num; i++) {
    if(stack->buffers == NULL){log_warn("Buffer already released."); return;}
    free(stack->buffer_addresses[i]->data);
    free(stack->buffer_addresses[i]);
  }
  free(stack->buffers);
  free(stack->buffer_addresses);
  stack->buffers = NULL;
}


int
netio_bufferstack_pop(struct netio_buffer_stack* stack, struct netio_buffer** buffer)
{
  log_trc("pop: available %lu", stack->available_buffers);
  if(stack->available_buffers > 0) {
    stack->available_buffers--;
    *buffer = stack->buffers[stack->available_buffers];
    return 0;
  } else {
    return 1;
  }
}


int
netio_bufferstack_push(struct netio_buffer_stack* stack, struct netio_buffer* buffer)
{
  log_trc("push: available %lu", stack->available_buffers);
  if(stack->available_buffers < stack->num_buffers) {
    stack->buffers[stack->available_buffers] = buffer;
    stack->available_buffers++;
    return 0;
  } else {
    return 1;
  }
}