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; }