in prov/sockets/src/sock_ep.c [1595:1785]
int sock_alloc_endpoint(struct fid_domain *domain, struct fi_info *info,
struct sock_ep **ep, void *context, size_t fclass)
{
int ret;
struct sock_ep *sock_ep;
struct sock_tx_ctx *tx_ctx;
struct sock_rx_ctx *rx_ctx;
struct sock_domain *sock_dom;
assert(info);
sock_dom = container_of(domain, struct sock_domain, dom_fid);
sock_ep = calloc(1, sizeof(*sock_ep));
if (!sock_ep)
return -FI_ENOMEM;
switch (fclass) {
case FI_CLASS_EP:
sock_ep->ep.fid.fclass = FI_CLASS_EP;
sock_ep->ep.fid.context = context;
sock_ep->ep.fid.ops = &sock_ep_fi_ops;
sock_ep->ep.ops = &sock_ep_ops;
sock_ep->ep.cm = &sock_ep_cm_ops;
sock_ep->ep.msg = &sock_ep_msg_ops;
sock_ep->ep.rma = &sock_ep_rma;
sock_ep->ep.tagged = &sock_ep_tagged;
sock_ep->ep.atomic = &sock_ep_atomic;
break;
case FI_CLASS_SEP:
sock_ep->ep.fid.fclass = FI_CLASS_SEP;
sock_ep->ep.fid.context = context;
sock_ep->ep.fid.ops = &sock_ep_fi_ops;
sock_ep->ep.ops = &sock_ep_ops;
sock_ep->ep.cm = &sock_ep_cm_ops;
break;
default:
ret = -FI_EINVAL;
goto err1;
}
sock_ep->attr = (struct sock_ep_attr *) calloc(1, sizeof(struct sock_ep_attr));
if (!sock_ep->attr) {
ret = -FI_ENOMEM;
goto err1;
}
sock_ep->attr->fclass = fclass;
*ep = sock_ep;
sock_ep->attr->info.caps = info->caps;
sock_ep->attr->info.addr_format = info->addr_format;
if (info->ep_attr) {
sock_ep->attr->ep_type = info->ep_attr->type;
sock_ep->attr->ep_attr.tx_ctx_cnt = info->ep_attr->tx_ctx_cnt;
sock_ep->attr->ep_attr.rx_ctx_cnt = info->ep_attr->rx_ctx_cnt;
}
if (info->src_addr) {
sock_ep->attr->src_addr = calloc(1, sizeof(*sock_ep->
attr->src_addr));
if (!sock_ep->attr->src_addr) {
ret = -FI_ENOMEM;
goto err2;
}
memcpy(sock_ep->attr->src_addr, info->src_addr,
info->src_addrlen);
}
if (info->dest_addr) {
sock_ep->attr->dest_addr = calloc(1, sizeof(*sock_ep->
attr->dest_addr));
if (!sock_ep->attr->dest_addr) {
ret = -FI_ENOMEM;
goto err2;
}
memcpy(sock_ep->attr->dest_addr, info->dest_addr,
info->dest_addrlen);
}
if (info->tx_attr) {
sock_ep->tx_attr = *info->tx_attr;
if (!(sock_ep->tx_attr.op_flags & (FI_INJECT_COMPLETE |
FI_TRANSMIT_COMPLETE | FI_DELIVERY_COMPLETE)))
sock_ep->tx_attr.op_flags |= FI_TRANSMIT_COMPLETE;
sock_ep->tx_attr.size = sock_ep->tx_attr.size ?
sock_ep->tx_attr.size : SOCK_EP_TX_SZ;
}
if (info->rx_attr)
sock_ep->rx_attr = *info->rx_attr;
sock_ep->attr->info.handle = info->handle;
if (!sock_ep->attr->src_addr && sock_ep_assign_src_addr(sock_ep, info)) {
SOCK_LOG_ERROR("failed to get src_address\n");
ret = -FI_EINVAL;
goto err2;
}
ofi_atomic_initialize32(&sock_ep->attr->ref, 0);
ofi_atomic_initialize32(&sock_ep->attr->num_tx_ctx, 0);
ofi_atomic_initialize32(&sock_ep->attr->num_rx_ctx, 0);
fastlock_init(&sock_ep->attr->lock);
if (sock_ep->attr->ep_attr.tx_ctx_cnt == FI_SHARED_CONTEXT)
sock_ep->attr->tx_shared = 1;
if (sock_ep->attr->ep_attr.rx_ctx_cnt == FI_SHARED_CONTEXT)
sock_ep->attr->rx_shared = 1;
if (sock_ep->attr->fclass != FI_CLASS_SEP) {
sock_ep->attr->ep_attr.tx_ctx_cnt = 1;
sock_ep->attr->ep_attr.rx_ctx_cnt = 1;
}
sock_ep->attr->tx_array = calloc(sock_ep->attr->ep_attr.tx_ctx_cnt,
sizeof(struct sock_tx_ctx *));
if (!sock_ep->attr->tx_array) {
ret = -FI_ENOMEM;
goto err2;
}
sock_ep->attr->rx_array = calloc(sock_ep->attr->ep_attr.rx_ctx_cnt,
sizeof(struct sock_rx_ctx *));
if (!sock_ep->attr->rx_array) {
ret = -FI_ENOMEM;
goto err2;
}
if (sock_ep->attr->fclass != FI_CLASS_SEP) {
/* default tx ctx */
tx_ctx = sock_tx_ctx_alloc(&sock_ep->tx_attr, context,
sock_ep->attr->tx_shared);
if (!tx_ctx) {
ret = -FI_ENOMEM;
goto err2;
}
tx_ctx->ep_attr = sock_ep->attr;
tx_ctx->domain = sock_dom;
if (tx_ctx->rx_ctrl_ctx && tx_ctx->rx_ctrl_ctx->is_ctrl_ctx)
tx_ctx->rx_ctrl_ctx->domain = sock_dom;
tx_ctx->tx_id = 0;
dlist_insert_tail(&sock_ep->attr->tx_ctx_entry, &tx_ctx->ep_list);
sock_ep->attr->tx_array[0] = tx_ctx;
sock_ep->attr->tx_ctx = tx_ctx;
/* default rx_ctx */
rx_ctx = sock_rx_ctx_alloc(&sock_ep->rx_attr, context,
sock_ep->attr->rx_shared);
if (!rx_ctx) {
ret = -FI_ENOMEM;
goto err2;
}
rx_ctx->ep_attr = sock_ep->attr;
rx_ctx->domain = sock_dom;
rx_ctx->rx_id = 0;
dlist_insert_tail(&sock_ep->attr->rx_ctx_entry, &rx_ctx->ep_list);
sock_ep->attr->rx_array[0] = rx_ctx;
sock_ep->attr->rx_ctx = rx_ctx;
}
/* default config */
sock_ep->attr->min_multi_recv = SOCK_EP_MIN_MULTI_RECV;
if (info)
memcpy(&sock_ep->attr->info, info, sizeof(struct fi_info));
sock_ep->attr->domain = sock_dom;
fastlock_init(&sock_ep->attr->cm.lock);
if (sock_conn_map_init(sock_ep, sock_cm_def_map_sz)) {
SOCK_LOG_ERROR("failed to init connection map\n");
ret = -FI_EINVAL;
goto err2;
}
ofi_atomic_inc32(&sock_dom->ref);
return 0;
err2:
if (sock_ep->attr) {
free(sock_ep->attr->src_addr);
free(sock_ep->attr->dest_addr);
free(sock_ep->attr);
}
err1:
free(sock_ep);
return ret;
}