• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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