diff options
author | Abseil Team <absl-team@google.com> | 2021-04-20 07:17:48 -0700 |
---|---|---|
committer | Dino Radaković <dinor@google.com> | 2021-04-20 08:45:46 -0700 |
commit | 1ae9b71c474628d60eb251a3f62967fe64151bb2 (patch) | |
tree | cb4fb71be788b327f78bd0d2fc8ec7b4f2a022c5 /absl/strings/internal/cordz_info.h | |
parent | 732c6540c19610d2653ce73c09eb6cb66da15f42 (diff) | |
download | abseil-1ae9b71c474628d60eb251a3f62967fe64151bb2.tar.gz abseil-1ae9b71c474628d60eb251a3f62967fe64151bb2.tar.bz2 abseil-1ae9b71c474628d60eb251a3f62967fe64151bb2.zip |
Export of internal Abseil changes
--
ac1df60490c9583e475e22de7adfc40023196fbf by Martijn Vels <mvels@google.com>:
Change Cord constructor(string_view) to explicit make_tree and Cordz tracking
This CL changes the ctor to use an easier to maintain model where Cord code explicitly invokes Cordz update or new / tree logic, which avoids the ambiguity of the 'branched' InlineRep::set_tree code. This removes the need to equip InlineRep with 'MethodIdentifier' or other necessary call info, and also is a cleaner model: InlineRep is carrying too much code now that should plainly sit in Cord, especially with all internal abstractions having moved to InlineData.
See child CL(s) for desired state
PiperOrigin-RevId: 369433619
--
b665af7f586e6c679a8b27d4f78d5a1d2b596058 by Abseil Team <absl-team@google.com>:
Rename the 'Compare' template type to 'LessThan', as the passed-in function is expected to act like operator<. It is worth avoiding confusion with std::compare, which returns an int (-1/0/1), as due to implicit casting this can lead to hard-to-spot bugs.
PiperOrigin-RevId: 369391118
--
c3c775269cad0f4982ec63f3616dd78bb9e52dca by Martijn Vels <mvels@google.com>:
Integrate CordzUpdateTracker into CordzInfo
PiperOrigin-RevId: 369348824
--
771d81ed357496c117179e1daec76eba5155932d by Martijn Vels <mvels@google.com>:
Replace mutex() with Lock() / Unlock() function
Mini design future tracking of CordzInfo sampled cords: CordzInfo holds a CordRep* reference without a reference count. Cord is responsible for synchronizing updates for sampled cords such that the CordRep* contained in CordzInfo is at all times valid. This is done by scoping Lock() and Unlock() calls around the code modifying the code of a sampled cord. For example (using the future CL CordzUpdateScope()):
CordzInfo* cordz_info = get_cordz_info();
CordzUpdateScope scope(cordz_info, CordzUpdateTracker::kRemovePrefix);
CordRep* rep = RemovePrefixImpl(root);
set_tree(rep);
if (cordz_info) {
cordz_info->SetCordRep(rep);
}
On CordzInfo::Unlock(), if the internal rep is null, the cord is no longer sampled, and CordzInfo will be deleted. Thus any update resulting in the Cord being inlined will automatically no longer be sampled.
PiperOrigin-RevId: 369338802
--
5563c12df04a1e965a03b50bdd032739c55c0706 by Martijn Vels <mvels@google.com>:
Add UpdateTracker to CordzStatistics
PiperOrigin-RevId: 369318178
--
6b4d8463722a3e55a3e8f6cb3741a41055e7f83e by Martijn Vels <mvels@google.com>:
Add kClear, kConstructor* and kUnknown values and fix typo
PiperOrigin-RevId: 369297163
--
041adcbc929789d6d53371a8236840fc350e1eeb by Derek Mauro <dmauro@google.com>:
Switch from malloc to operator new in pool_urbg.cc
so it can only fail by throwing/aborting
PiperOrigin-RevId: 369274087
--
5d97a5f43e3f2d02d0a5bbe586d93b5751812981 by Benjamin Barenblat <bbaren@google.com>:
Correct Thumb function bound computation in the symbolizer
On 32-bit ARM, all functions are aligned to multiples of two bytes, and
the lowest-order bit in a function’s address is ignored by the CPU when
computing branch targets. That bit is still present in instructions and
ELF symbol tables, though; it’s repurposed to indicate whether the
function contains ARM or Thumb code. If the symbolizer doesn’t ignore
that bit, it will believe Thumb functions have boundaries that are off
by one byte, so instruct the symbolizer to null out the lowest-order bit
after retrieving it from the symbol table.
PiperOrigin-RevId: 369254082
--
462bb307c6cc332c1e2c3adb5f0cad51804bf937 by Derek Mauro <dmauro@google.com>:
Add a check for malloc failure in pool_urbg.cc
GitHub #940
PiperOrigin-RevId: 369238100
GitOrigin-RevId: ac1df60490c9583e475e22de7adfc40023196fbf
Change-Id: Ic6ec91c62cd3a0031f6a75a43a83da959ece2d25
Diffstat (limited to 'absl/strings/internal/cordz_info.h')
-rw-r--r-- | absl/strings/internal/cordz_info.h | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/absl/strings/internal/cordz_info.h b/absl/strings/internal/cordz_info.h index c1090a1c..5345be75 100644 --- a/absl/strings/internal/cordz_info.h +++ b/absl/strings/internal/cordz_info.h @@ -24,6 +24,7 @@ #include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/cordz_handle.h" #include "absl/strings/internal/cordz_statistics.h" +#include "absl/strings/internal/cordz_update_tracker.h" #include "absl/synchronization/mutex.h" #include "absl/types/span.h" @@ -42,13 +43,20 @@ namespace cord_internal { // the destructor of a CordzSampleToken object. class CordzInfo : public CordzHandle { public: + using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; + // All profiled Cords should be accompanied by a call to TrackCord. // TrackCord creates a CordzInfo instance which tracks important metrics of // the sampled cord. CordzInfo instances are placed in a global list which is // used to discover and snapshot all actively tracked cords. // Callers are responsible for calling UntrackCord() before the tracked Cord // instance is deleted, or to stop tracking the sampled Cord. - static CordzInfo* TrackCord(CordRep* rep); + // Callers are also responsible for guarding changes to `rep` through the + // Lock() and Unlock() calls, and calling SetCordRep() if the root of the + // sampled cord changes before the old root has been unreffed and/or deleted. + // `method` identifies the Cord method which initiated the cord to be sampled. + static CordzInfo* TrackCord( + CordRep* rep, MethodIdentifier method = MethodIdentifier::kUnknown); // Stops tracking changes for a sampled cord, and deletes the provided info. // This function must be called before the sampled cord instance is deleted, @@ -58,10 +66,12 @@ class CordzInfo : public CordzHandle { static void UntrackCord(CordzInfo* cordz_info); // Identical to TrackCord(), except that this function fills the - // 'parent_stack' property of the returned CordzInfo instance from the - // provided `src` instance if `src` is not null. + // `parent_stack` and `parent_method` properties of the returned CordzInfo + // instance from the provided `src` instance if `src` is not null. // This function should be used for sampling 'copy constructed' cords. - static CordzInfo* TrackCord(CordRep* rep, const CordzInfo* src); + static CordzInfo* TrackCord( + CordRep* rep, const CordzInfo* src, + MethodIdentifier method = MethodIdentifier::kUnknown); CordzInfo() = delete; CordzInfo(const CordzInfo&) = delete; @@ -73,17 +83,20 @@ class CordzInfo : public CordzHandle { // Retrieves the next oldest existing CordzInfo older than 'this' instance. CordzInfo* Next(const CordzSnapshot& snapshot) const; - // Returns a reference to the mutex guarding the `rep` property of this - // instance. CordzInfo instances hold a weak reference to the rep pointer of - // sampled cords, and rely on Cord logic to update the rep pointer when the - // underlying root tree or ring of the cord changes. - absl::Mutex& mutex() const { return mutex_; } + // Locks this instance for the update identified by `method`. + // Increases the count for `method` in `update_tracker`. + void Lock(MethodIdentifier method) ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_); + + // Unlocks this instance. If the contained `rep` has been set to null + // indicating the Cord has been cleared or is otherwise no longer sampled, + // then this method will delete this CordzInfo instance. + void Unlock() ABSL_UNLOCK_FUNCTION(mutex_); // Updates the `rep' property of this instance. This methods is invoked by // Cord logic each time the root node of a sampled Cord changes, and before // the old root reference count is deleted. This guarantees that collection // code can always safely take a reference on the tracked cord. - // Requires `mutex()` to be held. + // Requires a lock to be held through the `Lock()` method. // TODO(b/117940323): annotate with ABSL_EXCLUSIVE_LOCKS_REQUIRED once all // Cord code is in a state where this can be proven true by the compiler. void SetCordRep(CordRep* rep); @@ -106,15 +119,10 @@ class CordzInfo : public CordzHandle { // from, or being assigned the value of an existing (sampled) cord. absl::Span<void* const> GetParentStack() const; - // Retrieve the CordzStatistics associated with this Cord. The statistics are - // only updated when a Cord goes through a mutation, such as an Append or - // RemovePrefix. The refcounts can change due to external events, so the - // reported refcount stats might be incorrect. - CordzStatistics GetCordzStatistics() const { - CordzStatistics stats; - stats.size = size_.load(std::memory_order_relaxed); - return stats; - } + // Retrieves the CordzStatistics associated with this Cord. The statistics + // are only updated when a Cord goes through a mutation, such as an Append + // or RemovePrefix. + CordzStatistics GetCordzStatistics() const; // Records size metric for this CordzInfo instance. void RecordMetrics(int64_t size) { @@ -124,9 +132,21 @@ class CordzInfo : public CordzHandle { private: static constexpr int kMaxStackDepth = 64; - explicit CordzInfo(CordRep* tree); + explicit CordzInfo(CordRep* rep, const CordzInfo* src, + MethodIdentifier method); ~CordzInfo() override; + // Returns the parent method from `src`, which is either `parent_method_` or + // `method_` depending on `parent_method_` being kUnknown. + // Returns kUnknown if `src` is null. + static MethodIdentifier GetParentMethod(const CordzInfo* src); + + // Fills the provided stack from `src`, copying either `parent_stack_` or + // `stack_` depending on `parent_stack_` being empty, returning the size of + // the parent stack. + // Returns 0 if `src` is null. + static int FillParentStack(const CordzInfo* src, void** stack); + void Track(); void Untrack(); @@ -149,12 +169,15 @@ class CordzInfo : public CordzHandle { std::atomic<CordzInfo*> ci_next_ ABSL_GUARDED_BY(ci_mutex_){nullptr}; mutable absl::Mutex mutex_; - CordRep* rep_ ABSL_GUARDED_BY(mutex()); + CordRep* rep_ ABSL_GUARDED_BY(mutex_); void* stack_[kMaxStackDepth]; void* parent_stack_[kMaxStackDepth]; const int stack_depth_; - int parent_stack_depth_; + const int parent_stack_depth_; + const MethodIdentifier method_; + const MethodIdentifier parent_method_; + CordzUpdateTracker update_tracker_; const absl::Time create_time_; // Last recorded size for the cord. |