1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "unique_timeline.h"
18
19 #include <errno.h>
20 #include <limits>
21 #include <string.h>
22 #include <sw_sync.h>
23
24 #include <android-base/logging.h>
25
26 namespace android {
27 namespace automotive {
28 namespace evs {
29 namespace V1_1 {
30 namespace implementation {
31
UniqueTimeline(unsigned offset)32 UniqueTimeline::UniqueTimeline(unsigned offset)
33 : fd_(sw_sync_timeline_create()), fence_counter_(offset) {
34 if (!fd_) {
35 LOG(FATAL) << "Failed to create a timeline.";
36 }
37 }
38
~UniqueTimeline()39 UniqueTimeline::~UniqueTimeline() {
40 // Force any fences waiting on the timeline to be released by incrementing
41 // by the difference between the two counters. The sw_sync driver has
42 // changed behavior several times, and no longer releases fences when the
43 // timeline fd is closed. While at one point adding MAX_UINT worked (by
44 // adding MAX_INT with two separate calls), even that stopped working.
45 // (See b/35115489 for background)
46 BumpTimelineEventCounter(fence_counter_ - timeline_counter_);
47 }
48
Supported()49 bool UniqueTimeline::Supported() {
50 UniqueFd fd{sw_sync_timeline_create()};
51 return !!fd;
52 }
53
CreateFence(const char * name)54 UniqueFence UniqueTimeline::CreateFence(const char* name) {
55 UniqueFence fence(sw_sync_fence_create(fd_.Get(), name, fence_counter_));
56 if (!fence) {
57 PLOG(FATAL) << "Cannot create fence";
58 }
59 return fence;
60 }
61
BumpTimelineEventCounter()62 void UniqueTimeline::BumpTimelineEventCounter() {
63 BumpTimelineEventCounter(1);
64 }
65
BumpTimelineEventCounter(unsigned count)66 void UniqueTimeline::BumpTimelineEventCounter(unsigned count) {
67 timeline_counter_ += count;
68 int err = sw_sync_timeline_inc(fd_.Get(), count);
69 if (err < 0) {
70 PLOG(FATAL) << "Cannot bump timeline counter";
71 }
72 }
73
74 } // namespace implementation
75 } // namespace V1_1
76 } // namespace evs
77 } // namespace automotive
78 } // namespace android
79