/* A comparision function between two handles makes it possible to use qsort to
 * sort a list of handles */
static int _starpu_compar_handles(const struct _starpu_data_descr *descrA,
				  const struct _starpu_data_descr *descrB)
{
	struct _starpu_data_state *dataA = descrA->handle;
	struct _starpu_data_state *dataB = descrB->handle;

	/* Perhaps we have the same piece of data */
	if (dataA == dataB)
	{
		/* Process write requests first, this is needed for proper
		 * locking, see _submit_job_enforce_data_deps,
		 * _starpu_fetch_task_input, and _starpu_push_task_output  */
		if (descrA->mode & STARPU_W)
		{
			if (descrB->mode & STARPU_W)
				/* Both A and B write, take the reader first */
				if (descrA->mode & STARPU_R)
					return -1;
				else
					return 1;
			else
				/* Only A writes, take it first */
				return -1;
		}
		else
			/* A doesn't write, take B before */
			return 1;
	}

	/* Put arbitered accesses after non-arbitered */
	if (dataA->arbiter && !(dataB->arbiter))
		return 1;
	if (dataB->arbiter && !(dataA->arbiter))
		return -1;
	if (dataA->arbiter != dataB->arbiter)
		/* Both are arbitered, sort by arbiter pointer order */
		return ((dataA->arbiter < dataB->arbiter)?-1:1);
	/* If both are arbitered by the same arbiter (or they are both not
	 * arbitered), we'll sort them by handle */

	/* In case we have data/subdata from different trees */
	if (dataA->root_handle != dataB->root_handle)
		return ((dataA->root_handle < dataB->root_handle)?-1:1);

	/* Things get more complicated: we need to find the location of dataA
	 * and dataB within the tree. */
	unsigned dataA_path[dataA->depth - 1];
	unsigned dataB_path[dataB->depth - 1];

	find_data_path(dataA, dataA_path);
	find_data_path(dataB, dataB_path);

	return _compar_data_paths(dataA_path, dataA->depth, dataB_path, dataB->depth);
}
Esempio n. 2
0
/* A comparision function between two handles makes it possible to use qsort to
 * sort a list of handles */
static int _starpu_compar_handles(struct starpu_data_state_t *dataA,
				struct starpu_data_state_t *dataB)
{
	/* Perhaps we have the same piece of data */
	if (dataA == dataB)
		return 0;

	/* In case we have data/subdata from different trees */
	if (dataA->root_handle != dataB->root_handle)
		return ((dataA->root_handle < dataB->root_handle)?-1:1);

	/* Things get more complicated: we need to find the location of dataA
	 * and dataB within the tree. */
	unsigned dataA_path[dataA->depth - 1];
	unsigned dataB_path[dataB->depth - 1];

	find_data_path(dataA, dataA_path);
	find_data_path(dataB, dataB_path);

	return _compar_data_paths(dataA_path, dataA->depth, dataB_path, dataB->depth);
}