/* * 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 // for hash set in bulk_reclaim /// /// Classes related to hazard pointer domains. /// namespace folly { namespace detail { 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, tagged objects, locking and deadlock * avoidance: * - Tagged objects support reclamation order guarantees. A call to * cleanup_cohort_tag(tag) guarantees that all objects with the * specified tag are reclaimed before the function returns. * - Due to the strict order, access to the set of tagged objects * needs synchronization and care must be taken to avoid deadlock. * - There are two types of reclamation operations to consider: * - Type A: A Type A reclamation operation is triggered by meeting * some threshold. Reclaimed objects may have different * 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. * - Type B: A Type B reclamation operation is triggered by a call * to the function 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 Type A. * - Tagged retired objects are kept in a single list in the domain * structure, named tagged_. * - Both Type A and Type B of reclamation pop all the objects in * tagged_ 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 tagged_. * - The tagged_ list is locked between popping all objects and * pushing back unreclaimable objects, in order to guarantee that * Type B operations do not miss any objects that match the * specified tag. * - A Type A operation cannot release the lock on the tagged_ list * before reclaiming reclaimable objects, to prevent concurrent * Type B operations from returning before the reclamation of * objects with matching tags. * - A Type B operation can release the lock on tagged_ before * reclaiming objects because the set of reclaimable objects by * Type B operations are disjoint. * - The lock on the tagged_ list is re-entrant, to prevent deadlock * when reclamation in a Type A operation requires a Type B * reclamation operation to complete. * - The implementation allows only one pattern of re-entrance: An * inner Type B inside an outer Type A. * - An inner Type B operation must have access and ability to modify * the outer Type A operation's set of reclaimable objects and * their children objects in order not to miss objects that match * the specified tag. Hence, Type A operations use data members, * unprotected_ and children_, to keep track of these objects * between reclamation steps and to provide inner Type B operations * access to these objects. */ template