src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp
branchJEP-349-branch
changeset 57360 5d043a159d5c
parent 53013 c8b2a408628b
child 57870 00860d9caf4d
equal deleted inserted replaced
57359:4cab5edc2950 57360:5d043a159d5c
     1 /*
     1 /*
     2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    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   bool in_use;
       
    43   bool written;
    43 };
    44 };
    44 
    45 
    45 static GrowableArray<InterfaceEntry>* _interfaces = NULL;
    46 static GrowableArray<InterfaceEntry>* _interfaces = NULL;
    46 
    47 
    47 void JfrNetworkUtilization::destroy() {
    48 void JfrNetworkUtilization::destroy() {
    70   strncpy(entry.name, name, length + 1);
    71   strncpy(entry.name, name, length + 1);
    71   entry.id = ++interface_id;
    72   entry.id = ++interface_id;
    72   entry.bytes_in = iface->get_bytes_in();
    73   entry.bytes_in = iface->get_bytes_in();
    73   entry.bytes_out = iface->get_bytes_out();
    74   entry.bytes_out = iface->get_bytes_out();
    74   entry.in_use = false;
    75   entry.in_use = false;
       
    76   entry.written = false;
    75   return _interfaces->at(_interfaces->append(entry));
    77   return _interfaces->at(_interfaces->append(entry));
    76 }
    78 }
    77 
    79 
    78 static GrowableArray<InterfaceEntry>* get_interfaces() {
    80 static GrowableArray<InterfaceEntry>* get_interfaces() {
    79   if (_interfaces == NULL) {
    81   if (_interfaces == NULL) {
   115     return false;
   117     return false;
   116   }
   118   }
   117   return ret_val != FUNCTIONALITY_NOT_IMPLEMENTED;
   119   return ret_val != FUNCTIONALITY_NOT_IMPLEMENTED;
   118 }
   120 }
   119 
   121 
   120 class JfrNetworkInterfaceName : public JfrSerializer {
   122 static void write_interface_types(JfrCheckpointWriter& writer) {
   121  public:
       
   122   void serialize(JfrCheckpointWriter& writer) {
       
   123     assert(_interfaces != NULL, "invariant");
   123     assert(_interfaces != NULL, "invariant");
       
   124   writer.write_type(TYPE_NETWORKINTERFACENAME);
   124     const JfrCheckpointContext ctx = writer.context();
   125     const JfrCheckpointContext ctx = writer.context();
   125     const intptr_t count_offset = writer.reserve(sizeof(u4)); // Don't know how many yet
   126     const intptr_t count_offset = writer.reserve(sizeof(u4)); // Don't know how many yet
   126     int active_interfaces = 0;
   127     int active_interfaces = 0;
   127     for (int i = 0; i < _interfaces->length(); ++i) {
   128     for (int i = 0; i < _interfaces->length(); ++i) {
   128       InterfaceEntry& entry = _interfaces->at(i);
   129       InterfaceEntry& entry = _interfaces->at(i);
   129       if (entry.in_use) {
   130     if (entry.in_use && !entry.written) {
   130         entry.in_use = false;
   131         entry.in_use = false;
       
   132         entry.written = true;
   131         writer.write_key(entry.id);
   133         writer.write_key(entry.id);
   132         writer.write(entry.name);
   134         writer.write(entry.name);
   133         ++active_interfaces;
   135         ++active_interfaces;
   134       }
   136       }
   135     }
   137     }
   138       writer.set_context(ctx);
   140       writer.set_context(ctx);
   139       return;
   141       return;
   140     }
   142     }
   141     writer.write_count(active_interfaces, count_offset);
   143     writer.write_count(active_interfaces, count_offset);
   142   }
   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    }
   143 };
   153 };
   144 
   154 
   145 static bool register_network_interface_name_serializer() {
   155 static bool register_network_interface_name_serializer() {
   146   assert(_interfaces != NULL, "invariant");
   156   assert(_interfaces != NULL, "invariant");
   147   return JfrSerializer::register_serializer(TYPE_NETWORKINTERFACENAME,
   157   return JfrSerializer::register_serializer(TYPE_NETWORKINTERFACENAME,
   148                                             false, // require safepoint
       
   149                                             false, // disallow caching; we want a callback every rotation
   158                                             false, // disallow caching; we want a callback every rotation
   150                                             new JfrNetworkInterfaceName());
   159                                             new JfrNetworkInterfaceName());
   151 }
   160 }
   152 
   161 
   153 void JfrNetworkUtilization::send_events() {
   162 void JfrNetworkUtilization::send_events() {
   159   log_trace(jfr, event)("Reporting network utilization");
   168   log_trace(jfr, event)("Reporting network utilization");
   160   static JfrTicks last_sample_instant;
   169   static JfrTicks last_sample_instant;
   161   const JfrTicks cur_time = JfrTicks::now();
   170   const JfrTicks cur_time = JfrTicks::now();
   162   const JfrTickspan interval = last_sample_instant == 0 ? cur_time - cur_time : cur_time - last_sample_instant;
   171   const JfrTickspan interval = last_sample_instant == 0 ? cur_time - cur_time : cur_time - last_sample_instant;
   163   last_sample_instant = cur_time;
   172   last_sample_instant = cur_time;
       
   173   bool write_type = false;
   164   for (NetworkInterface *cur = network_interfaces; cur != NULL; cur = cur->next()) {
   174   for (NetworkInterface *cur = network_interfaces; cur != NULL; cur = cur->next()) {
   165     InterfaceEntry& entry = get_entry(cur);
   175     InterfaceEntry& entry = get_entry(cur);
   166     if (interval.value() > 0) {
   176     if (interval.value() > 0) {
   167       const uint64_t current_bytes_in = cur->get_bytes_in();
   177       const uint64_t current_bytes_in = cur->get_bytes_in();
   168       const uint64_t current_bytes_out = cur->get_bytes_out();
   178       const uint64_t current_bytes_out = cur->get_bytes_out();
   175         event.set_endtime(cur_time);
   185         event.set_endtime(cur_time);
   176         event.set_networkInterface(entry.id);
   186         event.set_networkInterface(entry.id);
   177         event.set_readRate(8 * read_rate);
   187         event.set_readRate(8 * read_rate);
   178         event.set_writeRate(8 * write_rate);
   188         event.set_writeRate(8 * write_rate);
   179         event.commit();
   189         event.commit();
       
   190         if (!entry.written) {
       
   191           write_type = true;
       
   192         }
   180       }
   193       }
   181       // update existing entry with new values
   194       // update existing entry with new values
   182       entry.bytes_in = current_bytes_in;
   195       entry.bytes_in = current_bytes_in;
   183       entry.bytes_out = current_bytes_out;
   196       entry.bytes_out = current_bytes_out;
   184     }
   197     }
   185   }
   198   }
   186 
   199 
       
   200   if (write_type) {
       
   201     JfrCheckpointWriter writer(false, true, Thread::current());
       
   202     write_interface_types(writer);
       
   203   }
   187   static bool is_serializer_registered = false;
   204   static bool is_serializer_registered = false;
   188   if (!is_serializer_registered) {
   205   if (!is_serializer_registered) {
   189     is_serializer_registered = register_network_interface_name_serializer();
   206     is_serializer_registered = register_network_interface_name_serializer();
   190   }
   207   }
   191 }
   208 }