/* * Copyright (c) Facebook, Inc. and its 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 #include #include #include #include #include #include #include #include #include /// /// Classes related to hazard pointer domains. /// namespace folly { namespace detail { /** Threshold for the number of retired objects to trigger asynchronous reclamation. */ constexpr int hazptr_domain_rcount_threshold() { return 1000; } } // namespace detail /** * hazptr_domain * * A domain manages a set of hazard pointers and a set of retired objects. * * Most user code need not specify any domains. * * Notes on destruction order and tagged objects: * - Tagged objects support reclamation order guarantees (i.e., * synchronous reclamation). A call to cleanup_cohort_tag(tag) * guarantees that all objects with the specified tag are reclaimed * before the function returns. * - There are two types of reclamation operations to consider: * - Asynchronous reclamation: It is triggered by meeting some * threshold for the number of retired objects or the time since * the last asynchronous reclamation. Reclaimed objects may have * different tags or no tags. Hazard pointers are checked and only * unprotected objects are reclaimed. This type is expected to be * expensive but infrequent and the cost is amortized over a large * number of reclaimed objects. This type is needed to guarantee * an upper bound on unreclaimed reclaimable objects. * - Synchronous reclamation: It is invoked by calling * cleanup_cohort_tag for a specific tag. All objects with the * specified tag must be reclaimed unconditionally before * returning from such a function call. Hazard pointers are not * checked. This type of reclamation operation is expected to be * inexpensive and may be invoked more frequently than * asynchronous reclamation. * - Tagged retired objects are kept in a sharded list in the domain * structure. * - Both asynchronous and synchronous reclamation pop all the * objects in the tagged list(s) and sort them into two sets of * reclaimable and unreclaimable objects. The objects in the * reclaimable set are reclaimed and the objects in the * unreclaimable set are pushed back in the tagged list(s). * - The tagged list(s) are locked between popping all objects and * pushing back unreclaimable objects, in order to guarantee that * synchronous reclamation operations do not miss any objects. * - Asynchronous reclamation can release the lock(s) on the tagged * list(s) before reclaiming reclaimable objects, because it pushes * reclaimable tagged objects in their respective cohorts, which * would handle concurrent synchronous reclamation of such objects * properly. * - Synchronous reclamation operations can release the lock on the * tagged list shard before reclaiming objects because the sets of * reclaimable objects by different synchronous reclamation * operations are disjoint. */ template