summaryrefslogtreecommitdiff
path: root/absl/strings/cord.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-04-15 19:42:51 -0700
committerGravatar Dino Radaković <dinor@google.com>2021-04-15 19:45:30 -0700
commite20fe888fabc1fc995dc61180e8a31b5f809a95f (patch)
tree5877907889fe35eb3162aa71111e16bd1d59fde4 /absl/strings/cord.h
parent46dfbfe31ca1dd414e4c33cbcbcd7199bb4efde3 (diff)
Export of internal Abseil changes
-- 341670bce317dd6af8d3c066970230591a47e80c by Martijn Vels <mvels@google.com>: Change GetStack() and GetParentStack() to return absl::Span PiperOrigin-RevId: 368765721 -- 6aaab9536d6957303c7aba100c3afaa6fb0ea2c8 by Martijn Vels <mvels@google.com>: Remove locking from parent stack. This change removes the need to lock all access to `parent_stack' by making the 'copy constructor' logic specify the 'copied from' CordzInfo (where available) to the TrackCord function, after which parent_stack is immutable. PiperOrigin-RevId: 368760630 -- b19e2059cada35a8ede994833018edac94de6ddc by Martijn Vels <mvels@google.com>: Add cordz instrumentation to Cord PiperOrigin-RevId: 368746225 -- 67b8bbf980f0f4e1db79aa32968e9a715a09b51a by Martijn Vels <mvels@google.com>: Create ABSL_INTERNAL_CORDZ_ENABLED define controlling when Cordz code is enabled There are specific builds and condtions under which we don't support cordz sampling, which is per this change represented by ABSL_INTERNAL_CORDZ_ENABLED being defined. PiperOrigin-RevId: 368731603 -- 8cbfe0e3169637a620f4b66ad2bc2ce340879cb0 by Martijn Vels <mvels@google.com>: Add a `rep` property to CordzInfo to be managed by Cord logic. This change adds a `rep` property to CordzInfo, which is intended to be used by collection logic. Mini design: Cord invokes TrackCord() providing the active 'root' cordrep of the newly sampled Cord, returning a CordzInfo with a weak (uncounted) reference to this root. Cord invokes `SetCordRep()` each time the root cordrep of the sampled Cord is updated while holding `mutex()`. Cord must also obtain `mutex()` _before_ removing a reference on the old root. i.e.: Cord must guarantee that the (weak) reference held in CordzInfo is at all times valid. CordzInfo collection code can then safely obtain a (reference counted) rep pointer by adding a reference to `rep_` while holding `mutex()`. This requires only a very brief critical section inside CordzInfo logic, minimizing contention with concurrent Cord updates. Cord code should typically obtain and hold `mutex()` for the entirety of each mutating Cord operation on a sampled cord. As Cord is thread compatible, it never competes on the lock with any other thread. The only possible concurrent access is from Cordz collection code, which should be a relatively rare event. PiperOrigin-RevId: 368673758 -- 1255120dce2bdd6b4205a34a0e555e0b74b6152f by Martijn Vels <mvels@google.com>: Remove 'depth' from active recorded metrics. Going forward we do not 'live' record depth (and size), but will observe these at collection time only. PiperOrigin-RevId: 368636572 -- 83e5146e35f221736b49e9f0a8805f8c159a51db by Martijn Vels <mvels@google.com>: Make cordz targets visible in OSS PiperOrigin-RevId: 368615010 -- dcb16a4f1239151f0a8c70a8cfeb29dabbd113b8 by Martijn Vels <mvels@google.com>: Internal cleanup PiperOrigin-RevId: 368514666 GitOrigin-RevId: 341670bce317dd6af8d3c066970230591a47e80c Change-Id: I94cecfbbd441eb386f99fc5186c468a7a5538862
Diffstat (limited to 'absl/strings/cord.h')
-rw-r--r--absl/strings/cord.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index 7ce938ca..de1470b2 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -70,6 +70,7 @@
#include <string>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/internal/per_thread_tls.h"
#include "absl/base/macros.h"
@@ -80,6 +81,9 @@
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_ring.h"
#include "absl/strings/internal/cord_rep_ring_reader.h"
+#include "absl/strings/internal/cordz_functions.h"
+#include "absl/strings/internal/cordz_info.h"
+#include "absl/strings/internal/cordz_statistics.h"
#include "absl/strings/internal/resize_uninitialized.h"
#include "absl/strings/internal/string_constant.h"
#include "absl/strings/string_view.h"
@@ -772,6 +776,20 @@ class Cord {
// Resets the current cordz_info to null / empty.
void clear_cordz_info() { data_.clear_cordz_info(); }
+ // Starts profiling this cord.
+ void StartProfiling();
+
+ // Starts profiling this cord which has been copied from `src`.
+ void StartProfiling(const Cord::InlineRep& src);
+
+ // Returns true if a Cord should be profiled and false otherwise.
+ static bool should_profile();
+
+ // Updates the cordz statistics. info may be nullptr if the CordzInfo object
+ // is unknown.
+ void UpdateCordzStatistics();
+ void UpdateCordzStatisticsSlow();
+
private:
friend class Cord;
@@ -943,6 +961,9 @@ inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src)
if (is_tree()) {
data_.clear_cordz_info();
absl::cord_internal::CordRep::Ref(as_tree());
+ if (ABSL_PREDICT_FALSE(should_profile())) {
+ StartProfiling(src);
+ }
}
}
@@ -1004,6 +1025,9 @@ inline size_t Cord::InlineRep::size() const {
inline void Cord::InlineRep::set_tree(absl::cord_internal::CordRep* rep) {
if (rep == nullptr) {
+ if (ABSL_PREDICT_FALSE(is_profiled())) {
+ absl::cord_internal::CordzInfo::UntrackCord(cordz_info());
+ }
ResetToEmpty();
} else {
if (data_.is_tree()) {
@@ -1013,7 +1037,11 @@ inline void Cord::InlineRep::set_tree(absl::cord_internal::CordRep* rep) {
} else {
// `data_` contains inlined data: initialize data_ to tree value `rep`.
data_.make_tree(rep);
+ if (ABSL_PREDICT_FALSE(should_profile())) {
+ StartProfiling();
+ }
}
+ UpdateCordzStatistics();
}
}
@@ -1024,9 +1052,13 @@ inline void Cord::InlineRep::replace_tree(absl::cord_internal::CordRep* rep) {
return;
}
data_.set_tree(rep);
+ UpdateCordzStatistics();
}
inline absl::cord_internal::CordRep* Cord::InlineRep::clear() {
+ if (ABSL_PREDICT_FALSE(is_profiled())) {
+ absl::cord_internal::CordzInfo::UntrackCord(cordz_info());
+ }
absl::cord_internal::CordRep* result = tree();
ResetToEmpty();
return result;
@@ -1039,6 +1071,15 @@ inline void Cord::InlineRep::CopyToArray(char* dst) const {
cord_internal::SmallMemmove(dst, data_.as_chars(), n);
}
+inline ABSL_ATTRIBUTE_ALWAYS_INLINE bool Cord::InlineRep::should_profile() {
+ return absl::cord_internal::cordz_should_profile();
+}
+
+inline void Cord::InlineRep::UpdateCordzStatistics() {
+ if (ABSL_PREDICT_TRUE(!is_profiled())) return;
+ UpdateCordzStatisticsSlow();
+}
+
constexpr inline Cord::Cord() noexcept {}
template <typename T>