1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_G1_G1NUMA_HPP
  26 #define SHARE_VM_GC_G1_G1NUMA_HPP
  27 
  28 #include "runtime/globals.hpp"
  29 
  30 // Manages NUMA node related information.
  31 // Provides a conversion between NUMA indices (sequential, starting
  32 // from zero) and NUMA ids (which may not start at zero and may not be
  33 // sequential). Indices are generally used by clients, and mapped to
  34 // ids when dealing with the OS/hardware layer.
  35 class G1NUMA : public CHeapObj<mtGC> {
  36   // Mapping of available numa ids to some 0-based index which can be used for
  37   // fast resource management. I.e. for every numa id provides a unique value in
  38   // the range from [0, {# of numa nodes-1}].
  39   // For invalid numa id, return G1MemoryNodeManager::InvalidNodeIndex.
  40   // So the caller need exception handling.
  41   uint* _numa_id_to_index_map;
  42   // Length of numa_id to index map.
  43   int _len_numa_id_to_index_map;
  44 
  45   // Necessary when touching memory.
  46   size_t _page_size;
  47 
  48   // Current active numa ids.
  49   int* _numa_ids;
  50   // Total number of numa ids.
  51   uint _num_active_numa_ids;
  52 
  53   static G1NUMA* _inst;
  54 
  55   // Creates numa id and numa index mapping table of _numa_id_to_index_map.
  56   void init_numa_id_to_index_map(const int* numa_ids, uint num_numa_ids);
  57 
  58 public:
  59   G1NUMA() : _numa_id_to_index_map(NULL), _len_numa_id_to_index_map(0),
  60              _page_size(0), _numa_ids(NULL), _num_active_numa_ids(0) { }
  61   ~G1NUMA();
  62 
  63   static G1NUMA* numa() { return _inst; }
  64 
  65   static void set_numa(G1NUMA* numa) {
  66     guarantee(_inst == NULL, "Should be called once.");
  67 
  68     _inst = numa;
  69   }
  70 
  71   void request_memory_on_node(address aligned_address, size_t size_in_bytes);
  72 
  73   bool initialize();
  74 
  75   inline bool is_valid_numa_id(int numa_id);
  76 
  77   inline bool is_valid_numa_index(uint numa_index) const;
  78 
  79   inline uint num_active_numa_ids() const;
  80 
  81   // Returns numa index of the given numa id.
  82   // Returns G1MemoryNodeManager::InvalidNodeIndex if the given numa id is invalid.
  83   inline uint index_of_numa_id(int numa_id) const;
  84 
  85   uint index_of_current_thread() const;
  86 
  87   // Returns numa id of the given numa index.
  88   inline int numa_id_of_index(uint numa_index) const;
  89 
  90   // Initialize with information after heap is created.
  91   // If AlwaysPreTouch is disabled _numa_id_of_regions_table is initialized.
  92   void set_page_size(size_t page_size);
  93 
  94   // Returns current active numa ids.
  95   const int* numa_ids() const { return _numa_ids; }
  96 
  97   // Returns the preferred index for the given address.
  98   // This assumes that HeapRegions are evenly spit, so we can decide preferred index
  99   // with the given address.
 100   uint preferred_index_for_address(HeapWord* address) const;
 101 
 102   // Returns numa index of the given address via system call.
 103   uint index_of_address(HeapWord* address) const;
 104 };
 105 
 106 #endif // SHARE_VM_GC_G1_G1NUMA_HPP