Пример #1
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;
}
Пример #2
0
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;
}