commit
8e10fc9fc9
206 changed files with 16713 additions and 2314 deletions
@ -0,0 +1,134 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/buffer_list.h" |
||||
#include "src/core/lib/iomgr/port.h" |
||||
|
||||
#include <grpc/support/log.h> |
||||
|
||||
#ifdef GRPC_LINUX_ERRQUEUE |
||||
#include <time.h> |
||||
|
||||
#include "src/core/lib/gprpp/memory.h" |
||||
|
||||
namespace grpc_core { |
||||
void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, |
||||
void* arg) { |
||||
GPR_DEBUG_ASSERT(head != nullptr); |
||||
TracedBuffer* new_elem = New<TracedBuffer>(seq_no, arg); |
||||
/* Store the current time as the sendmsg time. */ |
||||
new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); |
||||
if (*head == nullptr) { |
||||
*head = new_elem; |
||||
return; |
||||
} |
||||
/* Append at the end. */ |
||||
TracedBuffer* ptr = *head; |
||||
while (ptr->next_ != nullptr) { |
||||
ptr = ptr->next_; |
||||
} |
||||
ptr->next_ = new_elem; |
||||
} |
||||
|
||||
namespace { |
||||
/** Fills gpr_timespec gts based on values from timespec ts */ |
||||
void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { |
||||
gts->tv_sec = ts->tv_sec; |
||||
gts->tv_nsec = static_cast<int32_t>(ts->tv_nsec); |
||||
gts->clock_type = GPR_CLOCK_REALTIME; |
||||
} |
||||
|
||||
/** The saved callback function that will be invoked when we get all the
|
||||
* timestamps that we are going to get for a TracedBuffer. */ |
||||
void (*timestamps_callback)(void*, grpc_core::Timestamps*, |
||||
grpc_error* shutdown_err); |
||||
} /* namespace */ |
||||
|
||||
void TracedBuffer::ProcessTimestamp(TracedBuffer** head, |
||||
struct sock_extended_err* serr, |
||||
struct scm_timestamping* tss) { |
||||
GPR_DEBUG_ASSERT(head != nullptr); |
||||
TracedBuffer* elem = *head; |
||||
TracedBuffer* next = nullptr; |
||||
while (elem != nullptr) { |
||||
/* The byte number refers to the sequence number of the last byte which this
|
||||
* timestamp relates to. */ |
||||
if (serr->ee_data >= elem->seq_no_) { |
||||
switch (serr->ee_info) { |
||||
case SCM_TSTAMP_SCHED: |
||||
fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0])); |
||||
elem = elem->next_; |
||||
break; |
||||
case SCM_TSTAMP_SND: |
||||
fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0])); |
||||
elem = elem->next_; |
||||
break; |
||||
case SCM_TSTAMP_ACK: |
||||
fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); |
||||
/* Got all timestamps. Do the callback and free this TracedBuffer.
|
||||
* The thing below can be passed by value if we don't want the |
||||
* restriction on the lifetime. */ |
||||
timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE); |
||||
next = elem->next_; |
||||
Delete<TracedBuffer>(elem); |
||||
*head = elem = next; |
||||
break; |
||||
default: |
||||
abort(); |
||||
} |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) { |
||||
GPR_DEBUG_ASSERT(head != nullptr); |
||||
TracedBuffer* elem = *head; |
||||
while (elem != nullptr) { |
||||
if (timestamps_callback) { |
||||
timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); |
||||
} |
||||
auto* next = elem->next_; |
||||
Delete<TracedBuffer>(elem); |
||||
elem = next; |
||||
} |
||||
*head = nullptr; |
||||
GRPC_ERROR_UNREF(shutdown_err); |
||||
} |
||||
|
||||
void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, |
||||
grpc_core::Timestamps*, |
||||
grpc_error* error)) { |
||||
timestamps_callback = fn; |
||||
} |
||||
} /* namespace grpc_core */ |
||||
|
||||
#else /* GRPC_LINUX_ERRQUEUE */ |
||||
|
||||
namespace grpc_core { |
||||
void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, |
||||
grpc_core::Timestamps*, |
||||
grpc_error* error)) { |
||||
gpr_log(GPR_DEBUG, "Timestamps callback is not enabled for this platform"); |
||||
} |
||||
} /* namespace grpc_core */ |
||||
|
||||
#endif /* GRPC_LINUX_ERRQUEUE */ |
@ -0,0 +1,96 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H |
||||
#define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
|
||||
#include <grpc/support/time.h> |
||||
|
||||
#include "src/core/lib/gprpp/memory.h" |
||||
#include "src/core/lib/iomgr/error.h" |
||||
#include "src/core/lib/iomgr/internal_errqueue.h" |
||||
|
||||
namespace grpc_core { |
||||
struct Timestamps { |
||||
/* TODO(yashykt): This would also need to store OPTSTAT once support is added
|
||||
*/ |
||||
gpr_timespec sendmsg_time; |
||||
gpr_timespec scheduled_time; |
||||
gpr_timespec sent_time; |
||||
gpr_timespec acked_time; |
||||
}; |
||||
|
||||
/** TracedBuffer is a class to keep track of timestamps for a specific buffer in
|
||||
* the TCP layer. We are only tracking timestamps for Linux kernels and hence |
||||
* this class would only be used by Linux platforms. For all other platforms, |
||||
* TracedBuffer would be an empty class. |
||||
* |
||||
* The timestamps collected are according to grpc_core::Timestamps declared |
||||
* above. |
||||
* |
||||
* A TracedBuffer list is kept track of using the head element of the list. If |
||||
* the head element of the list is nullptr, then the list is empty. |
||||
*/ |
||||
#ifdef GRPC_LINUX_ERRQUEUE |
||||
class TracedBuffer { |
||||
public: |
||||
/** Add a new entry in the TracedBuffer list pointed to by head. Also saves
|
||||
* sendmsg_time with the current timestamp. */ |
||||
static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, |
||||
void* arg); |
||||
|
||||
/** Processes a received timestamp based on sock_extended_err and
|
||||
* scm_timestamping structures. It will invoke the timestamps callback if the |
||||
* timestamp type is SCM_TSTAMP_ACK. */ |
||||
static void ProcessTimestamp(grpc_core::TracedBuffer** head, |
||||
struct sock_extended_err* serr, |
||||
struct scm_timestamping* tss); |
||||
|
||||
/** Cleans the list by calling the callback for each traced buffer in the list
|
||||
* with timestamps that it has. */ |
||||
static void Shutdown(grpc_core::TracedBuffer** head, |
||||
grpc_error* shutdown_err); |
||||
|
||||
private: |
||||
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW |
||||
|
||||
TracedBuffer(int seq_no, void* arg) |
||||
: seq_no_(seq_no), arg_(arg), next_(nullptr) {} |
||||
|
||||
uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ |
||||
void* arg_; /* The arg to pass to timestamps_callback */ |
||||
grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */ |
||||
grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */ |
||||
}; |
||||
#else /* GRPC_LINUX_ERRQUEUE */ |
||||
class TracedBuffer {}; |
||||
#endif /* GRPC_LINUX_ERRQUEUE */ |
||||
|
||||
/** Sets the callback function to call when timestamps for a write are
|
||||
* collected. The callback does not own a reference to error. */ |
||||
void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, |
||||
grpc_core::Timestamps*, |
||||
grpc_error* error)); |
||||
|
||||
}; /* namespace grpc_core */ |
||||
|
||||
#endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ |
@ -0,0 +1,36 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
|
||||
#include "src/core/lib/iomgr/internal_errqueue.h" |
||||
|
||||
#ifdef GRPC_POSIX_SOCKET_TCP |
||||
|
||||
bool kernel_supports_errqueue() { |
||||
#ifdef LINUX_VERSION_CODE |
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) |
||||
return true; |
||||
#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */ |
||||
#endif /* LINUX_VERSION_CODE */ |
||||
return false; |
||||
} |
||||
|
||||
#endif /* GRPC_POSIX_SOCKET_TCP */ |
@ -0,0 +1,83 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
/* This file contains constants defined in <linux/errqueue.h> and
|
||||
* <linux/net_tstamp.h> so as to allow collecting network timestamps in the |
||||
* kernel. This file allows tcp_posix.cc to compile on platforms that do not |
||||
* have <linux/errqueue.h> and <linux/net_tstamp.h>. |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H |
||||
#define GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
|
||||
#ifdef GRPC_POSIX_SOCKET_TCP |
||||
|
||||
#include <sys/types.h> |
||||
#include <time.h> |
||||
|
||||
#ifdef GRPC_LINUX_ERRQUEUE |
||||
#include <linux/errqueue.h> |
||||
#include <linux/net_tstamp.h> |
||||
#include <sys/socket.h> |
||||
#endif /* GRPC_LINUX_ERRQUEUE */ |
||||
|
||||
namespace grpc_core { |
||||
|
||||
#ifdef GRPC_LINUX_ERRQUEUE |
||||
|
||||
/* Redefining scm_timestamping in the same way that <linux/errqueue.h> defines
|
||||
* it, so that code compiles on systems that don't have it. */ |
||||
struct scm_timestamping { |
||||
struct timespec ts[3]; |
||||
}; |
||||
/* Also redefine timestamp types */ |
||||
/* The timestamp type for when the driver passed skb to NIC, or HW. */ |
||||
constexpr int SCM_TSTAMP_SND = 0; |
||||
/* The timestamp type for when data entered the packet scheduler. */ |
||||
constexpr int SCM_TSTAMP_SCHED = 1; |
||||
/* The timestamp type for when data acknowledged by peer. */ |
||||
constexpr int SCM_TSTAMP_ACK = 2; |
||||
/* Redefine required constants from <linux/net_tstamp.h> */ |
||||
constexpr uint32_t SOF_TIMESTAMPING_TX_SOFTWARE = 1u << 1; |
||||
constexpr uint32_t SOF_TIMESTAMPING_SOFTWARE = 1u << 4; |
||||
constexpr uint32_t SOF_TIMESTAMPING_OPT_ID = 1u << 7; |
||||
constexpr uint32_t SOF_TIMESTAMPING_TX_SCHED = 1u << 8; |
||||
constexpr uint32_t SOF_TIMESTAMPING_TX_ACK = 1u << 9; |
||||
constexpr uint32_t SOF_TIMESTAMPING_OPT_TSONLY = 1u << 11; |
||||
|
||||
constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | |
||||
SOF_TIMESTAMPING_OPT_ID | |
||||
SOF_TIMESTAMPING_OPT_TSONLY; |
||||
constexpr uint32_t kTimestampingRecordingOptions = |
||||
SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | |
||||
SOF_TIMESTAMPING_TX_ACK; |
||||
#endif /* GRPC_LINUX_ERRQUEUE */ |
||||
|
||||
/* Returns true if kernel is capable of supporting errqueue and timestamping.
|
||||
* Currently allowing only linux kernels above 4.0.0 |
||||
*/ |
||||
bool kernel_supports_errqueue(); |
||||
} // namespace grpc_core
|
||||
|
||||
#endif /* GRPC_POSIX_SOCKET_TCP */ |
||||
|
||||
#endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */ |
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue