1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 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 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 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. 16 * 17 */ 18 19 #ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H 20 #define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include "src/core/lib/iomgr/port.h" 25 26 #include <grpc/support/time.h> 27 28 #include "src/core/lib/gprpp/memory.h" 29 #include "src/core/lib/iomgr/error.h" 30 #include "src/core/lib/iomgr/internal_errqueue.h" 31 32 namespace grpc_core { 33 struct Timestamps { 34 /* TODO(yashykt): This would also need to store OPTSTAT once support is added 35 */ 36 gpr_timespec sendmsg_time; 37 gpr_timespec scheduled_time; 38 gpr_timespec sent_time; 39 gpr_timespec acked_time; 40 }; 41 42 /** TracedBuffer is a class to keep track of timestamps for a specific buffer in 43 * the TCP layer. We are only tracking timestamps for Linux kernels and hence 44 * this class would only be used by Linux platforms. For all other platforms, 45 * TracedBuffer would be an empty class. 46 * 47 * The timestamps collected are according to grpc_core::Timestamps declared 48 * above. 49 * 50 * A TracedBuffer list is kept track of using the head element of the list. If 51 * the head element of the list is nullptr, then the list is empty. 52 */ 53 #ifdef GRPC_LINUX_ERRQUEUE 54 class TracedBuffer { 55 public: 56 /** Add a new entry in the TracedBuffer list pointed to by head. Also saves 57 * sendmsg_time with the current timestamp. */ 58 static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, 59 void* arg); 60 61 /** Processes a received timestamp based on sock_extended_err and 62 * scm_timestamping structures. It will invoke the timestamps callback if the 63 * timestamp type is SCM_TSTAMP_ACK. */ 64 static void ProcessTimestamp(grpc_core::TracedBuffer** head, 65 struct sock_extended_err* serr, 66 struct scm_timestamping* tss); 67 68 /** Cleans the list by calling the callback for each traced buffer in the list 69 * with timestamps that it has. */ 70 static void Shutdown(grpc_core::TracedBuffer** head, 71 grpc_error* shutdown_err); 72 73 private: 74 GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW 75 TracedBuffer(int seq_no,void * arg)76 TracedBuffer(int seq_no, void* arg) 77 : seq_no_(seq_no), arg_(arg), next_(nullptr) {} 78 79 uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ 80 void* arg_; /* The arg to pass to timestamps_callback */ 81 grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */ 82 grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */ 83 }; 84 #else /* GRPC_LINUX_ERRQUEUE */ 85 class TracedBuffer {}; 86 #endif /* GRPC_LINUX_ERRQUEUE */ 87 88 /** Sets the callback function to call when timestamps for a write are 89 * collected. The callback does not own a reference to error. */ 90 void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, 91 grpc_core::Timestamps*, 92 grpc_error* error)); 93 94 }; /* namespace grpc_core */ 95 96 #endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ 97