src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp
branchJEP-349-branch
changeset 58154 060d9d139109
parent 57870 00860d9caf4d
child 58182 457ebc7a0cf9
equal deleted inserted replaced
58101:84b0544833c4 58154:060d9d139109
    37 struct InterfaceEntry {
    37 struct InterfaceEntry {
    38   char* name;
    38   char* name;
    39   traceid id;
    39   traceid id;
    40   uint64_t bytes_in;
    40   uint64_t bytes_in;
    41   uint64_t bytes_out;
    41   uint64_t bytes_out;
    42   bool in_use;
    42   mutable bool written;
    43   bool written;
       
    44 };
    43 };
    45 
    44 
    46 static GrowableArray<InterfaceEntry>* _interfaces = NULL;
    45 static GrowableArray<InterfaceEntry>* _interfaces = NULL;
    47 
    46 
    48 void JfrNetworkUtilization::destroy() {
    47 void JfrNetworkUtilization::destroy() {
    70   entry.name = NEW_C_HEAP_ARRAY(char, length + 1, mtInternal);
    69   entry.name = NEW_C_HEAP_ARRAY(char, length + 1, mtInternal);
    71   strncpy(entry.name, name, length + 1);
    70   strncpy(entry.name, name, length + 1);
    72   entry.id = ++interface_id;
    71   entry.id = ++interface_id;
    73   entry.bytes_in = iface->get_bytes_in();
    72   entry.bytes_in = iface->get_bytes_in();
    74   entry.bytes_out = iface->get_bytes_out();
    73   entry.bytes_out = iface->get_bytes_out();
    75   entry.in_use = false;
       
    76   entry.written = false;
    74   entry.written = false;
    77   return _interfaces->at(_interfaces->append(entry));
    75   return _interfaces->at(_interfaces->append(entry));
    78 }
    76 }
    79 
    77 
    80 static GrowableArray<InterfaceEntry>* get_interfaces() {
    78 static GrowableArray<InterfaceEntry>* get_interfaces() {
   108     return 0;
   106     return 0;
   109   }
   107   }
   110   return ((current - old) * NANOSECS_PER_SEC) / interval.nanoseconds();
   108   return ((current - old) * NANOSECS_PER_SEC) / interval.nanoseconds();
   111 }
   109 }
   112 
   110 
       
   111 class JfrNetworkInterfaceName : public JfrSerializer {
       
   112  public:
       
   113    void serialize(JfrCheckpointWriter& writer) {} // we write each constant lazily
       
   114 
       
   115    void on_rotation() {
       
   116      for (int i = 0; i < _interfaces->length(); ++i) {
       
   117        const InterfaceEntry& entry = _interfaces->at(i);
       
   118        if (entry.written) {
       
   119          entry.written = false;
       
   120        }
       
   121      }
       
   122    }
       
   123 };
       
   124 
       
   125 static bool register_network_interface_name_serializer() {
       
   126   assert(_interfaces != NULL, "invariant");
       
   127   return JfrSerializer::register_serializer(TYPE_NETWORKINTERFACENAME,
       
   128     false, // disallow caching; we want a callback every rotation
       
   129     new JfrNetworkInterfaceName());
       
   130 }
       
   131 
       
   132 static void write_interface_constant(const InterfaceEntry& entry) {
       
   133   if (entry.written) {
       
   134     return;
       
   135   }
       
   136   JfrCheckpointWriter writer;
       
   137   writer.write_type(TYPE_NETWORKINTERFACENAME);
       
   138   writer.write_count(1);
       
   139   writer.write_key(entry.id);
       
   140   writer.write(entry.name);
       
   141   entry.written = true;
       
   142 }
       
   143 
   113 static bool get_interfaces(NetworkInterface** network_interfaces) {
   144 static bool get_interfaces(NetworkInterface** network_interfaces) {
   114   const int ret_val = JfrOSInterface::network_utilization(network_interfaces);
   145   const int ret_val = JfrOSInterface::network_utilization(network_interfaces);
   115   if (ret_val == OS_ERR) {
   146   if (ret_val == OS_ERR) {
   116     log_debug(jfr, system)("Unable to generate network utilization events");
   147     log_debug(jfr, system)("Unable to generate network utilization events");
   117     return false;
   148     return false;
   118   }
   149   }
   119   return ret_val != FUNCTIONALITY_NOT_IMPLEMENTED;
   150   return ret_val != FUNCTIONALITY_NOT_IMPLEMENTED;
   120 }
       
   121 
       
   122 static void write_interface_types(JfrCheckpointWriter& writer) {
       
   123     assert(_interfaces != NULL, "invariant");
       
   124   writer.write_type(TYPE_NETWORKINTERFACENAME);
       
   125     const JfrCheckpointContext ctx = writer.context();
       
   126     const intptr_t count_offset = writer.reserve(sizeof(u4)); // Don't know how many yet
       
   127     int active_interfaces = 0;
       
   128     for (int i = 0; i < _interfaces->length(); ++i) {
       
   129       InterfaceEntry& entry = _interfaces->at(i);
       
   130     if (entry.in_use && !entry.written) {
       
   131         entry.in_use = false;
       
   132         entry.written = true;
       
   133         writer.write_key(entry.id);
       
   134         writer.write(entry.name);
       
   135         ++active_interfaces;
       
   136       }
       
   137     }
       
   138     if (active_interfaces == 0) {
       
   139       // nothing to write, restore context
       
   140       writer.set_context(ctx);
       
   141       return;
       
   142     }
       
   143     writer.write_count(active_interfaces, count_offset);
       
   144   }
       
   145 class JfrNetworkInterfaceName : public JfrSerializer {
       
   146  public:
       
   147    void on_rotation() {
       
   148      for (int i = 0; i < _interfaces->length(); ++i) {
       
   149        InterfaceEntry& entry = _interfaces->at(i);
       
   150        entry.written = false;
       
   151      }
       
   152    }
       
   153 };
       
   154 
       
   155 static bool register_network_interface_name_serializer() {
       
   156   assert(_interfaces != NULL, "invariant");
       
   157   return JfrSerializer::register_serializer(TYPE_NETWORKINTERFACENAME,
       
   158                                             false, // disallow caching; we want a callback every rotation
       
   159                                             new JfrNetworkInterfaceName());
       
   160 }
   151 }
   161 
   152 
   162 void JfrNetworkUtilization::send_events() {
   153 void JfrNetworkUtilization::send_events() {
   163   ResourceMark rm;
   154   ResourceMark rm;
   164   NetworkInterface* network_interfaces;
   155   NetworkInterface* network_interfaces;
   177       const uint64_t current_bytes_in = cur->get_bytes_in();
   168       const uint64_t current_bytes_in = cur->get_bytes_in();
   178       const uint64_t current_bytes_out = cur->get_bytes_out();
   169       const uint64_t current_bytes_out = cur->get_bytes_out();
   179       const uint64_t read_rate = rate_per_second(current_bytes_in, entry.bytes_in, interval);
   170       const uint64_t read_rate = rate_per_second(current_bytes_in, entry.bytes_in, interval);
   180       const uint64_t write_rate = rate_per_second(current_bytes_out, entry.bytes_out, interval);
   171       const uint64_t write_rate = rate_per_second(current_bytes_out, entry.bytes_out, interval);
   181       if (read_rate > 0 || write_rate > 0) {
   172       if (read_rate > 0 || write_rate > 0) {
   182         entry.in_use = true;
   173         write_interface_constant(entry);
   183         EventNetworkUtilization event(UNTIMED);
   174         EventNetworkUtilization event(UNTIMED);
   184         event.set_starttime(cur_time);
   175         event.set_starttime(cur_time);
   185         event.set_endtime(cur_time);
   176         event.set_endtime(cur_time);
   186         event.set_networkInterface(entry.id);
   177         event.set_networkInterface(entry.id);
   187         event.set_readRate(8 * read_rate);
   178         event.set_readRate(8 * read_rate);
   188         event.set_writeRate(8 * write_rate);
   179         event.set_writeRate(8 * write_rate);
   189         event.commit();
   180         event.commit();
   190         if (!entry.written) {
       
   191           write_type = true;
       
   192         }
       
   193       }
   181       }
   194       // update existing entry with new values
   182       // update existing entry with new values
   195       entry.bytes_in = current_bytes_in;
   183       entry.bytes_in = current_bytes_in;
   196       entry.bytes_out = current_bytes_out;
   184       entry.bytes_out = current_bytes_out;
   197     }
   185     }
   198   }
   186   }
   199 
   187 
   200   if (write_type) {
       
   201     JfrCheckpointWriter writer;
       
   202     write_interface_types(writer);
       
   203   }
       
   204   static bool is_serializer_registered = false;
   188   static bool is_serializer_registered = false;
   205   if (!is_serializer_registered) {
   189   if (!is_serializer_registered) {
   206     is_serializer_registered = register_network_interface_name_serializer();
   190     is_serializer_registered = register_network_interface_name_serializer();
   207   }
   191   }
   208 }
   192 }