1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 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 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 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. 14 15 #ifndef sw_Resource_hpp 16 #define sw_Resource_hpp 17 18 #include "MutexLock.hpp" 19 20 namespace sw 21 { 22 enum Accessor 23 { 24 PUBLIC, // Application/API access 25 PRIVATE, // Renderer access, shared by multiple threads if read-only 26 MANAGED, // Renderer access, shared read/write access if partitioned 27 EXCLUSIVE 28 }; 29 30 // Resource is a form of shared mutex that guards an internally allocated 31 // buffer. Resource has an exclusive lock mode (sw::Accessor) and lock 32 // count, defaulting to sw::Accessor::PUBLIC and 0, respectively. 33 // Resource doesn't treat any of the sw::Accessor enumerator lock modes 34 // differently, all semantic meaning comes from the usage of Resource. 35 // You can have multiple locks in mode sw::Accessor::EXCLUSIVE. 36 class Resource 37 { 38 public: 39 Resource(size_t bytes); 40 41 // destruct() is an asynchronous destructor, that will atomically: 42 // When the resource is unlocked: 43 // * Delete itself. 44 // When the resource is locked: 45 // * Flag itself for deletion when next fully unlocked. 46 void destruct(); 47 48 // lock() will atomically: 49 // When the resource is unlocked OR the lock mode equals claimer: 50 // * Increment the lock count. 51 // * Return a pointer to the buffer. 52 // When the resource is locked AND the lock mode does not equal claimer: 53 // * Block until all existing locks are released (lock count equals 0). 54 // * Switch lock mode to claimer. 55 // * Increment the lock count. 56 // * Return a pointer to the buffer. 57 void *lock(Accessor claimer); 58 59 // lock() will atomically: 60 // When the resource is unlocked OR the lock mode equals claimer: 61 // * Increment the lock count. 62 // * Return a pointer to the buffer. 63 // When the resource is locked AND the lock mode equals relinquisher: 64 // * Release *all* existing locks (regardless of prior count). 65 // * Delete itself and return nullptr if Resource::destruct() had been called while locked. 66 // * Switch lock mode to claimer. 67 // * Increment the lock count to 1. 68 // * Return a pointer to the buffer. 69 // When the resource is locked AND the lock mode does not equal relinquisher: 70 // * Block until all existing locks are released (lock count equals 0) 71 // * Switch lock mode to claimer 72 // * Increment the lock count to 1. 73 // * Return a pointer to the buffer. 74 void *lock(Accessor relinquisher, Accessor claimer); 75 76 // unlock() will atomically: 77 // * Assert if there are no locks. 78 // * Release a single lock. 79 // * Delete itself if Resource::destruct() had been called while locked. 80 void unlock(); 81 82 // unlock() will atomically: 83 // When the resource is locked AND the lock mode equals relinquisher: 84 // * Release *all* existing locks (regardless of prior count). 85 // * Delete itself if Resource::destruct() had been called while locked. 86 // When the resource is not locked OR the lock mode does not equal relinquisher: 87 // * Do nothing. 88 void unlock(Accessor relinquisher); 89 90 // data() will return the Resource's buffer pointer regardless of lock 91 // state. 92 const void *data() const; 93 94 // size is the size in bytes of the Resource's buffer. 95 const size_t size; 96 97 private: 98 ~Resource(); // Always call destruct() instead 99 100 MutexLock criticalSection; 101 Event unblock; 102 volatile int blocked; 103 104 volatile Accessor accessor; 105 volatile int count; 106 bool orphaned; 107 108 void *buffer; 109 }; 110 } 111 112 #endif // sw_Resource_hpp 113