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
20namespace 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