/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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. */ #pragma once #include <atomic> #include <folly/concurrency/CacheLocality.h> #include <folly/synchronization/Hazptr-fwd.h> namespace folly { /** * hazptr_rec: * * Contains the actual hazard pointer. */ template <template <typename> class Atom> class alignas(hardware_destructive_interference_size) hazptr_rec { Atom<const void*> hazptr_{nullptr}; // the hazard pointer hazptr_domain<Atom>* domain_; hazptr_rec* next_; // Next in the main hazard pointer list. Immutable. hazptr_rec* nextAvail_{nullptr}; // Next available hazard pointer. friend class hazptr_domain<Atom>; friend class hazptr_holder<Atom>; #if FOLLY_HAZPTR_THR_LOCAL friend class hazptr_tc<Atom>; #endif friend hazptr_holder<Atom> make_hazard_pointer<Atom>(hazptr_domain<Atom>&); template <uint8_t M, template <typename> class A> friend hazptr_array<M, A> make_hazard_pointer_array(); const void* hazptr() const noexcept { return hazptr_.load(std::memory_order_acquire); } FOLLY_ALWAYS_INLINE void reset_hazptr(const void* p = nullptr) noexcept { hazptr_.store(p, std::memory_order_release); } hazptr_rec<Atom>* next() { return next_; } hazptr_rec<Atom>* next_avail() { return nextAvail_; } void set_next(hazptr_rec<Atom>* rec) { next_ = rec; } void set_next_avail(hazptr_rec<Atom>* rec) { nextAvail_ = rec; } FOLLY_ALWAYS_INLINE hazptr_domain<Atom>* domain() { return domain_; } void set_domain(hazptr_domain<Atom>* dom) { domain_ = dom; } }; // hazptr_rec } // namespace folly