linux-libnuma.h

    00001 /*
    00002  * Copyright © 2009 CNRS
    00003  * Copyright © 2009-2010 INRIA.  All rights reserved.
    00004  * Copyright © 2009-2010 Université Bordeaux 1
    00005  * See COPYING in top-level directory.
    00006  */
    00007
    00024 #ifndef HWLOC_LINUX_LIBNUMA_H
    00025 #define HWLOC_LINUX_LIBNUMA_H
    00026
    00027 #include <hwloc.h>
    00028 #include <numa.h>
    00029
    00030
    00031 #ifdef __cplusplus
    00032 extern "C" {
    00033 #endif
    00034
    00035
    00051 static inline int
    00052 hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
    00053                                     unsigned long *mask, unsigned long *maxnode)
    00054 {
    00055   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00056   unsigned long outmaxnode = -1;
    00057
    00058   /* round-up to the next ulong and clear all bytes */
    00059   *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
    00060   memset(mask, 0, *maxnode/8);
    00061
    00062   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00063     hwloc_obj_t node = NULL;
    00064     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL) {
    00065       if (node->os_index >= *maxnode)
    00066         continue;
    00067       mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
    00068       if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
    00069         outmaxnode = node->os_index;
    00070     }
    00071
    00072   } else {
    00073     /* if no numa, libnuma assumes we have a single node */
    00074     if (!hwloc_bitmap_iszero(cpuset)) {
    00075       mask[0] = 1;
    00076       outmaxnode = 0;
    00077     }
    00078   }
    00079
    00080   *maxnode = outmaxnode+1;
    00081   return 0;
    00082 }
    00083
    00094 static inline int
    00095 hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
    00096                                       unsigned long *mask, unsigned long *maxnode)
    00097 {
    00098   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00099   unsigned long outmaxnode = -1;
    00100
    00101   /* round-up to the next ulong and clear all bytes */
    00102   *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
    00103   memset(mask, 0, *maxnode/8);
    00104
    00105   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00106     hwloc_obj_t node = NULL;
    00107     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL) {
    00108       if (node->os_index >= *maxnode)
    00109         continue;
    00110       if (!hwloc_bitmap_isset(nodeset, node->os_index))
    00111         continue;
    00112       mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
    00113       if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
    00114         outmaxnode = node->os_index;
    00115     }
    00116
    00117   } else {
    00118     /* if no numa, libnuma assumes we have a single node */
    00119     if (!hwloc_bitmap_iszero(nodeset)) {
    00120       mask[0] = 1;
    00121       outmaxnode = 0;
    00122     }
    00123   }
    00124
    00125   *maxnode = outmaxnode+1;
    00126   return 0;
    00127 }
    00128
    00138 static inline int
    00139 hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
    00140                                       const unsigned long *mask, unsigned long maxnode)
    00141 {
    00142   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00143
    00144   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00145     hwloc_obj_t node;
    00146     unsigned i;
    00147     hwloc_bitmap_zero(cpuset);
    00148     for(i=0; i<maxnode; i++)
    00149       if (mask[i/sizeof(*mask)/8] & (1UL << (i% (sizeof(*mask)*8)))) {
    00150         node = hwloc_get_obj_by_depth(topology, depth, i);
    00151         if (node)
    00152           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
    00153       }
    00154   } else {
    00155     /* if no numa, libnuma assumes we have a single node */
    00156     if (mask[0] & 1)
    00157       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
    00158     else
    00159       hwloc_bitmap_zero(cpuset);
    00160   }
    00161
    00162   return 0;
    00163 }
    00164
    00174 static inline int
    00175 hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
    00176                                         const unsigned long *mask, unsigned long maxnode)
    00177 {
    00178   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00179
    00180   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00181     hwloc_obj_t node;
    00182     unsigned i;
    00183     hwloc_bitmap_zero(nodeset);
    00184     for(i=0; i<maxnode; i++)
    00185       if (mask[i/sizeof(*mask)/8] & (1UL << (i% (sizeof(*mask)*8)))) {
    00186         node = hwloc_get_obj_by_depth(topology, depth, i);
    00187         if (node)
    00188           hwloc_bitmap_set(nodeset, node->os_index);
    00189       }
    00190   } else {
    00191     /* if no numa, libnuma assumes we have a single node */
    00192     if (mask[0] & 1)
    00193       hwloc_bitmap_fill(nodeset);
    00194     else
    00195       hwloc_bitmap_zero(nodeset);
    00196   }
    00197
    00198   return 0;
    00199 }
    00200
    00219 static inline struct bitmask *
    00220 hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)
    00221 {
    00222   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00223   struct bitmask *bitmask = numa_allocate_cpumask();
    00224   if (!bitmask)
    00225     return NULL;
    00226
    00227   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00228     hwloc_obj_t node = NULL;
    00229     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
    00230       numa_bitmask_setbit(bitmask, node->os_index);
    00231   } else {
    00232     /* if no numa, libnuma assumes we have a single node */
    00233     if (!hwloc_bitmap_iszero(cpuset))
    00234       numa_bitmask_setbit(bitmask, 0);
    00235   }
    00236
    00237   return bitmask;
    00238 }
    00239
    00249 static inline struct bitmask *
    00250 hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
    00251 {
    00252   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00253   struct bitmask *bitmask = numa_allocate_cpumask();
    00254   if (!bitmask)
    00255     return NULL;
    00256
    00257   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00258     hwloc_obj_t node = NULL;
    00259     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
    00260       if (hwloc_bitmap_isset(nodeset, node->os_index))
    00261         numa_bitmask_setbit(bitmask, node->os_index);
    00262   } else {
    00263     /* if no numa, libnuma assumes we have a single node */
    00264     if (!hwloc_bitmap_iszero(nodeset))
    00265       numa_bitmask_setbit(bitmask, 0);
    00266   }
    00267
    00268   return bitmask;
    00269 }
    00270
    00276 static inline int
    00277 hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
    00278                                         const struct bitmask *bitmask)
    00279 {
    00280   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00281
    00282   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00283     hwloc_obj_t node;
    00284     int i;
    00285     hwloc_bitmap_zero(cpuset);
    00286     for(i=0; i<NUMA_NUM_NODES; i++)
    00287       if (numa_bitmask_isbitset(bitmask, i)) {
    00288         node = hwloc_get_obj_by_depth(topology, depth, i);
    00289         if (node)
    00290           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
    00291       }
    00292   } else {
    00293     /* if no numa, libnuma assumes we have a single node */
    00294     if (numa_bitmask_isbitset(bitmask, 0))
    00295       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
    00296     else
    00297       hwloc_bitmap_zero(cpuset);
    00298   }
    00299
    00300   return 0;
    00301 }
    00302
    00308 static inline int
    00309 hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
    00310                                          const struct bitmask *bitmask)
    00311 {
    00312   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00313
    00314   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00315     hwloc_obj_t node;
    00316     int i;
    00317     hwloc_bitmap_zero(nodeset);
    00318     for(i=0; i<NUMA_NUM_NODES; i++)
    00319       if (numa_bitmask_isbitset(bitmask, i)) {
    00320         node = hwloc_get_obj_by_depth(topology, depth, i);
    00321         if (node)
    00322           hwloc_bitmap_set(nodeset, node->os_index);
    00323       }
    00324   } else {
    00325     /* if no numa, libnuma assumes we have a single node */
    00326     if (numa_bitmask_isbitset(bitmask, 0))
    00327       hwloc_bitmap_fill(nodeset);
    00328     else
    00329       hwloc_bitmap_zero(nodeset);
    00330   }
    00331
    00332   return 0;
    00333 }
    00334
    00339 #ifdef NUMA_VERSION1_COMPATIBILITY
    00340
    00350 static inline int
    00351 hwloc_cpuset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
    00352                                       nodemask_t *nodemask)
    00353 {
    00354   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00355
    00356   nodemask_zero(nodemask);
    00357
    00358   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00359     hwloc_obj_t node = NULL;
    00360     while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_NODE, node)) != NULL)
    00361       nodemask_set(nodemask, node->os_index);
    00362   } else {
    00363     /* if no numa, libnuma assumes we have a single node */
    00364     if (!hwloc_bitmap_iszero(cpuset))
    00365       nodemask_set(nodemask, 0);
    00366   }
    00367
    00368   return 0;
    00369 }
    00370
    00376 static inline int
    00377 hwloc_nodeset_to_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
    00378                                         nodemask_t *nodemask)
    00379 {
    00380   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00381
    00382   nodemask_zero(nodemask);
    00383
    00384   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00385     hwloc_obj_t node = NULL;
    00386     while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
    00387       if (hwloc_bitmap_isset(nodeset, node->os_index))
    00388         nodemask_set(nodemask, node->os_index);
    00389   } else {
    00390     /* if no numa, libnuma assumes we have a single node */
    00391     if (!hwloc_bitmap_iszero(nodeset))
    00392       nodemask_set(nodemask, 0);
    00393   }
    00394
    00395   return 0;
    00396 }
    00397
    00403 static inline int
    00404 hwloc_cpuset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
    00405                                         const nodemask_t *nodemask)
    00406 {
    00407   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00408
    00409   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00410     hwloc_obj_t node;
    00411     int i;
    00412     hwloc_bitmap_zero(cpuset);
    00413     for(i=0; i<NUMA_NUM_NODES; i++)
    00414       if (nodemask_isset(nodemask, i)) {
    00415         node = hwloc_get_obj_by_depth(topology, depth, i);
    00416         if (node)
    00417           hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
    00418       }
    00419   } else {
    00420     /* if no numa, libnuma assumes we have a single node */
    00421     if (nodemask_isset(nodemask, 0))
    00422       hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
    00423     else
    00424       hwloc_bitmap_zero(cpuset);
    00425   }
    00426
    00427   return 0;
    00428 }
    00429
    00435 static inline int
    00436 hwloc_nodeset_from_linux_libnuma_nodemask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
    00437                                           const nodemask_t *nodemask)
    00438 {
    00439   int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
    00440
    00441   if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
    00442     hwloc_obj_t node;
    00443     int i;
    00444     hwloc_bitmap_zero(nodeset);
    00445     for(i=0; i<NUMA_NUM_NODES; i++)
    00446       if (nodemask_isset(nodemask, i)) {
    00447         node = hwloc_get_obj_by_depth(topology, depth, i);
    00448         if (node)
    00449           hwloc_bitmap_set(nodeset, node->os_index);
    00450       }
    00451   } else {
    00452     /* if no numa, libnuma assumes we have a single node */
    00453     if (nodemask_isset(nodemask, 0))
    00454       hwloc_bitmap_fill(nodeset);
    00455     else
    00456       hwloc_bitmap_zero(nodeset);
    00457   }
    00458
    00459   return 0;
    00460 }
    00461
    00463 #endif /* NUMA_VERSION1_COMPATIBILITY */
    00464
    00465
    00466 #ifdef __cplusplus
    00467 } /* extern "C" */
    00468 #endif
    00469
    00470
    00471 #endif /* HWLOC_LINUX_NUMA_H */