src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed Sep  3 01:57:03 2014
--- new/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed Sep  3 01:57:03 2014

*** 26,39 **** --- 26,128 ---- #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "runtime/os.hpp" #include "vm_version_sparc.hpp" - # include <sys/auxv.h> - # include <sys/auxv_SPARC.h> - # include <sys/systeminfo.h> - # include <kstat.h> + #include <picl.h> + + extern "C" static int PICL_cpu_visitor_helper(picl_nodehdl_t nodeh, void *result); + + class PICL { + // Get a value of the integer property. The value in the tree can be either 32 or 64 bit + // depending on the platform. The result is converted to int. + static int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) { + picl_propinfo_t pinfo; + picl_prophdl_t proph; + if (picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS || + picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) { + return PICL_FAILURE; + } + + if (pinfo.type != PICL_PTYPE_INT) { + assert(false, "Invalid property type"); + return PICL_FAILURE; + } + if (pinfo.size == sizeof(int64_t)) { + int64_t val; + if (picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) { + return PICL_FAILURE; + } + *result = static_cast<int>(val); + } else if (pinfo.size == sizeof(int32_t)) { + int32_t val; + if (picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) { + return PICL_FAILURE; + } + *result = static_cast<int>(val); + } else { + assert(false, "Unexpected integer property size"); + return PICL_FAILURE; + } + return PICL_SUCCESS; + } + + // For every visited node make sure the specified property exists and has the same value + static int get_int_property_and_ensure_consistency(picl_nodehdl_t nodeh, const char* name, void *result) { + int *prev = static_cast<int*>(result); + int curr; + if (*prev >= 0) { // are still interested in walking? + if (get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { + if (*prev == 0) { // first + *prev = curr; + return PICL_WALK_CONTINUE; + } else if (curr == *prev) { // others + return PICL_WALK_CONTINUE; + } + } + *prev = -1; + } + return PICL_WALK_TERMINATE; + } + + int _L1_data_cache_line_size; + int _L2_cache_line_size; + + public: + static int cpu_visitor(picl_nodehdl_t nodeh, void *result) + { + PICL *picl = static_cast<PICL*>(result); + int r1 = get_int_property_and_ensure_consistency(nodeh, "l2-cache-line-size", &(picl->_L2_cache_line_size)); + int r2 = get_int_property_and_ensure_consistency(nodeh, "l1-dcache-line-size", &(picl->_L1_data_cache_line_size)); + if (r1 == PICL_WALK_TERMINATE && r2 == PICL_WALK_TERMINATE) { + return PICL_WALK_TERMINATE; + } + return PICL_WALK_CONTINUE; + } + + PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0) { + if (picl_initialize() == PICL_SUCCESS) { + picl_nodehdl_t rooth; + if (picl_get_root(&rooth) == PICL_SUCCESS) { + // Visit all CPUs + picl_walk_tree_by_class(rooth, "cpu", this, PICL_cpu_visitor_helper); + } + picl_shutdown(); + } + } + + unsigned int L1_data_cache_line_size() const { return MAX2(0, _L1_data_cache_line_size); } + unsigned int L2_cache_line_size() const { return MAX2(0, _L2_cache_line_size); } + }; + + extern "C" static int PICL_cpu_visitor_helper(picl_nodehdl_t nodeh, void *result) { + return PICL::cpu_visitor(nodeh, result); + } // We need to keep these here as long as we have to build on Solaris // versions before 10. #ifndef SI_ARCHITECTURE_32 #define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */
*** 209,215 **** --- 298,309 ---- assert(strcmp(implementation, "UNKNOWN") != 0, "unknown cpu info (changed kstat interface?)"); kstat_close(kc); } + // Figure out cache line sizes using PICL + PICL picl; + _L1_data_cache_line_size = picl.L1_data_cache_line_size(); + _L2_cache_line_size = picl.L2_cache_line_size(); + return features; }

src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File