blob: 3a63810ad4fed132c9e7fe53109e34180ec83f98 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "Resource.hpp"
16
17#include "Memory.hpp"
Cody Schuffelen124c81a2019-03-15 15:21:34 -070018#include "Debug.hpp"
John Bauman89401822014-05-06 15:04:28 -040019
20namespace sw
21{
Nicolas Capens53fae3e2014-12-03 11:09:40 -050022 Resource::Resource(size_t bytes) : size(bytes)
John Bauman89401822014-05-06 15:04:28 -040023 {
John Bauman89401822014-05-06 15:04:28 -040024 blocked = 0;
25
26 accessor = PUBLIC;
27 count = 0;
28 orphaned = false;
29
Nicolas Capens027288c2017-07-07 05:00:00 -040030 buffer = allocate(bytes);
John Bauman89401822014-05-06 15:04:28 -040031 }
32
33 Resource::~Resource()
34 {
Nicolas Capens0bac2852016-05-07 06:09:58 -040035 deallocate(buffer);
John Bauman89401822014-05-06 15:04:28 -040036 }
37
38 void *Resource::lock(Accessor claimer)
39 {
40 criticalSection.lock();
41
Lingfeng Yang2693e752017-12-22 09:28:09 -080042 while(count > 0 && accessor != claimer)
John Bauman89401822014-05-06 15:04:28 -040043 {
44 blocked++;
45 criticalSection.unlock();
46
John Bauman66b8ab22014-05-06 15:57:45 -040047 unblock.wait();
John Bauman89401822014-05-06 15:04:28 -040048
49 criticalSection.lock();
50 blocked--;
51 }
52
53 accessor = claimer;
54 count++;
55
56 criticalSection.unlock();
57
58 return buffer;
59 }
60
61 void *Resource::lock(Accessor relinquisher, Accessor claimer)
62 {
63 criticalSection.lock();
64
65 // Release
66 while(count > 0 && accessor == relinquisher)
67 {
68 count--;
John Bauman66b8ab22014-05-06 15:57:45 -040069
John Bauman89401822014-05-06 15:04:28 -040070 if(count == 0)
71 {
72 if(blocked)
73 {
John Bauman66b8ab22014-05-06 15:57:45 -040074 unblock.signal();
John Bauman89401822014-05-06 15:04:28 -040075 }
76 else if(orphaned)
77 {
78 criticalSection.unlock();
79
80 delete this;
81
82 return 0;
83 }
84 }
85 }
86
87 // Acquire
Lingfeng Yang2693e752017-12-22 09:28:09 -080088 while(count > 0 && accessor != claimer)
John Bauman89401822014-05-06 15:04:28 -040089 {
90 blocked++;
91 criticalSection.unlock();
92
John Bauman66b8ab22014-05-06 15:57:45 -040093 unblock.wait();
John Bauman89401822014-05-06 15:04:28 -040094
95 criticalSection.lock();
96 blocked--;
97 }
98
99 accessor = claimer;
100 count++;
101
102 criticalSection.unlock();
103
104 return buffer;
105 }
106
107 void Resource::unlock()
108 {
109 criticalSection.lock();
Cody Schuffelen124c81a2019-03-15 15:21:34 -0700110 ASSERT(count > 0);
John Bauman89401822014-05-06 15:04:28 -0400111
112 count--;
John Bauman66b8ab22014-05-06 15:57:45 -0400113
John Bauman89401822014-05-06 15:04:28 -0400114 if(count == 0)
115 {
116 if(blocked)
117 {
John Bauman66b8ab22014-05-06 15:57:45 -0400118 unblock.signal();
John Bauman89401822014-05-06 15:04:28 -0400119 }
120 else if(orphaned)
121 {
122 criticalSection.unlock();
123
124 delete this;
125
126 return;
127 }
128 }
129
130 criticalSection.unlock();
131 }
132
133 void Resource::unlock(Accessor relinquisher)
134 {
135 criticalSection.lock();
Cody Schuffelen124c81a2019-03-15 15:21:34 -0700136 ASSERT(count > 0);
John Bauman89401822014-05-06 15:04:28 -0400137
138 while(count > 0 && accessor == relinquisher)
139 {
140 count--;
John Bauman66b8ab22014-05-06 15:57:45 -0400141
John Bauman89401822014-05-06 15:04:28 -0400142 if(count == 0)
143 {
144 if(blocked)
145 {
John Bauman66b8ab22014-05-06 15:57:45 -0400146 unblock.signal();
John Bauman89401822014-05-06 15:04:28 -0400147 }
148 else if(orphaned)
149 {
150 criticalSection.unlock();
151
152 delete this;
153
154 return;
155 }
156 }
157 }
158
159 criticalSection.unlock();
160 }
161
162 void Resource::destruct()
163 {
164 criticalSection.lock();
165
166 if(count == 0 && !blocked)
167 {
168 criticalSection.unlock();
169
170 delete this;
171
172 return;
173 }
174
175 orphaned = true;
176
177 criticalSection.unlock();
178 }
179
Nicolas Capens53fae3e2014-12-03 11:09:40 -0500180 const void *Resource::data() const
John Bauman89401822014-05-06 15:04:28 -0400181 {
182 return buffer;
183 }
John Bauman66b8ab22014-05-06 15:57:45 -0400184}