コード例 #1
0
int _gnix_cm_nic_progress(struct gnix_cm_nic *cm_nic)
{
	int ret = FI_SUCCESS;
	int complete;
	struct gnix_work_req *p = NULL;

	/*
	 * if we're doing FI_PROGRESS_MANUAL,
	 * see what's going on inside kgni's datagram
	 * box...
	 */

	if (cm_nic->control_progress == FI_PROGRESS_MANUAL) {
		ret = _gnix_dgram_poll(cm_nic->dgram_hndl,
					  GNIX_DGRAM_NOBLOCK);
		if (ret != FI_SUCCESS)
			goto err;
	}

	/*
	 * do a quick check if queue doesn't have anything yet,
	 * don't need this to be atomic
	 */

check_again:
	if (list_empty(&cm_nic->cm_nic_wq))
		return ret;

	/*
	 * okay, stuff to do, lock work queue,
	 * dequeue head, unlock, process work element,
	 * if it doesn't compete, put back at the tail
	 * of the queue.
	 */

	fastlock_acquire(&cm_nic->wq_lock);
	p = list_top(&cm_nic->cm_nic_wq, struct gnix_work_req, list);
	if (p == NULL) {
		fastlock_release(&cm_nic->wq_lock);
		return ret;
	}

	gnix_list_del_init(&p->list);
	fastlock_release(&cm_nic->wq_lock);

	assert(p->progress_fn);

	ret = p->progress_fn(p->data, &complete);
	if (ret != FI_SUCCESS) {
		/*
		 * TODO: fix this
		 */
	}

	if (complete == 1) {
		if (p->completer_fn) {
			ret = p->completer_fn(p->completer_data);
			free(p);
			if (ret != FI_SUCCESS)
				goto err;
		}
		goto check_again;
	} else {
		fastlock_acquire(&cm_nic->wq_lock);
		list_add_tail(&cm_nic->cm_nic_wq, &p->list);
		fastlock_release(&cm_nic->wq_lock);
	}

err:
	return ret;
}
コード例 #2
0
ファイル: gnix_datagram.c プロジェクト: lionkov/libfabric
/*
 * this function is intended to be invoked as an argument to pthread_create,
 */
static void *_gnix_dgram_prog_thread_fn(void *the_arg)
{
	int ret = FI_SUCCESS, prev_state;
	struct gnix_dgram_hndl *the_hndl = (struct gnix_dgram_hndl *)the_arg;
	sigset_t  sigmask;

	GNIX_TRACE(FI_LOG_EP_CTRL, "\n");

	/*
	 * temporarily disable cancelability while we set up
	 * some stuff
	 */

	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &prev_state);

	/*
	 * help out Cray core-spec, say we're not an app thread
	 * and can be run on core-spec cpus.
	 */

	ret = _gnix_task_is_not_app();
	if (ret)
		GNIX_WARN(FI_LOG_EP_CTRL,
		"_gnix_task_is_not_app call returned %d\n", ret);

	/*
	 * block all signals, don't want this thread to catch
	 * signals that may be for app threads
	 */

	memset(&sigmask, 0, sizeof(sigset_t));
	ret = sigfillset(&sigmask);
	if (ret) {
		GNIX_WARN(FI_LOG_EP_CTRL,
		"sigfillset call returned %d\n", ret);
	} else {

		ret = pthread_sigmask(SIG_SETMASK,
					&sigmask, NULL);
		if (ret)
			GNIX_WARN(FI_LOG_EP_CTRL,
			"pthread_sigmask call returned %d\n", ret);
	}

	/*
	 * okay now we're ready to be cancelable.
	 */

	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &prev_state);

	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

retry:
	ret = _gnix_dgram_poll(the_hndl, GNIX_DGRAM_BLOCK);
	if ((ret == -FI_ETIMEDOUT) || (ret == FI_SUCCESS))
		goto retry;

	GNIX_WARN(FI_LOG_EP_CTRL,
		"_gnix_dgram_poll returned %s\n", fi_strerror(-ret));

	/*
	 * TODO: need to be able to enqueue events on to the
	 * ep associated with the cm_nic.
	 */
	return NULL;
}
コード例 #3
0
int _gnix_cm_nic_progress(void *arg)
{
	struct gnix_cm_nic *cm_nic = (struct gnix_cm_nic *)arg;
	int ret = FI_SUCCESS;
	int complete;
	struct gnix_work_req *p = NULL;

	/*
	 * if we're doing FI_PROGRESS_MANUAL,
	 * see what's going on inside kgni's datagram
	 * box...
	 */

	if (cm_nic->ctrl_progress == FI_PROGRESS_MANUAL) {
		++cm_nic->poll_cnt;
		if (((cm_nic->poll_cnt % 512) == 0)  ||
			!dlist_empty(&cm_nic->cm_nic_wq)) {
			ret = _gnix_dgram_poll(cm_nic->dgram_hndl,
						  GNIX_DGRAM_NOBLOCK);
			if (ret != FI_SUCCESS) {
				GNIX_WARN(FI_LOG_EP_CTRL,
					"_gnix_dgram_poll returned %s\n",
					  fi_strerror(-ret));
					goto err;
			}
		}
	}

	/*
	 * do a quick check if queue doesn't have anything yet,
	 * don't need this to be atomic
	 */

check_again:
	if (dlist_empty(&cm_nic->cm_nic_wq))
		return ret;

	/*
	 * okay, stuff to do, lock work queue,
	 * dequeue head, unlock, process work element,
	 * if it doesn't compete, put back at the tail
	 * of the queue.
	 */

	fastlock_acquire(&cm_nic->wq_lock);
	p = dlist_first_entry(&cm_nic->cm_nic_wq, struct gnix_work_req,
			      list);
	if (p == NULL) {
		fastlock_release(&cm_nic->wq_lock);
		return ret;
	}

	dlist_remove_init(&p->list);
	fastlock_release(&cm_nic->wq_lock);

	assert(p->progress_fn);

	ret = p->progress_fn(p->data, &complete);
	if (ret != FI_SUCCESS) {
		GNIX_WARN(FI_LOG_EP_CTRL,
			  "dgram prog fn returned %s\n",
			  fi_strerror(-ret));
	}

	if (complete == 1) {
		if (p->completer_fn) {
			ret = p->completer_fn(p->completer_data);
			free(p);
			if (ret != FI_SUCCESS) {
				GNIX_WARN(FI_LOG_EP_CTRL,
					  "dgram completer fn returned %s\n",
					  fi_strerror(-ret));
				goto err;
			}
		} else {
			free(p);
		}
		goto check_again;
	} else {
		fastlock_acquire(&cm_nic->wq_lock);
		dlist_insert_before(&p->list, &cm_nic->cm_nic_wq);
		fastlock_release(&cm_nic->wq_lock);
	}

err:
	return ret;
}