1cb93a386Sopenharmony_ci// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2cb93a386Sopenharmony_ci// 3cb93a386Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4cb93a386Sopenharmony_ci// you may not use this file except in compliance with the License. 5cb93a386Sopenharmony_ci// You may obtain a copy of the License at 6cb93a386Sopenharmony_ci// 7cb93a386Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8cb93a386Sopenharmony_ci// 9cb93a386Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10cb93a386Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11cb93a386Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cb93a386Sopenharmony_ci// See the License for the specific language governing permissions and 13cb93a386Sopenharmony_ci// limitations under the License. 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci#include "Resource.hpp" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ci#include "Memory.hpp" 18cb93a386Sopenharmony_ci#include "Debug.hpp" 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_cinamespace sw 21cb93a386Sopenharmony_ci{ 22cb93a386Sopenharmony_ci Resource::Resource(size_t bytes) : size(bytes) 23cb93a386Sopenharmony_ci { 24cb93a386Sopenharmony_ci blocked = 0; 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci accessor = PUBLIC; 27cb93a386Sopenharmony_ci count = 0; 28cb93a386Sopenharmony_ci orphaned = false; 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci buffer = allocate(bytes); 31cb93a386Sopenharmony_ci } 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci Resource::~Resource() 34cb93a386Sopenharmony_ci { 35cb93a386Sopenharmony_ci deallocate(buffer); 36cb93a386Sopenharmony_ci } 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci void *Resource::lock(Accessor claimer) 39cb93a386Sopenharmony_ci { 40cb93a386Sopenharmony_ci criticalSection.lock(); 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci while(count > 0 && accessor != claimer) 43cb93a386Sopenharmony_ci { 44cb93a386Sopenharmony_ci blocked++; 45cb93a386Sopenharmony_ci criticalSection.unlock(); 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci unblock.wait(); 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci criticalSection.lock(); 50cb93a386Sopenharmony_ci blocked--; 51cb93a386Sopenharmony_ci } 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci accessor = claimer; 54cb93a386Sopenharmony_ci count++; 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci criticalSection.unlock(); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci return buffer; 59cb93a386Sopenharmony_ci } 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci void *Resource::lock(Accessor relinquisher, Accessor claimer) 62cb93a386Sopenharmony_ci { 63cb93a386Sopenharmony_ci criticalSection.lock(); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci // Release 66cb93a386Sopenharmony_ci while(count > 0 && accessor == relinquisher) 67cb93a386Sopenharmony_ci { 68cb93a386Sopenharmony_ci count--; 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci if(count == 0) 71cb93a386Sopenharmony_ci { 72cb93a386Sopenharmony_ci if(blocked) 73cb93a386Sopenharmony_ci { 74cb93a386Sopenharmony_ci unblock.signal(); 75cb93a386Sopenharmony_ci } 76cb93a386Sopenharmony_ci else if(orphaned) 77cb93a386Sopenharmony_ci { 78cb93a386Sopenharmony_ci criticalSection.unlock(); 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci delete this; 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci return 0; 83cb93a386Sopenharmony_ci } 84cb93a386Sopenharmony_ci } 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci // Acquire 88cb93a386Sopenharmony_ci while(count > 0 && accessor != claimer) 89cb93a386Sopenharmony_ci { 90cb93a386Sopenharmony_ci blocked++; 91cb93a386Sopenharmony_ci criticalSection.unlock(); 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci unblock.wait(); 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci criticalSection.lock(); 96cb93a386Sopenharmony_ci blocked--; 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci accessor = claimer; 100cb93a386Sopenharmony_ci count++; 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci criticalSection.unlock(); 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci return buffer; 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci void Resource::unlock() 108cb93a386Sopenharmony_ci { 109cb93a386Sopenharmony_ci criticalSection.lock(); 110cb93a386Sopenharmony_ci ASSERT(count > 0); 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci count--; 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci if(count == 0) 115cb93a386Sopenharmony_ci { 116cb93a386Sopenharmony_ci if(blocked) 117cb93a386Sopenharmony_ci { 118cb93a386Sopenharmony_ci unblock.signal(); 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci else if(orphaned) 121cb93a386Sopenharmony_ci { 122cb93a386Sopenharmony_ci criticalSection.unlock(); 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci delete this; 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ci return; 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci } 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci criticalSection.unlock(); 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci void Resource::unlock(Accessor relinquisher) 134cb93a386Sopenharmony_ci { 135cb93a386Sopenharmony_ci criticalSection.lock(); 136cb93a386Sopenharmony_ci ASSERT(count > 0); 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci while(count > 0 && accessor == relinquisher) 139cb93a386Sopenharmony_ci { 140cb93a386Sopenharmony_ci count--; 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci if(count == 0) 143cb93a386Sopenharmony_ci { 144cb93a386Sopenharmony_ci if(blocked) 145cb93a386Sopenharmony_ci { 146cb93a386Sopenharmony_ci unblock.signal(); 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci else if(orphaned) 149cb93a386Sopenharmony_ci { 150cb93a386Sopenharmony_ci criticalSection.unlock(); 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci delete this; 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ci return; 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci } 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci criticalSection.unlock(); 160cb93a386Sopenharmony_ci } 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_ci void Resource::destruct() 163cb93a386Sopenharmony_ci { 164cb93a386Sopenharmony_ci criticalSection.lock(); 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_ci if(count == 0 && !blocked) 167cb93a386Sopenharmony_ci { 168cb93a386Sopenharmony_ci criticalSection.unlock(); 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci delete this; 171cb93a386Sopenharmony_ci 172cb93a386Sopenharmony_ci return; 173cb93a386Sopenharmony_ci } 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci orphaned = true; 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci criticalSection.unlock(); 178cb93a386Sopenharmony_ci } 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci const void *Resource::data() const 181cb93a386Sopenharmony_ci { 182cb93a386Sopenharmony_ci return buffer; 183cb93a386Sopenharmony_ci } 184cb93a386Sopenharmony_ci} 185