root/opal/mca/hwloc/hwloc201/hwloc/hwloc/topology-solaris-chiptype.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. assign_value
  2. assign_string_value
  3. search_table
  4. probe_cpu
  5. probe_picl
  6. hwloc_solaris_get_chip_info
  7. hwloc_solaris_get_chip_info

   1 /*
   2  * Copyright © 2009-2010 Oracle and/or its affiliates.  All rights reserved.
   3  * Copyright © 2013 Université Bordeaux.  All rights reserved.
   4  * Copyright © 2016-2017 Inria.  All rights reserved.
   5  *
   6  * $COPYRIGHT$
   7  *
   8  * Additional copyrights may follow
   9  *
  10  * $HEADER$
  11  */
  12 
  13 #include <private/autogen/config.h>
  14 #include <hwloc.h>
  15 #include <private/solaris-chiptype.h>
  16 #include <private/misc.h>
  17 #include <private/debug.h>
  18 
  19 #include <stdlib.h>
  20 #include <strings.h>
  21 
  22 #ifdef HAVE_PICL_H
  23 #include <sys/systeminfo.h>
  24 #include <picl.h>
  25 
  26 /* SPARC Chip Implementations. */
  27 #define IMPL_SPARC64_VI         0x6
  28 #define IMPL_SPARC64_VII        0x7
  29 #define IMPL_SPITFIRE           0x10
  30 #define IMPL_BLACKBIRD          0x11
  31 #define IMPL_SABRE              0x12
  32 #define IMPL_HUMMINGBIRD        0x13
  33 #define IMPL_CHEETAH            0x14
  34 #define IMPL_CHEETAHPLUS        0x15
  35 #define IMPL_JALAPENO           0x16
  36 #define IMPL_JAGUAR             0x18
  37 #define IMPL_PANTHER            0x19
  38 #define IMPL_NIAGARA            0x23
  39 #define IMPL_NIAGARA_2          0x24
  40 #define IMPL_ROCK               0x25
  41 
  42 /* Default Mfg, Cache, Speed settings */
  43 #define TI_MANUFACTURER         0x17
  44 #define TWO_MEG_CACHE           2097152
  45 #define SPITFIRE_SPEED          142943750
  46 
  47 /*****************************************************************************
  48    Order of this list is important for the assign_value and
  49    assign_string_value routines
  50 *****************************************************************************/
  51 
  52 static const char* items[] = {
  53 #define INDEX_PROCESSOR_TYPE 0
  54   "ProcessorType",
  55 #define INDEX_BRAND_STRING 1
  56   "brand-string",
  57 #define INDEX_COMPATIBLE 2
  58   "compatible",
  59 #define INDEX_IMPLEMENTATION 3
  60   "implementation#",
  61 
  62 /* the following groups must be contigous from L1I to L3 each */
  63 #define INDEX_L1I_CACHE_SIZE 4
  64   "l1-icache-size",
  65 #define INDEX_L1D_CACHE_SIZE 5
  66   "l1-dcache-size",
  67 #define INDEX_L2I_CACHE_SIZE 6
  68   "l2-icache-size",
  69 #define INDEX_L2D_CACHE_SIZE 7
  70   "l2-dcache-size",
  71 #define INDEX_L3_CACHE_SIZE 8
  72   "l3-cache-size",
  73 
  74 #define INDEX_L1I_CACHE_LINESIZE 9
  75   "l1-icache-line-size",
  76 #define INDEX_L1D_CACHE_LINESIZE 10
  77   "l1-dcache-line-size",
  78 #define INDEX_L2I_CACHE_LINESIZE 11
  79   "l2-icache-line-size",
  80 #define INDEX_L2D_CACHE_LINESIZE 12
  81   "l2-dcache-line-size",
  82 #define INDEX_L3_CACHE_LINESIZE 13
  83   "l3-cache-line-size",
  84 
  85 #define INDEX_L1I_CACHE_ASSOCIATIVITY 14
  86   "l1-icache-associativity",
  87 #define INDEX_L1D_CACHE_ASSOCIATIVITY 15
  88   "l1-dcache-associativity",
  89 #define INDEX_L2I_CACHE_ASSOCIATIVITY 16
  90   "l2-icache-associativity",
  91 #define INDEX_L2D_CACHE_ASSOCIATIVITY 17
  92   "l2-dcache-associativity",
  93 #define INDEX_L3_CACHE_ASSOCIATIVITY 18
  94   "l3-cache-associativity",
  95 
  96 #define INDEX_L2U_CACHE_SIZE 19
  97   "l2-cache-size",
  98 #define INDEX_L2U_CACHE_LINESIZE 20
  99   "l2-cache-line-size",
 100 #define INDEX_L2U_CACHE_ASSOCIATIVITY 21
 101   "l2-cache-associativity",
 102 
 103 #define INDEX_SL2_CACHE_SIZE 22
 104   "sectored-l2-cache-size",
 105 #define INDEX_SL2_CACHE_LINESIZE 23
 106   "sectored-l2-cache-line-size",
 107 #define INDEX_SL2_CACHE_ASSOCIATIVITY 24
 108   "sectored-l2-cache-associativity",
 109 };
 110 
 111 #define NUM_ITEMS (sizeof(items) / sizeof(items[0]))
 112 
 113 /*****************************************************************************
 114 SPARC strings for chip modes and implementation
 115 *****************************************************************************/
 116 static const char* sparc_modes[] = {
 117 #define MODE_UNKNOWN            0
 118     "UNKNOWN",
 119 #define MODE_SPITFIRE           1
 120     "SPITFIRE",
 121 #define MODE_BLACKBIRD          2
 122     "BLACKBIRD",
 123 #define MODE_CHEETAH            3
 124     "CHEETAH",
 125 #define MODE_SPARC64_VI         4
 126     "SPARC64_VI",
 127 #define MODE_T1                 5
 128     "T1",
 129 #define MODE_T2                 6
 130     "T2",
 131 /* needs T4, T3 and T2+ ? */
 132 #define MODE_SPARC64_VII        7
 133     "SPARC64_VII",
 134 #define MODE_ROCK               8
 135     "ROCK",
 136 #define MODE_T5                 9
 137     "T5",
 138 #define MODE_T6                 10
 139     "T6",
 140 #define MODE_M7                 11
 141     "M7",
 142 #define MODE_S7                 12
 143     "S7",
 144 #define MODE_M8                 13
 145     "M8"
 146 };
 147 
 148 /*****************************************************************************
 149 Default values are for Unknown so we can build up from there.
 150 *****************************************************************************/
 151 
 152 static int  called_cpu_probe      = 0;
 153 static char dss_chip_type[PICL_PROPNAMELEN_MAX];
 154 static char dss_chip_model[PICL_PROPNAMELEN_MAX];
 155 static long dss_chip_mode         = MODE_UNKNOWN;
 156 
 157 struct hwloc_solaris_chip_info_s chip_info;
 158 
 159 /*****************************************************************************
 160 Assigns values based on the value of index.  For this reason, the order of
 161 the items array is important.
 162 *****************************************************************************/
 163 static void assign_value(int index, long long val) {
 164   if (index == INDEX_IMPLEMENTATION) {
 165     /* implementation#  T1, T2, and Rock do not have this, see RFE 6615268 */
 166     long dss_chip_impl = val;
 167     if (dss_chip_impl == IMPL_SPITFIRE) {
 168       dss_chip_mode = MODE_SPITFIRE;
 169     }
 170     else if ((dss_chip_impl >= IMPL_BLACKBIRD) &&
 171              (dss_chip_impl <= IMPL_HUMMINGBIRD)) {
 172       dss_chip_mode = MODE_BLACKBIRD;
 173     }
 174     else if ((dss_chip_impl >= IMPL_CHEETAH) &&
 175              (dss_chip_impl <= IMPL_PANTHER)) {
 176       dss_chip_mode = MODE_CHEETAH;
 177     }
 178     else if (dss_chip_impl == IMPL_SPARC64_VI) {
 179       dss_chip_mode = MODE_SPARC64_VI;
 180     }
 181     else if (dss_chip_impl == IMPL_NIAGARA) {
 182       dss_chip_mode = MODE_T1;
 183     }
 184     else if (dss_chip_impl == IMPL_NIAGARA_2) {
 185       dss_chip_mode = MODE_T2;
 186     }
 187     else if (dss_chip_impl == IMPL_SPARC64_VII) {
 188       dss_chip_mode = MODE_SPARC64_VII;
 189     }
 190     else if (dss_chip_impl == IMPL_ROCK) {
 191       dss_chip_mode = MODE_ROCK;
 192     }
 193   }
 194 
 195   else if ((index >= INDEX_L1I_CACHE_SIZE) && (index <= INDEX_L3_CACHE_SIZE)) {
 196     /* make sure our indexes and the target structure are ordered the same */
 197     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_SIZE);
 198     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_SIZE);
 199     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_SIZE);
 200     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_SIZE);
 201     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L3  == INDEX_L3_CACHE_SIZE);
 202 
 203     chip_info.cache_size[index-INDEX_L1I_CACHE_SIZE] = val;
 204   }
 205   else if ((index >= INDEX_L1I_CACHE_LINESIZE) && (index <= INDEX_L3_CACHE_LINESIZE)) {
 206     /* make sure our indexes and the target structure are ordered the same */
 207     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_LINESIZE);
 208     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_LINESIZE);
 209     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_LINESIZE);
 210     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_LINESIZE);
 211     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L3  == INDEX_L3_CACHE_LINESIZE);
 212 
 213     chip_info.cache_linesize[index-INDEX_L1I_CACHE_LINESIZE] = val;
 214   }
 215   else if ((index >= INDEX_L1I_CACHE_ASSOCIATIVITY) && (index <= INDEX_L3_CACHE_ASSOCIATIVITY)) {
 216     /* make sure our indexes and the target structure are ordered the same */
 217     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_ASSOCIATIVITY);
 218     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_ASSOCIATIVITY);
 219     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_ASSOCIATIVITY);
 220     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_ASSOCIATIVITY);
 221     HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L3  == INDEX_L3_CACHE_ASSOCIATIVITY);
 222 
 223     chip_info.cache_associativity[index-INDEX_L1I_CACHE_ASSOCIATIVITY] = val;
 224   }
 225 
 226   /* store L2U info in L2D with l2_unified flag */
 227   else if (index == INDEX_L2U_CACHE_SIZE) {
 228     chip_info.cache_size[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
 229     chip_info.l2_unified = 1;
 230   }
 231   else if (index == INDEX_L2U_CACHE_LINESIZE) {
 232     chip_info.cache_linesize[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
 233     chip_info.l2_unified = 1;
 234   }
 235   else if (index == INDEX_L2U_CACHE_ASSOCIATIVITY) {
 236     chip_info.cache_associativity[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
 237     chip_info.l2_unified = 1;
 238   }
 239 
 240   /* assume sectored L2 is identical to L2u for size/linesize/associativity */
 241   else if (index == INDEX_SL2_CACHE_SIZE) {
 242     chip_info.cache_size[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
 243     chip_info.l2_unified = 1;
 244   }
 245   else if (index == INDEX_SL2_CACHE_LINESIZE) {
 246     chip_info.cache_linesize[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
 247     chip_info.l2_unified = 1;
 248   }
 249   else if (index == INDEX_SL2_CACHE_ASSOCIATIVITY) {
 250     chip_info.cache_associativity[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
 251     chip_info.l2_unified = 1;
 252   }
 253 }
 254 
 255 /*****************************************************************************
 256 Assigns values based on the value of index.  For this reason, the order of
 257 the items array is important.
 258 *****************************************************************************/
 259 static void assign_string_value(int index, char* string_val) {
 260   if (index == INDEX_COMPATIBLE) { /* compatible */
 261     if (strncasecmp(string_val, "FJSV,SPARC64-VI",
 262                     PICL_PROPNAMELEN_MAX) == 0) {
 263       dss_chip_mode = MODE_SPARC64_VI;
 264     }
 265     else if (strncasecmp(string_val, "SUNW,UltraSPARC-T1",
 266                          PICL_PROPNAMELEN_MAX) == 0) {
 267       dss_chip_mode = MODE_T1;
 268     }
 269     else if (strncasecmp(string_val, "SUNW,UltraSPARC-T2",
 270                          PICL_PROPNAMELEN_MAX) == 0) {
 271       dss_chip_mode = MODE_T2;
 272     }
 273     else if (strncasecmp(string_val, "FJSV,SPARC64-VII",
 274                          PICL_PROPNAMELEN_MAX) == 0) {
 275       dss_chip_mode = MODE_SPARC64_VII;
 276     }
 277     else if (strncasecmp(string_val, "SUNW,Rock",
 278                          PICL_PROPNAMELEN_MAX) == 0) {
 279       dss_chip_mode = MODE_ROCK;
 280     }
 281     else if (strncasecmp(string_val, "SPARC-T5",
 282                          PICL_PROPNAMELEN_MAX) == 0) {
 283       dss_chip_mode = MODE_T5;
 284     }
 285     else if (strncasecmp(string_val, "SPARC-T6", /* not actually tested */
 286                          PICL_PROPNAMELEN_MAX) == 0) {
 287       dss_chip_mode = MODE_T6;
 288     }
 289     else if (strncasecmp(string_val, "SPARC-M7",
 290                          PICL_PROPNAMELEN_MAX) == 0) {
 291       dss_chip_mode = MODE_M7;
 292     }
 293     else if (strncasecmp(string_val, "SPARC-S7",
 294                          PICL_PROPNAMELEN_MAX) == 0) {
 295       dss_chip_mode = MODE_S7;
 296     }
 297     else if (strncasecmp(string_val, "SPARC-M8",
 298                          PICL_PROPNAMELEN_MAX) == 0) {
 299       dss_chip_mode = MODE_M8;
 300     }
 301   } else if (index == INDEX_PROCESSOR_TYPE) {  /* ProcessorType */
 302       strncpy(&dss_chip_type[0], string_val, PICL_PROPNAMELEN_MAX);
 303   } else if (index == INDEX_BRAND_STRING) { /* brand-string */
 304       strncpy(&dss_chip_model[0], string_val, PICL_PROPNAMELEN_MAX);
 305   }
 306 }
 307 
 308 /*****************************************************************************
 309 Gets called by probe_cpu.  Cycles through the table values until we find
 310 what we are looking for.
 311 *****************************************************************************/
 312 static void search_table(int index, picl_prophdl_t table_hdl) {
 313 
 314   picl_prophdl_t  col_hdl;
 315   picl_prophdl_t  row_hdl;
 316   picl_propinfo_t p_info;
 317   int             val;
 318   char            string_val[PICL_PROPNAMELEN_MAX];
 319 
 320   for (val = picl_get_next_by_col(table_hdl, &row_hdl); val != PICL_ENDOFLIST;
 321        val = picl_get_next_by_col(row_hdl, &row_hdl)) {
 322     if (val == PICL_SUCCESS) {
 323       for (col_hdl = row_hdl; val != PICL_ENDOFLIST;
 324            val = picl_get_next_by_row(col_hdl, &col_hdl)) {
 325         if (val == PICL_SUCCESS) {
 326           val = picl_get_propinfo(col_hdl, &p_info);
 327           if (val == PICL_SUCCESS) {
 328             if (p_info.type == PICL_PTYPE_CHARSTRING) {
 329               val = picl_get_propval(col_hdl, &string_val, sizeof(string_val));
 330               if (val == PICL_SUCCESS) {
 331                 assign_string_value(index, string_val);
 332               }
 333             }
 334           }
 335         }
 336       }
 337     }
 338   }
 339 }
 340 
 341 /*****************************************************************************
 342 Gets called by picl_walk_tree_by_class.  Then it cycles through the properties
 343 until we find what we are looking for.  Once we are done, we return
 344 PICL_WALK_TERMINATE to stop picl_walk_tree_by_class from traversing the tree.
 345 
 346 Note that PICL_PTYPE_UNSIGNED_INT and PICL_PTYPE_INT can either be 4-bytes
 347 or 8-bytes.
 348 *****************************************************************************/
 349 static int probe_cpu(picl_nodehdl_t node_hdl, void* dummy_arg __hwloc_attribute_unused) {
 350 
 351   picl_prophdl_t  p_hdl;
 352   picl_prophdl_t  table_hdl;
 353   picl_propinfo_t p_info;
 354   long long       long_long_val;
 355   unsigned int    uint_val;
 356   unsigned int    index;
 357   int             int_val;
 358   int             val;
 359   char            string_val[PICL_PROPNAMELEN_MAX];
 360 
 361   val = picl_get_first_prop(node_hdl, &p_hdl);
 362   while (val == PICL_SUCCESS) {
 363     called_cpu_probe = 1;
 364     val = picl_get_propinfo(p_hdl, &p_info);
 365     if (val == PICL_SUCCESS) {
 366       for (index = 0; index < NUM_ITEMS; index++) {
 367         if (strcasecmp(p_info.name, items[index]) == 0) {
 368           if (p_info.type == PICL_PTYPE_UNSIGNED_INT) {
 369             if (p_info.size == sizeof(uint_val)) {
 370               val = picl_get_propval(p_hdl, &uint_val, sizeof(uint_val));
 371               if (val == PICL_SUCCESS) {
 372                 long_long_val = uint_val;
 373                 assign_value(index, long_long_val);
 374               }
 375             }
 376             else if (p_info.size == sizeof(long_long_val)) {
 377               val = picl_get_propval(p_hdl, &long_long_val,
 378                                      sizeof(long_long_val));
 379               if (val == PICL_SUCCESS) {
 380                 assign_value(index, long_long_val);
 381               }
 382             }
 383           }
 384           else if (p_info.type == PICL_PTYPE_INT) {
 385             if (p_info.size == sizeof(int_val)) {
 386               val = picl_get_propval(p_hdl, &int_val, sizeof(int_val));
 387               if (val == PICL_SUCCESS) {
 388                 long_long_val = int_val;
 389                 assign_value(index, long_long_val);
 390               }
 391             }
 392             else if (p_info.size == sizeof(long_long_val)) {
 393               val = picl_get_propval(p_hdl, &long_long_val,
 394                                      sizeof(long_long_val));
 395               if (val == PICL_SUCCESS) {
 396                 assign_value(index, long_long_val);
 397               }
 398             }
 399           }
 400           else if (p_info.type == PICL_PTYPE_CHARSTRING) {
 401             val = picl_get_propval(p_hdl, &string_val, sizeof(string_val));
 402             if (val == PICL_SUCCESS) {
 403               assign_string_value(index, string_val);
 404             }
 405           }
 406           else if (p_info.type == PICL_PTYPE_TABLE) {
 407             val = picl_get_propval(p_hdl, &table_hdl, p_info.size);
 408             if (val == PICL_SUCCESS) {
 409               search_table(index, table_hdl);
 410             }
 411           }
 412           break;
 413         }
 414       }
 415     }
 416 
 417     val = picl_get_next_prop(p_hdl, &p_hdl);
 418   }
 419   return PICL_WALK_TERMINATE;
 420 }
 421 
 422 
 423 /*****************************************************************************
 424 Initializes, gets the root, then walks the picl tree looking for information
 425 
 426 Currently, the "core" class is only needed for OPL systems
 427 *****************************************************************************/
 428 
 429 static void probe_picl(void)
 430 {
 431   char *env;
 432   int ret;
 433 
 434   memset(&chip_info, 0, sizeof(chip_info));
 435 
 436   /* if we ever see a heterogeneous platform, we'll need to parse PICL attributes for each CPU
 437    * (which means returning PICL_WALK_CONTINUE instead of PICL_WALK_TERMINATE above)
 438    * instead of using the first CPU PICL attributes for the entire machine.
 439    *
 440    * Use this env var to disable the PICL homogeneous-only parsing in the meantime.
 441    */
 442   env = getenv("HWLOC_PICL_HETEROGENEOUS");
 443   if (env && atoi(env))
 444     return;
 445 
 446   ret = picl_initialize();
 447   if (ret == PICL_SUCCESS) {
 448     picl_nodehdl_t root;
 449     ret = picl_get_root(&root);
 450     if (ret == PICL_SUCCESS) {
 451       ret = picl_walk_tree_by_class(root, "cpu", (void *)NULL, probe_cpu);
 452       ret = picl_walk_tree_by_class(root, "core", (void *)NULL, probe_cpu);
 453     }
 454     picl_shutdown();
 455   }
 456 
 457   if (called_cpu_probe) {
 458 #if (defined HWLOC_X86_64_ARCH) || (defined HWLOC_X86_32_ARCH)
 459     /* PICL returns some corrupted chip_type strings on x86,
 460      * and CPUType only used on Sparc anyway, at least for now.
 461      * So we just ignore this attribute on x86. */
 462     dss_chip_type[0] = '\0';
 463 #endif
 464     if (dss_chip_mode != MODE_UNKNOWN) { /* SPARC chip */
 465       strncpy(dss_chip_model, sparc_modes[dss_chip_mode],
 466               PICL_PROPNAMELEN_MAX);
 467     }
 468   } else {
 469     /* no picl information on machine available */
 470     sysinfo(SI_HW_PROVIDER, dss_chip_type, PICL_PROPNAMELEN_MAX);
 471     sysinfo(SI_PLATFORM, dss_chip_model, PICL_PROPNAMELEN_MAX);
 472   }
 473 
 474 #ifdef HWLOC_DEBUG
 475   {
 476     unsigned i;
 477     for(i=0; i<sizeof(chip_info.cache_size)/sizeof(*chip_info.cache_size); i++)
 478       hwloc_debug("PICL gave cache #%u size %lu line %u associativity %u\n",
 479                   i, chip_info.cache_size[i], chip_info.cache_linesize[i], chip_info.cache_associativity[i]);
 480   }
 481 #endif
 482 
 483   /* make sure strings are null-terminated */
 484   dss_chip_type[sizeof(dss_chip_type)-1] = '\0';
 485   dss_chip_model[sizeof(dss_chip_model)-1] = '\0';
 486 
 487   /* setup the info struct */
 488   if (dss_chip_type[0])
 489     chip_info.type = dss_chip_type;
 490   if (dss_chip_model[0])
 491     chip_info.model = dss_chip_model;
 492 }
 493 
 494 void hwloc_solaris_get_chip_info(struct hwloc_solaris_chip_info_s *info)
 495 {
 496   static int probe_done = 0;
 497   if (!probe_done) {
 498     probe_picl();
 499     probe_done = 1;
 500   }
 501 
 502   memcpy(info, &chip_info, sizeof(*info));
 503 }
 504 
 505 #else /* !HAVE_PICL_H */
 506 void hwloc_solaris_get_chip_info(struct hwloc_solaris_chip_info_s *info)
 507 {
 508   memset(info, 0, sizeof(*info));
 509 }
 510 #endif /* !HAVE_PICL_H */

/* [<][>][^][v][top][bottom][index][help] */