blob: 7aaa9f4588829b501f0a7e593af3a1e0bba4ebf8 [file] [log] [blame]
Changyeon Job927b882019-11-21 10:16:33 -08001/*
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_fence.h"
18
19#include <errno.h>
20#include <cinttypes>
21#include <cstring>
22#include <memory>
23#include <string>
24
Changyeon Joffdf3db2020-03-06 15:23:02 -080025#include <android-base/logging.h>
Changyeon Job927b882019-11-21 10:16:33 -080026#ifdef __clang__
27#pragma clang diagnostic push
28#pragma clang diagnostic ignored "-Wzero-length-array"
29#endif // __clang__
30#include <sync/sync.h>
31#ifdef __clang__
32#pragma clang diagnostic pop
33#endif // __clang__
34#include <utils/String8.h>
35
Changyeon Joffdf3db2020-03-06 15:23:02 -080036
Changyeon Job927b882019-11-21 10:16:33 -080037constexpr int kWarningTimeout = 2000;
38
39namespace android {
40namespace automotive {
41namespace evs {
42namespace V1_1 {
43namespace implementation {
44
45namespace {
46
47const char* GetStatusString(int status) {
48 if (status == 0) {
49 return "active";
50 } else if (status == 1) {
51 return "signaled";
52 } else {
53 return "error";
54 }
55}
56
57} // namespace
58
59UniqueFence::UniqueFence() {}
60
61UniqueFence::UniqueFence(int fd) : fd_(fd) {}
62
63UniqueFence::UniqueFence(UniqueFence&& other) = default;
64UniqueFence& UniqueFence::operator=(UniqueFence&& other) = default;
65
66void UniqueFence::Reset() {
67 fd_.Reset();
68}
69
70UniqueFence UniqueFence::Dup() const {
71 return UniqueFence(fd_.GetUnowned());
72}
73
74int UniqueFence::Get() const {
75 return fd_.Get();
76}
77
78int UniqueFence::GetUnowned() const {
79 return fd_.GetUnowned();
80}
81
82UniqueFence::operator bool() const {
83 return static_cast<bool>(fd_);
84}
85
86void UniqueFence::GetDebugStateDump(String8& result) const {
87 constexpr int INDENT = 8;
88 struct sync_file_info* finfo = sync_file_info(fd_.Get());
89 if (finfo == nullptr) {
90 result.append("no debug info available");
91 return;
92 }
93 result.appendFormat("name: %s status: %d (%s)", finfo->name, finfo->status,
94 GetStatusString(finfo->status));
95
96 struct sync_fence_info* pinfo = sync_get_fence_info(finfo);
97 for (uint32_t i = 0; i < finfo->num_fences; i++) {
98 result.appendFormat("\n%*spt %u driver: %s obj: %s: status: %d(%s) timestamp: %llu", INDENT,
99 "", i, pinfo[i].driver_name, pinfo[i].obj_name, pinfo[i].status,
100 GetStatusString(pinfo[i].status), pinfo[i].timestamp_ns);
101 }
102 sync_file_info_free(finfo);
103}
104
105int UniqueFence::Wait(int wait_time_ms) {
106 if (wait_time_ms == -1) {
107 int err = sync_wait(fd_.Get(), kWarningTimeout);
108 if (err >= 0 || errno != ETIME) return err;
109
110 String8 dump;
111 GetDebugStateDump(dump);
Changyeon Joffdf3db2020-03-06 15:23:02 -0800112 LOG(WARNING) << "Waited on fence " << fd_.Get()
113 << " for " << kWarningTimeout << " ms. " << dump.string();
Changyeon Job927b882019-11-21 10:16:33 -0800114 }
115 return sync_wait(fd_.Get(), wait_time_ms);
116}
117
118UniqueFence UniqueFence::Merge(const char* name, const UniqueFence& fence1,
119 const UniqueFence& fence2) {
120 UniqueFence merged_fence;
121 if (fence1.fd_ || fence2.fd_) {
122 if (fence1.fd_ && fence2.fd_) {
123 merged_fence.fd_.Reset(sync_merge(name, fence1.fd_.Get(), fence2.fd_.Get()));
124 } else if (fence1.fd_) {
125 // We merge the fence with itself so that we always generate a fence with
126 // a new name.
127 merged_fence.fd_.Reset(sync_merge(name, fence1.fd_.Get(), fence1.fd_.Get()));
128 } else if (fence2.fd_) {
129 // We merge the fence with itself so that we always generate a fence with
130 // a new name.
131 merged_fence.fd_.Reset(sync_merge(name, fence2.fd_.Get(), fence2.fd_.Get()));
132 }
Changyeon Joffdf3db2020-03-06 15:23:02 -0800133
134 if (!merged_fence.fd_) {
135 PLOG(ERROR) << "Failed to merge fences";
136 }
Changyeon Job927b882019-11-21 10:16:33 -0800137 }
138 return merged_fence;
139}
140
141} // namespace implementation
142} // namespace V1_1
143} // namespace evs
144} // namespace automotive
145} // namespace android