| /** |
| * Copyright 2016, Quickstep Research Group, Computer Sciences Department, |
| * University of Wisconsin—Madison. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| **/ |
| |
| #ifndef QUICKSTEP_TRANSACTION_ACCESS_MODE_HPP_ |
| #define QUICKSTEP_TRANSACTION_ACCESS_MODE_HPP_ |
| |
| #include <cstdint> |
| #include <type_traits> |
| |
| namespace quickstep { |
| namespace transaction { |
| |
| /** \addtogroup Transaction |
| * @{ |
| */ |
| |
| /** |
| * @brief Represents mode type. Possible options are NL, IS, IX, S, SIX, X. |
| **/ |
| enum class AccessModeType : std::uint8_t { |
| kNoLock = 0, |
| kIsLock, |
| kIxLock, |
| kSLock, |
| kSixLock, |
| kXLock, |
| kNumAccessModeTypes, |
| }; |
| |
| /** |
| * @brief Class for representing resource lock's access mode |
| **/ |
| class AccessMode { |
| public: |
| /** |
| * @brief Only constructor for access mode. |
| * |
| * @param access_mode Mode type of the object. |
| **/ |
| explicit AccessMode(const AccessModeType access_mode) |
| : access_mode_(access_mode) {} |
| |
| /** |
| * @brief Checks whether this access mode is compatible with the other. |
| * |
| * @param other Other access mode that will be checked against to this one. |
| * @return True if they are compatible, otherwise false. |
| **/ |
| inline bool isCompatible(const AccessMode &other) const { |
| const access_mode_underlying_type this_mode = |
| static_cast<access_mode_underlying_type>(access_mode_); |
| const access_mode_underlying_type other_mode = |
| static_cast<access_mode_underlying_type>(other.access_mode_); |
| return AccessMode::kLockCompatibilityMatrix[this_mode][other_mode]; |
| } |
| |
| /** |
| * @brief Checks whether this access mode is IS mode. |
| * |
| * @return True if it is IS mode, false otherwise. |
| **/ |
| inline bool isIntentionShareLock() const { |
| return access_mode_ == AccessModeType::kIsLock; |
| } |
| |
| /** |
| * @brief Checks whether this access mode is IX mode. |
| * |
| * @return True if it is IX mode, false otherwise. |
| **/ |
| inline bool isIntentionExclusiveLock() const { |
| return access_mode_ == AccessModeType::kIxLock; |
| } |
| |
| /** |
| * @brief Checks whether this access mdoe is SIX mode. |
| * |
| * @return True if it is SIX mode, false otherwise. |
| **/ |
| inline bool isShareAndIntentionExclusiveLock() const { |
| return access_mode_ == AccessModeType::kSixLock; |
| } |
| |
| /** |
| * @brief Checks whether this access mode is S mode. |
| * |
| * @return True if it is S mode, false otherwise. |
| **/ |
| inline bool isShareLock() const { |
| return access_mode_ == AccessModeType::kSLock; |
| } |
| |
| /** |
| * @brief Checks whether this access mode is X mode. |
| * |
| * @return True if it is X mode, false otherwise. |
| **/ |
| inline bool isExclusiveLock() const { |
| return access_mode_ == AccessModeType::kXLock; |
| } |
| |
| /** |
| * @brief Checks whether this access mode is in |
| * the same level with other mode. |
| * |
| * @return True if both modes have the same level. |
| **/ |
| inline bool operator==(const AccessMode &other) const { |
| return access_mode_ == other.access_mode_; |
| } |
| |
| /** |
| * @brief Checks whether this access mode is in |
| * the different level with other mode. |
| * |
| * @return True if the modes have different levels. |
| **/ |
| inline bool operator!=(const AccessMode &other) const { |
| return access_mode_ != other.access_mode_; |
| } |
| |
| private: |
| typedef std::underlying_type<AccessModeType>::type |
| access_mode_underlying_type; |
| |
| // The compatibility matrix should be N by N. kNumberLocks == N. |
| static constexpr std::uint64_t kNumberLocks = |
| static_cast<access_mode_underlying_type>( |
| AccessModeType::kNumAccessModeTypes); |
| |
| // Compatibility matrix for checking access modes. |
| // True means they are compatible. |
| static constexpr bool kLockCompatibilityMatrix[kNumberLocks][kNumberLocks] = { |
| /* NL IS IX S SIX X */ |
| /* NL */ {true , true , true , true , true , true }, |
| /* IS */ {true , true , true , true , true , false}, |
| /* IX */ {true , true , true , false, false, false}, |
| /* S */ {true , true , false, true , false, false}, |
| /* SIX */ {true , true , false, false, false, false}, |
| /* X */ {true , false, false, false, false, false} |
| }; |
| |
| // Type of access, the possible values are |
| // NoLock, IsLock, IxLock, SLock, SixLock, XLock |
| AccessModeType access_mode_; |
| }; |
| |
| /** @} */ |
| |
| // static constexpr fields must be declared here, otherwise gcc |
| // gives linkage errors. |
| constexpr bool AccessMode::kLockCompatibilityMatrix[][kNumberLocks]; |
| |
| } // namespace transaction |
| } // namespace quickstep |
| |
| #endif // QUICKSTEP_TRANSACTION_ACCESS_MODE_HPP_ |