static int sock_poll_add(struct fid_poll *pollset, struct fid *event_fid, uint64_t flags) { struct sock_poll *poll; struct sock_fid_list *list_item; struct sock_cq *cq; struct sock_cntr *cntr; poll = container_of(pollset, struct sock_poll, poll_fid.fid); list_item = calloc(1, sizeof(*list_item)); if (!list_item) return -FI_ENOMEM; list_item->fid = event_fid; dlist_init(&list_item->entry); dlist_insert_after(&list_item->entry, &poll->fid_list); switch (list_item->fid->fclass) { case FI_CLASS_CQ: cq = container_of(list_item->fid, struct sock_cq, cq_fid); ofi_atomic_inc32(&cq->ref); break; case FI_CLASS_CNTR: cntr = container_of(list_item->fid, struct sock_cntr, cntr_fid); ofi_atomic_inc32(&cntr->ref); break; default: SOCK_LOG_ERROR("Invalid fid class\n"); return -FI_EINVAL; } return 0; }
int main() { Test *h = NULL; Test t1, t2, t3, t4; test_init(&t1); test_init(&t2); test_init(&t3); test_init(&t4); dlist_insert_after(&t1.dlist, &t2.dlist); dlist_insert_after(&t3.dlist, &t4.dlist); DLIST_PUSH(&h, &t3, dlist); DLIST_PUSH(&h, &t1, dlist); DLIST_ITERATOR_BEGIN(h, dlist, loop) { printf("@ %p {id = %d, next = %p, prev = %p}\n", loop, loop->id, loop->dlist.next, loop->dlist.prev); if (loop->id % 2 == 0) { DLIST_REMOVE_FROM(&h, loop, dlist); } } DLIST_ITERATOR_END(loop);
int sock_poll_add(struct fid_poll *pollset, struct fid *event_fid, uint64_t flags) { struct sock_poll *poll; struct sock_fid_list *list_item; poll = container_of(pollset, struct sock_poll, poll_fid.fid); list_item = calloc(1, sizeof(*list_item)); if (!list_item) return -FI_ENOMEM; list_item->fid = event_fid; dlist_init(&list_item->entry); dlist_insert_after(&list_item->entry, &poll->fid_list); return 0; }
int sock_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr, struct fid_cq **cq, void *context) { struct sock_domain *sock_dom; struct sock_cq *sock_cq; struct fi_wait_attr wait_attr; struct sock_fid_list *list_entry; struct sock_wait *wait; int ret; sock_dom = container_of(domain, struct sock_domain, dom_fid); ret = sock_cq_verify_attr(attr); if (ret) return ret; sock_cq = calloc(1, sizeof(*sock_cq)); if (!sock_cq) return -FI_ENOMEM; atomic_initialize(&sock_cq->ref, 0); sock_cq->cq_fid.fid.fclass = FI_CLASS_CQ; sock_cq->cq_fid.fid.context = context; sock_cq->cq_fid.fid.ops = &sock_cq_fi_ops; sock_cq->cq_fid.ops = &sock_cq_ops; if (attr == NULL) sock_cq->attr = _sock_cq_def_attr; else { sock_cq->attr = *attr; if (attr->size == 0) sock_cq->attr.size = _sock_cq_def_attr.size; } sock_cq->domain = sock_dom; sock_cq->cq_entry_size = sock_cq_entry_size(sock_cq); sock_cq_set_report_fn(sock_cq); dlist_init(&sock_cq->tx_list); dlist_init(&sock_cq->rx_list); dlist_init(&sock_cq->ep_list); dlist_init(&sock_cq->overflow_list); if ((ret = rbfdinit(&sock_cq->cq_rbfd, sock_cq->attr.size * sock_cq->cq_entry_size))) goto err1; if ((ret = rbinit(&sock_cq->addr_rb, sock_cq->attr.size * sizeof(fi_addr_t)))) goto err2; if ((ret = rbinit(&sock_cq->cqerr_rb, sock_cq->attr.size * sizeof(struct fi_cq_err_entry)))) goto err3; fastlock_init(&sock_cq->lock); switch (sock_cq->attr.wait_obj) { case FI_WAIT_NONE: case FI_WAIT_UNSPEC: case FI_WAIT_FD: break; case FI_WAIT_MUTEX_COND: wait_attr.flags = 0; wait_attr.wait_obj = FI_WAIT_MUTEX_COND; ret = sock_wait_open(&sock_dom->fab->fab_fid, &wait_attr, &sock_cq->waitset); if (ret) { ret = -FI_EINVAL; goto err4; } sock_cq->signal = 1; break; case FI_WAIT_SET: if (!attr) { ret = -FI_EINVAL; goto err4; } sock_cq->waitset = attr->wait_set; sock_cq->signal = 1; wait = container_of(attr->wait_set, struct sock_wait, wait_fid); list_entry = calloc(1, sizeof(*list_entry)); dlist_init(&list_entry->entry); list_entry->fid = &sock_cq->cq_fid.fid; dlist_insert_after(&list_entry->entry, &wait->fid_list); break; default: break; } *cq = &sock_cq->cq_fid; atomic_inc(&sock_dom->ref); fastlock_init(&sock_cq->list_lock); return 0; err4: rbfree(&sock_cq->cqerr_rb); err3: rbfree(&sock_cq->addr_rb); err2: rbfdfree(&sock_cq->cq_rbfd); err1: free(sock_cq); return ret; }
int sock_cntr_open(struct fid_domain *domain, struct fi_cntr_attr *attr, struct fid_cntr **cntr, void *context) { int ret; struct sock_domain *dom; struct sock_cntr *_cntr; struct fi_wait_attr wait_attr; struct sock_fid_list *list_entry; struct sock_wait *wait; dom = container_of(domain, struct sock_domain, dom_fid); if (attr && sock_cntr_verify_attr(attr)) return -FI_ENOSYS; _cntr = calloc(1, sizeof(*_cntr)); if (!_cntr) return -FI_ENOMEM; ret = pthread_cond_init(&_cntr->cond, NULL); if (ret) goto err; if (attr == NULL) memcpy(&_cntr->attr, &sock_cntr_add, sizeof(sock_cntr_attr)); else memcpy(&_cntr->attr, attr, sizeof(sock_cntr_attr)); switch (_cntr->attr.wait_obj) { case FI_WAIT_NONE: case FI_WAIT_UNSPEC: case FI_WAIT_MUTEX_COND: _cntr->signal = 0; break; case FI_WAIT_FD: wait_attr.flags = 0; wait_attr.wait_obj = FI_WAIT_FD; ret = sock_wait_open(&dom->fab->fab_fid, &wait_attr, &_cntr->waitset); if (ret) { ret = FI_EINVAL; goto err; } _cntr->signal = 1; break; case FI_WAIT_SET: if (!attr) { ret = FI_EINVAL; goto err; } _cntr->waitset = attr->wait_set; _cntr->signal = 1; wait = container_of(attr->wait_set, struct sock_wait, wait_fid); list_entry = calloc(1, sizeof(*list_entry)); dlist_init(&list_entry->entry); list_entry->fid = &_cntr->cntr_fid.fid; dlist_insert_after(&list_entry->entry, &wait->fid_list); break; default: break; } pthread_mutex_init(&_cntr->mut, NULL); fastlock_init(&_cntr->list_lock); atomic_initialize(&_cntr->ref, 0); atomic_initialize(&_cntr->err_cnt, 0); atomic_initialize(&_cntr->value, 0); atomic_initialize(&_cntr->threshold, ~0); dlist_init(&_cntr->tx_list); dlist_init(&_cntr->rx_list); dlist_init(&_cntr->trigger_list); fastlock_init(&_cntr->trigger_lock); _cntr->cntr_fid.fid.fclass = FI_CLASS_CNTR; _cntr->cntr_fid.fid.context = context; _cntr->cntr_fid.fid.ops = &sock_cntr_fi_ops; _cntr->cntr_fid.ops = &sock_cntr_ops; atomic_inc(&dom->ref); _cntr->domain = dom; *cntr = &_cntr->cntr_fid; return 0; err: free(_cntr); return -ret; }
DIRECT_FN int gnix_domain_open(struct fid_fabric *fabric, struct fi_info *info, struct fid_domain **dom, void *context) { struct gnix_fid_domain *domain = NULL; int ret = FI_SUCCESS; uint8_t ptag; uint32_t cookie; struct gnix_fid_fabric *fabric_priv; GNIX_TRACE(FI_LOG_DOMAIN, "\n"); fabric_priv = container_of(fabric, struct gnix_fid_fabric, fab_fid); /* * check cookie/ptag credentials - for FI_EP_MSG we may be creating a * domain * using a cookie supplied being used by the server. Otherwise, we use * use the cookie/ptag supplied by the job launch system. */ if (info->dest_addr) { ret = gnixu_get_rdma_credentials(info->dest_addr, &ptag, &cookie); if (ret) { GNIX_WARN(FI_LOG_DOMAIN, "gnixu_get_rdma_credentials returned ptag %u cookie 0x%x\n", ptag, cookie); goto err; } } else { ret = gnixu_get_rdma_credentials(NULL, &ptag, &cookie); } GNIX_INFO(FI_LOG_DOMAIN, "gnix rdma credentials returned ptag %u cookie 0x%x\n", ptag, cookie); domain = calloc(1, sizeof *domain); if (domain == NULL) { ret = -FI_ENOMEM; goto err; } domain->mr_cache_attr = _gnix_default_mr_cache_attr; domain->mr_cache_attr.reg_context = (void *) domain; domain->mr_cache_attr.dereg_context = NULL; domain->mr_cache_attr.destruct_context = NULL; ret = _gnix_notifier_open(&domain->mr_cache_attr.notifier); if (ret != FI_SUCCESS) goto err; domain->mr_cache_ro = NULL; domain->mr_cache_rw = NULL; fastlock_init(&domain->mr_cache_lock); domain->udreg_reg_limit = 4096; dlist_init(&domain->nic_list); dlist_init(&domain->list); dlist_insert_after(&domain->list, &fabric_priv->domain_list); domain->fabric = fabric_priv; _gnix_ref_get(domain->fabric); domain->ptag = ptag; domain->cookie = cookie; domain->cdm_id_seed = getpid(); /* TODO: direct syscall better */ /* user tunables */ domain->params.msg_rendezvous_thresh = default_msg_rendezvous_thresh; domain->params.rma_rdma_thresh = default_rma_rdma_thresh; domain->params.ct_init_size = default_ct_init_size; domain->params.ct_max_size = default_ct_max_size; domain->params.ct_step = default_ct_step; domain->params.vc_id_table_capacity = default_vc_id_table_capacity; domain->params.mbox_page_size = default_mbox_page_size; domain->params.mbox_num_per_slab = default_mbox_num_per_slab; domain->params.mbox_maxcredit = default_mbox_maxcredit; domain->params.mbox_msg_maxsize = default_mbox_msg_maxsize; domain->params.max_retransmits = default_max_retransmits; domain->params.err_inject_count = default_err_inject_count; #if HAVE_XPMEM domain->params.xpmem_enabled = true; #else domain->params.xpmem_enabled = false; #endif domain->gni_tx_cq_size = default_tx_cq_size; domain->gni_rx_cq_size = default_rx_cq_size; domain->gni_cq_modes = gnix_def_gni_cq_modes; _gnix_ref_init(&domain->ref_cnt, 1, __domain_destruct); domain->domain_fid.fid.fclass = FI_CLASS_DOMAIN; domain->domain_fid.fid.context = context; domain->domain_fid.fid.ops = &gnix_domain_fi_ops; domain->domain_fid.ops = &gnix_domain_ops; domain->domain_fid.mr = &gnix_domain_mr_ops; domain->control_progress = info->domain_attr->control_progress; domain->data_progress = info->domain_attr->data_progress; domain->thread_model = info->domain_attr->threading; domain->mr_is_init = 0; domain->mr_iov_limit = info->domain_attr->mr_iov_limit; fastlock_init(&domain->cm_nic_lock); _gnix_open_cache(domain, GNIX_DEFAULT_CACHE_TYPE); *dom = &domain->domain_fid; return FI_SUCCESS; err: if (domain != NULL) { free(domain); } return ret; }