thread_local.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #pragma once
  10. #include <atomic>
  11. #include <functional>
  12. #include <memory>
  13. #include <unordered_map>
  14. #include <vector>
  15. #include "util/autovector.h"
  16. #include "port/port.h"
  17. namespace ROCKSDB_NAMESPACE {
  18. // Cleanup function that will be called for a stored thread local
  19. // pointer (if not NULL) when one of the following happens:
  20. // (1) a thread terminates
  21. // (2) a ThreadLocalPtr is destroyed
  22. //
  23. // Warning: this function is called while holding a global mutex. The same mutex
  24. // is used (at least in some cases) by most methods of ThreadLocalPtr, and it's
  25. // shared across all instances of ThreadLocalPtr. Thereforere extra care
  26. // is needed to avoid deadlocks. In particular, the handler shouldn't lock any
  27. // mutexes and shouldn't call any methods of any ThreadLocalPtr instances,
  28. // unless you know what you're doing.
  29. typedef void (*UnrefHandler)(void* ptr);
  30. // ThreadLocalPtr stores only values of pointer type. Different from
  31. // the usual thread-local-storage, ThreadLocalPtr has the ability to
  32. // distinguish data coming from different threads and different
  33. // ThreadLocalPtr instances. For example, if a regular thread_local
  34. // variable A is declared in DBImpl, two DBImpl objects would share
  35. // the same A. However, a ThreadLocalPtr that is defined under the
  36. // scope of DBImpl can avoid such confliction. As a result, its memory
  37. // usage would be O(# of threads * # of ThreadLocalPtr instances).
  38. class ThreadLocalPtr {
  39. public:
  40. explicit ThreadLocalPtr(UnrefHandler handler = nullptr);
  41. ThreadLocalPtr(const ThreadLocalPtr&) = delete;
  42. ThreadLocalPtr& operator=(const ThreadLocalPtr&) = delete;
  43. ~ThreadLocalPtr();
  44. // Return the current pointer stored in thread local
  45. void* Get() const;
  46. // Set a new pointer value to the thread local storage.
  47. void Reset(void* ptr);
  48. // Atomically swap the supplied ptr and return the previous value
  49. void* Swap(void* ptr);
  50. // Atomically compare the stored value with expected. Set the new
  51. // pointer value to thread local only if the comparison is true.
  52. // Otherwise, expected returns the stored value.
  53. // Return true on success, false on failure
  54. bool CompareAndSwap(void* ptr, void*& expected);
  55. // Reset all thread local data to replacement, and return non-nullptr
  56. // data for all existing threads
  57. void Scrape(autovector<void*>* ptrs, void* const replacement);
  58. typedef std::function<void(void*, void*)> FoldFunc;
  59. // Update res by applying func on each thread-local value. Holds a lock that
  60. // prevents unref handler from running during this call, but clients must
  61. // still provide external synchronization since the owning thread can
  62. // access the values without internal locking, e.g., via Get() and Reset().
  63. void Fold(FoldFunc func, void* res);
  64. // Add here for testing
  65. // Return the next available Id without claiming it
  66. static uint32_t TEST_PeekId();
  67. // Initialize the static singletons of the ThreadLocalPtr.
  68. //
  69. // If this function is not called, then the singletons will be
  70. // automatically initialized when they are used.
  71. //
  72. // Calling this function twice or after the singletons have been
  73. // initialized will be no-op.
  74. static void InitSingletons();
  75. class StaticMeta;
  76. private:
  77. static StaticMeta* Instance();
  78. const uint32_t id_;
  79. };
  80. } // namespace ROCKSDB_NAMESPACE