f->dump_int("threshold to keep", history_slow_op_threshold.load());
{
f->open_array_section("Ops");
- for (const auto& [t, op] : slow_op) {
+ for ([[maybe_unused]] const auto& [t, op] : slow_op) {
if (!op->filter_out(filters))
continue;
f->open_object_section("Op");
// no more slow ops in flight
return false;
}
+ if (op.is_continuous()) {
+ return true; /* skip reporting */
+ }
if (!op.warn_interval_multiplier)
return true;
slow++;
f->dump_stream("initiated_at") << get_initiated();
f->dump_float("age", now - get_initiated());
f->dump_float("duration", get_duration());
+ f->dump_bool("continuous", is_continuous());
{
f->open_object_section("type_data");
lambda(*this, f);
template <typename T, typename U>
typename T::Ref create_request(U params)
{
+ constexpr bool has_is_continuous = requires(U u) {
+ { u->is_continuous() } -> std::same_as<bool>;
+ };
typename T::Ref retval(new T(params, this));
retval->tracking_start();
if (is_tracking()) {
retval->mark_event("all_read", params->get_recv_complete_stamp());
retval->mark_event("dispatched", params->get_dispatch_stamp());
}
+ if constexpr (has_is_continuous) {
+ if (params->is_continuous()) {
+ retval->mark_continuous();
+ }
+ }
return retval;
}
};
class TrackedOp : public boost::intrusive::list_base_hook<> {
-private:
+public:
friend class OpHistory;
friend class OpTracker;
- boost::intrusive::list_member_hook<> tracker_item;
+ static const uint64_t FLAG_CONTINUOUS = (1<<1);
+private:
+ boost::intrusive::list_member_hook<> tracker_item;
public:
typedef boost::intrusive::list<
TrackedOp,
}
};
+
protected:
OpTracker *tracker; ///< the tracker we are associated with
std::atomic_int nref = {0}; ///< ref count
STATE_HISTORY
};
std::atomic<int> state = {STATE_UNTRACKED};
+ uint64_t flags = 0;
+
+ void mark_continuous() {
+ flags |= FLAG_CONTINUOUS;
+ }
+ bool is_continuous() const {
+ return flags & FLAG_CONTINUOUS;
+ }
TrackedOp(OpTracker *_tracker, const utime_t& initiated) :
tracker(_tracker),