• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *     * Redistributions of source code must retain the above copyright
8 *       notice, this list of conditions and the following disclaimer.
9 *     * Redistributions in binary form must reproduce the above
10 *       copyright notice, this list of conditions and the following
11 *       disclaimer in the documentation and/or other materials provided
12 *       with the distribution.
13 *     * Neither the name of The Linux Foundation nor the names of its
14 *       contributors may be used to endorse or promote products derived
15 *       from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <utils/fence.h>
31 #include <debug_handler.h>
32 #include <assert.h>
33 #include <string>
34 #include <vector>
35 #include <algorithm>
36 
37 #define __CLASS__ "Fence"
38 
39 namespace sdm {
40 
41 #define ASSERT_IF_NO_BUFFER_SYNC(x) if (!x) { assert(false); }
42 
43 BufferSyncHandler* Fence::g_buffer_sync_handler_ = nullptr;
44 std::vector<std::weak_ptr<Fence>> Fence::wps_;
45 
Fence(int fd,const string & name)46 Fence::Fence(int fd, const string &name) : fd_(fd), name_(name) {
47 }
48 
~Fence()49 Fence::~Fence() {
50   close(fd_);
51 
52   // erase all expired weak references.
53   wps_.erase(std::remove_if(wps_.begin(), wps_.end(), [](const std::weak_ptr<Fence> &wp) {
54     return wp.expired();
55   }), wps_.end());
56 }
57 
Set(BufferSyncHandler * buffer_sync_handler)58 void Fence::Set(BufferSyncHandler *buffer_sync_handler) {
59   g_buffer_sync_handler_ = buffer_sync_handler;
60 }
61 
Create(int fd,const string & name)62 shared_ptr<Fence> Fence::Create(int fd, const string &name) {
63   // Do not create Fence object for invalid fd, so that nullptr can be used for invalid fences.
64   if (fd < 0) {
65     return nullptr;
66   }
67 
68   shared_ptr<Fence> fence(new Fence(fd, name));
69   if (!fence) {
70     close(fd);
71   }
72 
73   wps_.push_back(fence);
74 
75   return fence;
76 }
77 
Dup(const shared_ptr<Fence> & fence)78 int Fence::Dup(const shared_ptr<Fence> &fence) {
79   return (fence ? dup(fence->fd_) : -1);
80 }
81 
Get(const shared_ptr<Fence> & fence)82 int Fence::Get(const shared_ptr<Fence> &fence) {
83   return (fence ? fence->fd_ : -1);
84 }
85 
Merge(const shared_ptr<Fence> & fence1,const shared_ptr<Fence> & fence2)86 shared_ptr<Fence> Fence::Merge(const shared_ptr<Fence> &fence1, const shared_ptr<Fence> &fence2) {
87   ASSERT_IF_NO_BUFFER_SYNC(g_buffer_sync_handler_);
88 
89   // Sync merge will return a new unique fd if source fds are same.
90   int fd1 = fence1 ? fence1->fd_ : -1;
91   int fd2 = fence2 ? fence2->fd_ : -1;
92   int merged = -1;
93   std::string name = "merged[" + to_string(fd1) + ", " + to_string(fd2) + "]";
94 
95   g_buffer_sync_handler_->SyncMerge(fd1, fd2, &merged);
96 
97   return Create(merged, name);
98 }
99 
Wait(const shared_ptr<Fence> & fence)100 DisplayError Fence::Wait(const shared_ptr<Fence> &fence) {
101   ASSERT_IF_NO_BUFFER_SYNC(g_buffer_sync_handler_);
102 
103   return g_buffer_sync_handler_->SyncWait(Fence::Get(fence), 1000);
104 }
105 
Wait(const shared_ptr<Fence> & fence,int timeout)106 DisplayError Fence::Wait(const shared_ptr<Fence> &fence, int timeout) {
107   ASSERT_IF_NO_BUFFER_SYNC(g_buffer_sync_handler_);
108 
109   return g_buffer_sync_handler_->SyncWait(Fence::Get(fence), timeout);
110 }
111 
GetStatus(const shared_ptr<Fence> & fence)112 Fence::Status Fence::GetStatus(const shared_ptr<Fence> &fence) {
113   ASSERT_IF_NO_BUFFER_SYNC(g_buffer_sync_handler_);
114 
115   if (!fence) {
116     return Fence::Status::kSignaled;
117   }
118 
119   // Treat only timeout error as pending, assume other errors as signaled.
120   return (g_buffer_sync_handler_->SyncWait(Fence::Get(fence), 0) == kErrorTimeOut ?
121                                     Fence::Status::kPending : Fence::Status::kSignaled);
122 }
123 
GetStr(const shared_ptr<Fence> & fence)124 string Fence::GetStr(const shared_ptr<Fence> &fence) {
125   return std::to_string(Fence::Get(fence));
126 }
127 
Dump(std::ostringstream * os)128 void Fence::Dump(std::ostringstream *os) {
129   ASSERT_IF_NO_BUFFER_SYNC(g_buffer_sync_handler_);
130 
131   *os << "\n------------Active Fences Info---------";
132   for (auto &wp : wps_) {
133     *os << "\n";
134     shared_ptr<Fence> fence = wp.lock();
135     if (!fence) {
136       continue;
137     }
138     *os << "FD: " << fence->fd_;
139     *os << ", name: " << fence->name_;
140     *os << ", use_count: " << fence.use_count() - 1;   // Do not count wp lock reference
141     *os << ", ";
142     g_buffer_sync_handler_->GetSyncInfo(fence->fd_, os);
143   }
144   *os << "\n---------------------------------------\n";
145 }
146 
~ScopedRef()147 Fence::ScopedRef::~ScopedRef() {
148   for (int dup_fd : dup_fds_) {
149     close(dup_fd);
150   }
151 }
152 
Get(const shared_ptr<Fence> & fence)153 int Fence::ScopedRef::Get(const shared_ptr<Fence> &fence) {
154   int dup_fd = Fence::Dup(fence);
155   if (dup_fd >= 0) {
156     dup_fds_.push_back(dup_fd);
157   }
158 
159   return dup_fd;
160 }
161 
162 }  // namespace sdm
163