src/hotspot/os/bsd/os_perf_bsd.cpp
changeset 50879 d90c3cbf13df
parent 50113 caf115bb98ad
child 58282 03fce7b04b42
--- a/src/hotspot/os/bsd/os_perf_bsd.cpp	Thu Jun 28 18:04:19 2018 +0530
+++ b/src/hotspot/os/bsd/os_perf_bsd.cpp	Thu Jun 28 15:06:55 2018 +0200
@@ -34,6 +34,10 @@
   #include <sys/sysctl.h>
   #include <mach/mach.h>
   #include <mach/task_info.h>
+  #include <sys/socket.h>
+  #include <net/if.h>
+  #include <net/if_dl.h>
+  #include <net/route.h>
 #endif
 
 static const double NANOS_PER_SEC = 1000000000.0;
@@ -403,3 +407,85 @@
   cpu_info = *_cpu_info; // shallow copy assignment
   return OS_OK;
 }
+
+class NetworkPerformanceInterface::NetworkPerformance : public CHeapObj<mtInternal> {
+  friend class NetworkPerformanceInterface;
+ private:
+  NetworkPerformance();
+  NetworkPerformance(const NetworkPerformance& rhs); // no impl
+  NetworkPerformance& operator=(const NetworkPerformance& rhs); // no impl
+  bool initialize();
+  ~NetworkPerformance();
+  int network_utilization(NetworkInterface** network_interfaces) const;
+};
+
+NetworkPerformanceInterface::NetworkPerformance::NetworkPerformance() {
+}
+
+bool NetworkPerformanceInterface::NetworkPerformance::initialize() {
+  return true;
+}
+
+NetworkPerformanceInterface::NetworkPerformance::~NetworkPerformance() {
+}
+
+int NetworkPerformanceInterface::NetworkPerformance::network_utilization(NetworkInterface** network_interfaces) const {
+  size_t len;
+  int mib[] = {CTL_NET, PF_ROUTE, /* protocol number */ 0, /* address family */ 0, NET_RT_IFLIST2, /* NET_RT_FLAGS mask*/ 0};
+  if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0) != 0) {
+    return OS_ERR;
+  }
+  uint8_t* buf = NEW_RESOURCE_ARRAY(uint8_t, len);
+  if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &len, NULL, 0) != 0) {
+    return OS_ERR;
+  }
+
+  size_t index = 0;
+  NetworkInterface* ret = NULL;
+  while (index < len) {
+    if_msghdr* msghdr = reinterpret_cast<if_msghdr*>(buf + index);
+    index += msghdr->ifm_msglen;
+
+    if (msghdr->ifm_type != RTM_IFINFO2) {
+      continue;
+    }
+
+    if_msghdr2* msghdr2 = reinterpret_cast<if_msghdr2*>(msghdr);
+    sockaddr_dl* sockaddr = reinterpret_cast<sockaddr_dl*>(msghdr2 + 1);
+
+    // The interface name is not necessarily NUL-terminated
+    char name_buf[128];
+    size_t name_len = MIN2(sizeof(name_buf) - 1, static_cast<size_t>(sockaddr->sdl_nlen));
+    strncpy(name_buf, sockaddr->sdl_data, name_len);
+    name_buf[name_len] = '\0';
+
+    uint64_t bytes_in = msghdr2->ifm_data.ifi_ibytes;
+    uint64_t bytes_out = msghdr2->ifm_data.ifi_obytes;
+
+    NetworkInterface* cur = new NetworkInterface(name_buf, bytes_in, bytes_out, ret);
+    ret = cur;
+  }
+
+  *network_interfaces = ret;
+
+  return OS_OK;
+}
+
+NetworkPerformanceInterface::NetworkPerformanceInterface() {
+  _impl = NULL;
+}
+
+NetworkPerformanceInterface::~NetworkPerformanceInterface() {
+  if (_impl != NULL) {
+    delete _impl;
+  }
+}
+
+bool NetworkPerformanceInterface::initialize() {
+  _impl = new NetworkPerformanceInterface::NetworkPerformance();
+  return _impl != NULL && _impl->initialize();
+}
+
+int NetworkPerformanceInterface::network_utilization(NetworkInterface** network_interfaces) const {
+  return _impl->network_utilization(network_interfaces);
+}