moonchen commented on code in PR #13583:
URL: https://github.com/apache/trafficserver/pull/13583#discussion_r3928496572


##########
src/tsutil/Metrics.cc:
##########
@@ -179,63 +190,21 @@ Metrics::Storage::type(IdType id) const
   return _extractType(id);
 }
 
-Metrics::SpanType
-Metrics::Storage::createSpan(size_t size, Metrics::MetricType type, 
Metrics::IdType *id)
-{
-  release_assert(size <= MAX_SIZE);
-  std::lock_guard lock(_mutex);
-
-  // On the final blob there is nowhere left to grow, so refuse a span that 
would fill or overflow
-  // it rather than letting addBlob() assert. Same intent as the guard in 
create(), and the same
-  // cost: some slots of the last blob go unused.
-  if (_cur_blob >= MAX_BLOBS - 1 && _cur_off + size >= MAX_SIZE) {
-    if (id) {
-      *id = 0; // Slot 0 is the reserved bad_id.
-    }
-    return {};
-  }
-
-  // A span has to be contiguous, so one that does not fit in the current blob 
starts a new one.
-  if (_cur_off + size > MAX_SIZE) {
-    addBlob();
-  }
-
-  Metrics::IdType           span_start = _makeId(_cur_blob, _cur_off, type);
-  Metrics::NamesAndAtomics *blob       = _blobs[_cur_blob].get();
-  Metrics::AtomicStorage   &atomics    = std::get<1>(*blob);
-  Metrics::SpanType         span       = Metrics::SpanType(&atomics[_cur_off], 
size);
-
-  if (id) {
-    *id = span_start;
-  }
-
-  _cur_off += size;
-
-  // create() grows as soon as it consumes the last slot; do the same here. 
Otherwise a span ending
-  // exactly on the boundary leaves _cur_off at MAX_SIZE, and the next 
create() writes one past the
-  // end of the blob's name array. It also makes end() unreachable for 
iterator::next(), which
-  // wraps on ++offset == MAX_SIZE.
-  if (_cur_off >= MAX_SIZE) {
-    addBlob();
-  }
-
-  return span;
-}
-
 bool
 Metrics::Storage::rename(Metrics::IdType id, std::string_view name)
 {
-  auto [blob_ix, offset]         = _splitID(id);
-  Metrics::NamesAndAtomics *blob = _blobs[blob_ix].get();
-
   // We can only rename Metrics that are already allocated
-  if (!blob || (blob_ix == _cur_blob && offset > _cur_off)) {
+  if (!_is_allocated(id)) {
     return false;
   }
 
-  std::string    &cur = std::get<0>(std::get<0>(*blob)[offset]);
+  // The name is the key _lookups is indexed by, so the whole replacement is 
serialized.
   std::lock_guard lock(_mutex);

Review Comment:
   The acquire on `_next_free` only publishes a slot's initial construction. 
This mutex protects the writer, but `lookup(id, &out_name)` and `name(id)` 
still read the same `std::string` without `_mutex`, and both expose a 
`string_view` into it. I reproduced a TSAN race between the assignment below 
and the read in `lookup()` at line 136. Please give metric names stable 
immutable storage with suitable synchronization/lifetime semantics, or remove 
`rename()`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to