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; }
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; }
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); }
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; }
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; }
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); }
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; }
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; }
void timeline_inc(struct sw_sync_timeline *obj, u32 value) { sw_sync_timeline_inc(obj, value); }