Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 1 | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 2 | // |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 3 | // 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 Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 6 | // |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 8 | // |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 9 | // 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 Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 14 | |
15 | #include "Resource.hpp" | ||||
16 | |||||
17 | #include "Memory.hpp" | ||||
Cody Schuffelen | 124c81a | 2019-03-15 15:21:34 -0700 | [diff] [blame] | 18 | #include "Debug.hpp" |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 19 | |
20 | namespace sw | ||||
21 | { | ||||
Nicolas Capens | 53fae3e | 2014-12-03 11:09:40 -0500 | [diff] [blame] | 22 | Resource::Resource(size_t bytes) : size(bytes) |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 23 | { |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 24 | blocked = 0; |
25 | |||||
26 | accessor = PUBLIC; | ||||
27 | count = 0; | ||||
28 | orphaned = false; | ||||
29 | |||||
Nicolas Capens | 027288c | 2017-07-07 05:00:00 -0400 | [diff] [blame] | 30 | buffer = allocate(bytes); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 31 | } |
32 | |||||
33 | Resource::~Resource() | ||||
34 | { | ||||
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 35 | deallocate(buffer); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 36 | } |
37 | |||||
38 | void *Resource::lock(Accessor claimer) | ||||
39 | { | ||||
40 | criticalSection.lock(); | ||||
41 | |||||
Lingfeng Yang | 2693e75 | 2017-12-22 09:28:09 -0800 | [diff] [blame] | 42 | while(count > 0 && accessor != claimer) |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 43 | { |
44 | blocked++; | ||||
45 | criticalSection.unlock(); | ||||
46 | |||||
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 47 | unblock.wait(); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 48 | |
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 Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 69 | |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 70 | if(count == 0) |
71 | { | ||||
72 | if(blocked) | ||||
73 | { | ||||
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 74 | unblock.signal(); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 75 | } |
76 | else if(orphaned) | ||||
77 | { | ||||
78 | criticalSection.unlock(); | ||||
79 | |||||
80 | delete this; | ||||
81 | |||||
82 | return 0; | ||||
83 | } | ||||
84 | } | ||||
85 | } | ||||
86 | |||||
87 | // Acquire | ||||
Lingfeng Yang | 2693e75 | 2017-12-22 09:28:09 -0800 | [diff] [blame] | 88 | while(count > 0 && accessor != claimer) |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 89 | { |
90 | blocked++; | ||||
91 | criticalSection.unlock(); | ||||
92 | |||||
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 93 | unblock.wait(); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 94 | |
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 Schuffelen | 124c81a | 2019-03-15 15:21:34 -0700 | [diff] [blame] | 110 | ASSERT(count > 0); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 111 | |
112 | count--; | ||||
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 113 | |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 114 | if(count == 0) |
115 | { | ||||
116 | if(blocked) | ||||
117 | { | ||||
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 118 | unblock.signal(); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 119 | } |
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 Schuffelen | 124c81a | 2019-03-15 15:21:34 -0700 | [diff] [blame] | 136 | ASSERT(count > 0); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 137 | |
138 | while(count > 0 && accessor == relinquisher) | ||||
139 | { | ||||
140 | count--; | ||||
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 141 | |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 142 | if(count == 0) |
143 | { | ||||
144 | if(blocked) | ||||
145 | { | ||||
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 146 | unblock.signal(); |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 147 | } |
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 Capens | 53fae3e | 2014-12-03 11:09:40 -0500 | [diff] [blame] | 180 | const void *Resource::data() const |
John Bauman | 8940182 | 2014-05-06 15:04:28 -0400 | [diff] [blame] | 181 | { |
182 | return buffer; | ||||
183 | } | ||||
John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 184 | } |