3 * Copyright 2018 gRPC authors.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 #ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H
20 #define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H
22 #include <grpc/support/port_platform.h>
24 #include "src/core/lib/iomgr/port.h"
26 #include <grpc/support/time.h>
28 #include "src/core/lib/gprpp/memory.h"
29 #include "src/core/lib/gprpp/optional.h"
30 #include "src/core/lib/iomgr/error.h"
31 #include "src/core/lib/iomgr/internal_errqueue.h"
35 struct ConnectionMetrics {
36 /* Delivery rate in Bytes/s. */
37 Optional<uint64_t> delivery_rate;
38 /* If the delivery rate is limited by the application, this is set to true. */
39 Optional<bool> is_delivery_rate_app_limited;
40 /* Total packets retransmitted. */
41 Optional<uint32_t> packet_retx;
42 /* Total packets retransmitted spuriously. This metric is smaller than or
43 equal to packet_retx. */
44 Optional<uint32_t> packet_spurious_retx;
45 /* Total packets sent. */
46 Optional<uint32_t> packet_sent;
47 /* Total packets delivered. */
48 Optional<uint32_t> packet_delivered;
49 /* Total packets delivered with ECE marked. This metric is smaller than or
50 equal to packet_delivered. */
51 Optional<uint32_t> packet_delivered_ce;
52 /* Total bytes lost so far. */
53 Optional<uint64_t> data_retx;
54 /* Total bytes sent so far. */
55 Optional<uint64_t> data_sent;
56 /* Total bytes in write queue but not sent. */
57 Optional<uint64_t> data_notsent;
58 /* Pacing rate of the connection in Bps */
59 Optional<uint64_t> pacing_rate;
60 /* Minimum RTT observed in usec. */
61 Optional<uint32_t> min_rtt;
62 /* Smoothed RTT in usec */
63 Optional<uint32_t> srtt;
64 /* Send congestion window. */
65 Optional<uint32_t> congestion_window;
66 /* Slow start threshold in packets. */
67 Optional<uint32_t> snd_ssthresh;
68 /* Maximum degree of reordering (i.e., maximum number of packets reodered)
70 Optional<uint32_t> reordering;
71 /* Represents the number of recurring retransmissions of the first sequence
72 that is not acknowledged yet. */
73 Optional<uint8_t> recurring_retrans;
74 /* The cumulative time (in usec) that the transport protocol was busy
76 Optional<uint64_t> busy_usec;
77 /* The cumulative time (in usec) that the transport protocol was limited by
78 the receive window size. */
79 Optional<uint64_t> rwnd_limited_usec;
80 /* The cumulative time (in usec) that the transport protocol was limited by
81 the send buffer size. */
82 Optional<uint64_t> sndbuf_limited_usec;
87 ConnectionMetrics metrics; /* Metrics collected with this timestamp */
91 Timestamp sendmsg_time;
92 Timestamp scheduled_time;
96 uint32_t byte_offset; /* byte offset relative to the start of the RPC */
98 #ifdef GRPC_LINUX_ERRQUEUE
99 grpc_core::tcp_info info; /* tcp_info collected on sendmsg */
100 #endif /* GRPC_LINUX_ERRQUEUE */
103 /** TracedBuffer is a class to keep track of timestamps for a specific buffer in
104 * the TCP layer. We are only tracking timestamps for Linux kernels and hence
105 * this class would only be used by Linux platforms. For all other platforms,
106 * TracedBuffer would be an empty class.
108 * The timestamps collected are according to grpc_core::Timestamps declared
111 * A TracedBuffer list is kept track of using the head element of the list. If
112 * the head element of the list is nullptr, then the list is empty.
114 #ifdef GRPC_LINUX_ERRQUEUE
117 /** Add a new entry in the TracedBuffer list pointed to by head. Also saves
118 * sendmsg_time with the current timestamp. */
119 static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no,
122 /** Processes a received timestamp based on sock_extended_err and
123 * scm_timestamping structures. It will invoke the timestamps callback if the
124 * timestamp type is SCM_TSTAMP_ACK. */
125 static void ProcessTimestamp(grpc_core::TracedBuffer** head,
126 struct sock_extended_err* serr,
127 struct cmsghdr* opt_stats,
128 struct scm_timestamping* tss);
130 /** Cleans the list by calling the callback for each traced buffer in the list
131 * with timestamps that it has. */
132 static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
133 grpc_error* shutdown_err);
136 GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
138 TracedBuffer(uint32_t seq_no, void* arg)
139 : seq_no_(seq_no), arg_(arg), next_(nullptr) {}
141 uint32_t seq_no_; /* The sequence number for the last byte in the buffer */
142 void* arg_; /* The arg to pass to timestamps_callback */
143 grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */
144 grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */
146 #else /* GRPC_LINUX_ERRQUEUE */
149 /* Dummy shutdown function */
150 static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
151 grpc_error* shutdown_err) {
152 GRPC_ERROR_UNREF(shutdown_err);
155 #endif /* GRPC_LINUX_ERRQUEUE */
157 /** Sets the callback function to call when timestamps for a write are
158 * collected. The callback does not own a reference to error. */
159 void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*,
160 grpc_core::Timestamps*,
163 } /* namespace grpc_core */
165 #endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */