Пример #1
0
int test_fence_multi_timeline_wait(void)
{
	int timelineA, timelineB, timelineC;
	int fenceA, fenceB, fenceC, merged;
	int valid, active, signaled, ret;

	timelineA = sw_sync_timeline_create();
	timelineB = sw_sync_timeline_create();
	timelineC = sw_sync_timeline_create();

	fenceA = sw_sync_fence_create(timelineA, "fenceA", 5);
	fenceB = sw_sync_fence_create(timelineB, "fenceB", 5);
	fenceC = sw_sync_fence_create(timelineC, "fenceC", 5);

	merged = sync_merge("mergeFence", fenceB, fenceA);
	merged = sync_merge("mergeFence", fenceC, merged);

	valid = sw_sync_fence_is_valid(merged);
	ASSERT(valid, "Failure merging fence from various timelines\n");

	/* Confirm fence isn't signaled */
	active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
	ASSERT(active == 3, "Fence signaled too early!\n");

	ret = sync_wait(merged, 0);
	ASSERT(ret == 0,
	       "Failure waiting on fence until timeout\n");

	ret = sw_sync_timeline_inc(timelineA, 5);
	active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
	signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
	ASSERT(active == 2 && signaled == 1,
	       "Fence did not signal properly!\n");

	ret = sw_sync_timeline_inc(timelineB, 5);
	active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
	signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
	ASSERT(active == 1 && signaled == 2,
	       "Fence did not signal properly!\n");

	ret = sw_sync_timeline_inc(timelineC, 5);
	active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
	signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
	ASSERT(active == 0 && signaled == 3,
	       "Fence did not signal properly!\n");

	/* confirm you can successfully wait */
	ret = sync_wait(merged, 100);
	ASSERT(ret > 0, "Failure waiting on signaled fence\n");

	sw_sync_fence_destroy(merged);
	sw_sync_fence_destroy(fenceC);
	sw_sync_fence_destroy(fenceB);
	sw_sync_fence_destroy(fenceA);
	sw_sync_timeline_destroy(timelineC);
	sw_sync_timeline_destroy(timelineB);
	sw_sync_timeline_destroy(timelineA);

	return 0;
}
Пример #2
0
int GLWorker::DoComposition(Compositor &compositor, Work *work) {
  int ret =
      compositor.Composite(work->layers, work->num_layers, work->framebuffer);

  int timeline_fd = work->timeline_fd;
  work->timeline_fd = -1;

  if (ret) {
    worker_ret_ = ret;
    glFinish();
    sw_sync_timeline_inc(timeline_fd, work->num_layers);
    close(timeline_fd);
    return pthread_cond_signal(&work_done_cond_);
  }

  unsigned timeline_count = work->num_layers + 1;
  worker_ret_ = sw_sync_fence_create(timeline_fd, "GLComposition done fence",
                                     timeline_count);
  ret = pthread_cond_signal(&work_done_cond_);

  glFinish();

  sw_sync_timeline_inc(timeline_fd, timeline_count);
  close(timeline_fd);

  return ret;
}
Пример #3
0
void sde_fence_signal(struct sde_fence *fence, bool is_error)
{
	if (!fence || !fence->timeline) {
		SDE_ERROR("invalid fence, %pK\n", fence);
		return;
	}

	mutex_lock(&fence->fence_lock);
	if ((fence->done_count - fence->commit_count) < 0)
		++fence->done_count;
	else
		SDE_ERROR("detected extra signal attempt!\n");

	MSM_EVTMSG(fence->dev,
			SDE_FENCE_TIMELINE_NAME(fence),
			fence->done_count,
			is_error);
	/*
	 * Always advance 'done' counter,
	 * but only advance timeline if !error
	 */
	if (!is_error) {
		int32_t val;

		val = fence->done_count;
		val -= ((struct sw_sync_timeline *)
				fence->timeline)->value;
		if (val < 0)
			SDE_ERROR("invalid value\n");
		else
			sw_sync_timeline_inc(fence->timeline, (int)val);
	}
	mutex_unlock(&fence->fence_lock);
}
Пример #4
0
void k3fb_buf_sync_suspend(struct k3_fb_data_type *k3fd)
{
	unsigned long flags;

	spin_lock_irqsave(&k3fd->buf_sync_ctrl.refresh_lock,flags);
	sw_sync_timeline_inc(k3fd->buf_sync_ctrl.timeline, k3fd->buf_sync_ctrl.refresh + 1);
	k3fd->buf_sync_ctrl.refresh = 0;
	k3fd->buf_sync_ctrl.timeline_max++;
	spin_unlock_irqrestore(&k3fd->buf_sync_ctrl.refresh_lock,flags);
}
int VirtualCompositorWorker::FinishComposition(int point) {
  int timeline_increase = point - timeline_current_;
  if (timeline_increase <= 0)
    return 0;
  int ret = sw_sync_timeline_inc(timeline_fd_, timeline_increase);
  if (ret)
    ALOGE("Failed to increment sync timeline %d", ret);
  else
    timeline_current_ = point;
  return ret;
}
Пример #6
0
static long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg)
{
	u32 value;

	if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
		return -EFAULT;

	sw_sync_timeline_inc(obj, value);

	return 0;
}
Пример #7
0
void k3fb_buf_sync_signal(struct k3_fb_data_type *k3fd)
{
	//K3_FB_DEBUG("fb%d, +.\n", k3fd->index);

	spin_lock(&k3fd->buf_sync_ctrl.refresh_lock);
	if (k3fd->buf_sync_ctrl.refresh) {
		sw_sync_timeline_inc(k3fd->buf_sync_ctrl.timeline, k3fd->buf_sync_ctrl.refresh);
		k3fd->buf_sync_ctrl.refresh = 0;
	}
	spin_unlock(&k3fd->buf_sync_ctrl.refresh_lock);

	//K3_FB_DEBUG("fb%d, -.\n", k3fd->index);
}
Пример #8
0
static int mpcs_consumer_thread(void)
{
	int fence, merged, tmp, valid, it, i;
	int *producer_timelines = test_data_mpsc.producer_timelines;
	int consumer_timeline = test_data_mpsc.consumer_timeline;
	int iterations = test_data_mpsc.iterations;
	int n = test_data_mpsc.threads;

	for (it = 1; it <= iterations; it++) {
		fence = sw_sync_fence_create(producer_timelines[0], "name", it);
		for (i = 1; i < n; i++) {
			tmp = sw_sync_fence_create(producer_timelines[i],
						   "name", it);
			merged = sync_merge("name", tmp, fence);
			sw_sync_fence_destroy(tmp);
			sw_sync_fence_destroy(fence);
			fence = merged;
		}

		valid = sw_sync_fence_is_valid(fence);
		ASSERT(valid, "Failure merging fences\n");

		/*
		 * Make sure we see an increment from every producer thread.
		 * Vary the means by which we wait.
		 */
		if (iterations % 8 != 0) {
			ASSERT(sync_wait(fence, -1) > 0,
			       "Producers did not increment as expected\n");
		} else {
			ASSERT(busy_wait_on_fence(fence) == 0,
			       "Producers did not increment as expected\n");
		}

		ASSERT(test_data_mpsc.counter == n * it,
		       "Counter value mismatch!\n");

		/* Release the producer threads */
		ASSERT(sw_sync_timeline_inc(consumer_timeline, 1) == 0,
		       "Failure releasing producer threads\n");

		sw_sync_fence_destroy(fence);
	}

	return 0;
}
Пример #9
0
static int mpsc_producer_thread(void *d)
{
	int id = (long)d;
	int fence, valid, i;
	int *producer_timelines = test_data_mpsc.producer_timelines;
	int consumer_timeline = test_data_mpsc.consumer_timeline;
	int iterations = test_data_mpsc.iterations;

	for (i = 0; i < iterations; i++) {
		fence = sw_sync_fence_create(consumer_timeline, "fence", i);
		valid = sw_sync_fence_is_valid(fence);
		ASSERT(valid, "Failure creating fence\n");

		/*
		 * Wait for the consumer to finish. Use alternate
		 * means of waiting on the fence
		 */

		if ((iterations + id) % 8 != 0) {
			ASSERT(sync_wait(fence, -1) > 0,
			       "Failure waiting on fence\n");
		} else {
			ASSERT(busy_wait_on_fence(fence) == 0,
			       "Failure waiting on fence\n");
		}

		/*
		 * Every producer increments the counter, the consumer
		 * checks and erases it
		 */
		pthread_mutex_lock(&test_data_mpsc.lock);
		test_data_mpsc.counter++;
		pthread_mutex_unlock(&test_data_mpsc.lock);

		ASSERT(sw_sync_timeline_inc(producer_timelines[id], 1) == 0,
		       "Error advancing producer timeline\n");

		sw_sync_fence_destroy(fence);
	}

	return 0;
}
Пример #10
0
void timeline_inc(struct sw_sync_timeline *obj, u32 value)
{
    sw_sync_timeline_inc(obj, value);
}