Back to index

numactl  2.0.8~rc4
numa.h
Go to the documentation of this file.
00001 /* Copyright (C) 2003,2004 Andi Kleen, SuSE Labs.
00002 
00003    libnuma is free software; you can redistribute it and/or
00004    modify it under the terms of the GNU Lesser General Public
00005    License as published by the Free Software Foundation; version
00006    2.1.
00007 
00008    libnuma is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Lesser General Public License for more details.
00012 
00013    You should find a copy of v2.1 of the GNU Lesser General Public License
00014    somewhere on your Linux system; if not, write to the Free Software
00015    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
00016 
00017 #ifndef _NUMA_H
00018 #define _NUMA_H 1
00019 
00020 /* allow an application to test for the current programming interface: */
00021 #define LIBNUMA_API_VERSION 2
00022 
00023 /* Simple NUMA policy library */
00024 
00025 #include <stddef.h>
00026 #include <string.h>
00027 #include <sys/types.h>
00028 #include <stdlib.h>
00029 
00030 #if defined(__x86_64__) || defined(__i386__)
00031 #define NUMA_NUM_NODES  128
00032 #else
00033 #define NUMA_NUM_NODES  2048
00034 #endif
00035 
00036 #ifdef __cplusplus
00037 extern "C" {
00038 #endif
00039 
00040 typedef struct {
00041         unsigned long n[NUMA_NUM_NODES/(sizeof(unsigned long)*8)];
00042 } nodemask_t;
00043 
00044 struct bitmask {
00045        unsigned long size; /* number of bits in the map */
00046        unsigned long *maskp;
00047 };
00048 
00049 /* operations on struct bitmask */
00050 int numa_bitmask_isbitset(const struct bitmask *, unsigned int);
00051 struct bitmask *numa_bitmask_setall(struct bitmask *);
00052 struct bitmask *numa_bitmask_clearall(struct bitmask *);
00053 struct bitmask *numa_bitmask_setbit(struct bitmask *, unsigned int);
00054 struct bitmask *numa_bitmask_clearbit(struct bitmask *, unsigned int);
00055 unsigned int numa_bitmask_nbytes(struct bitmask *);
00056 struct bitmask *numa_bitmask_alloc(unsigned int);
00057 void numa_bitmask_free(struct bitmask *);
00058 int numa_bitmask_equal(const struct bitmask *, const struct bitmask *);
00059 void copy_nodemask_to_bitmask(nodemask_t *, struct bitmask *);
00060 void copy_bitmask_to_nodemask(struct bitmask *, nodemask_t *);
00061 void copy_bitmask_to_bitmask(struct bitmask *, struct bitmask *);
00062 
00063 /* compatibility for codes that used them: */
00064 
00065 static inline void nodemask_zero(nodemask_t *mask)
00066 {
00067        struct bitmask tmp;
00068 
00069        tmp.maskp = (unsigned long *)mask;
00070        tmp.size = sizeof(nodemask_t) * 8;
00071        numa_bitmask_clearall(&tmp);
00072 }
00073 
00074 static inline void nodemask_zero_compat(nodemask_t *mask)
00075 {
00076        struct bitmask tmp;
00077 
00078        tmp.maskp = (unsigned long *)mask;
00079        tmp.size = sizeof(nodemask_t) * 8;
00080        numa_bitmask_clearall(&tmp);
00081 }
00082 
00083 static inline void nodemask_set_compat(nodemask_t *mask, int node)
00084 {
00085        mask->n[node / (8*sizeof(unsigned long))] |=
00086               (1UL<<(node%(8*sizeof(unsigned long))));
00087 }
00088 
00089 static inline void nodemask_clr_compat(nodemask_t *mask, int node)
00090 {
00091        mask->n[node / (8*sizeof(unsigned long))] &=
00092               ~(1UL<<(node%(8*sizeof(unsigned long))));
00093 }
00094 
00095 static inline int nodemask_isset_compat(const nodemask_t *mask, int node)
00096 {
00097        if ((unsigned)node >= NUMA_NUM_NODES)
00098               return 0;
00099        if (mask->n[node / (8*sizeof(unsigned long))] &
00100               (1UL<<(node%(8*sizeof(unsigned long)))))
00101               return 1;
00102        return 0;
00103 }
00104 
00105 static inline int nodemask_equal(const nodemask_t *a, const nodemask_t *b)
00106 {
00107        struct bitmask tmp_a, tmp_b;
00108 
00109        tmp_a.maskp = (unsigned long *)a;
00110        tmp_a.size = sizeof(nodemask_t) * 8;
00111 
00112        tmp_b.maskp = (unsigned long *)b;
00113        tmp_b.size = sizeof(nodemask_t) * 8;
00114 
00115        return numa_bitmask_equal(&tmp_a, &tmp_b);
00116 }
00117 
00118 static inline int nodemask_equal_compat(const nodemask_t *a, const nodemask_t *b)
00119 {
00120        struct bitmask tmp_a, tmp_b;
00121 
00122        tmp_a.maskp = (unsigned long *)a;
00123        tmp_a.size = sizeof(nodemask_t) * 8;
00124 
00125        tmp_b.maskp = (unsigned long *)b;
00126        tmp_b.size = sizeof(nodemask_t) * 8;
00127 
00128        return numa_bitmask_equal(&tmp_a, &tmp_b);
00129 }
00130 
00131 /* NUMA support available. If this returns a negative value all other function
00132    in this library are undefined. */
00133 int numa_available(void);
00134 
00135 /* Basic NUMA state */
00136 
00137 /* Get max available node */
00138 int numa_max_node(void);
00139 int numa_max_possible_node(void);
00140 /* Return preferred node */
00141 int numa_preferred(void);
00142 
00143 /* Return node size and free memory */
00144 long long numa_node_size64(int node, long long *freep);
00145 long numa_node_size(int node, long *freep);
00146 
00147 int numa_pagesize(void);
00148 
00149 /* Set with all nodes from which the calling process may allocate memory.
00150    Only valid after numa_available. */
00151 extern struct bitmask *numa_all_nodes_ptr;
00152 
00153 /* Set with all nodes the kernel has exposed to userspace */
00154 extern struct bitmask *numa_nodes_ptr;
00155 
00156 /* For source compatibility */
00157 extern nodemask_t numa_all_nodes;
00158 
00159 /* Set with all cpus. */
00160 extern struct bitmask *numa_all_cpus_ptr;
00161 
00162 /* Set with no nodes */
00163 extern struct bitmask *numa_no_nodes_ptr;
00164 
00165 /* Source compatibility */
00166 extern nodemask_t numa_no_nodes;
00167 
00168 /* Only run and allocate memory from a specific set of nodes. */
00169 void numa_bind(struct bitmask *nodes);
00170 
00171 /* Set the NUMA node interleaving mask. 0 to turn off interleaving */
00172 void numa_set_interleave_mask(struct bitmask *nodemask);
00173 
00174 /* Return the current interleaving mask */
00175 struct bitmask *numa_get_interleave_mask(void);
00176 
00177 /* allocate a bitmask big enough for all nodes */
00178 struct bitmask *numa_allocate_nodemask(void);
00179 
00180 static inline void numa_free_nodemask(struct bitmask *b)
00181 {
00182        numa_bitmask_free(b);
00183 }
00184 
00185 /* Some node to preferably allocate memory from for task. */
00186 void numa_set_preferred(int node);
00187 
00188 /* Set local memory allocation policy for task */
00189 void numa_set_localalloc(void);
00190 
00191 /* Only allocate memory from the nodes set in mask. 0 to turn off */
00192 void numa_set_membind(struct bitmask *nodemask);
00193 
00194 /* Return current membind */
00195 struct bitmask *numa_get_membind(void);
00196 
00197 /* Return allowed memories [nodes] */
00198 struct bitmask *numa_get_mems_allowed(void);
00199 
00200 int numa_get_interleave_node(void);
00201 
00202 /* NUMA memory allocation. These functions always round to page size
00203    and are relatively slow. */
00204 
00205 /* Alloc memory page interleaved on nodes in mask */
00206 void *numa_alloc_interleaved_subset(size_t size, struct bitmask *nodemask);
00207 /* Alloc memory page interleaved on all nodes. */
00208 void *numa_alloc_interleaved(size_t size);
00209 /* Alloc memory located on node */
00210 void *numa_alloc_onnode(size_t size, int node);
00211 /* Alloc memory on local node */
00212 void *numa_alloc_local(size_t size);
00213 /* Allocation with current policy */
00214 void *numa_alloc(size_t size);
00215 /* Change the size of a memory area preserving the memory policy */
00216 void *numa_realloc(void *old_addr, size_t old_size, size_t new_size);
00217 /* Free memory allocated by the functions above */
00218 void numa_free(void *mem, size_t size);
00219 
00220 /* Low level functions, primarily for shared memory. All memory
00221    processed by these must not be touched yet */
00222 
00223 /* Interleave an memory area. */
00224 void numa_interleave_memory(void *mem, size_t size, struct bitmask *mask);
00225 
00226 /* Allocate a memory area on a specific node. */
00227 void numa_tonode_memory(void *start, size_t size, int node);
00228 
00229 /* Allocate memory on a mask of nodes. */
00230 void numa_tonodemask_memory(void *mem, size_t size, struct bitmask *mask);
00231 
00232 /* Allocate a memory area on the current node. */
00233 void numa_setlocal_memory(void *start, size_t size);
00234 
00235 /* Allocate memory area with current memory policy */
00236 void numa_police_memory(void *start, size_t size);
00237 
00238 /* Run current task only on nodes in mask */
00239 int numa_run_on_node_mask(struct bitmask *mask);
00240 /* Run current task only on node */
00241 int numa_run_on_node(int node);
00242 /* Return current mask of nodes the task can run on */
00243 struct bitmask * numa_get_run_node_mask(void);
00244 
00245 /* When strict fail allocation when memory cannot be allocated in target node(s). */
00246 void numa_set_bind_policy(int strict);
00247 
00248 /* Fail when existing memory has incompatible policy */
00249 void numa_set_strict(int flag);
00250 
00251 /* maximum nodes (size of kernel nodemask_t) */
00252 int numa_num_possible_nodes();
00253 
00254 /* maximum cpus (size of kernel cpumask_t) */
00255 int numa_num_possible_cpus();
00256 
00257 /* nodes in the system */
00258 int numa_num_configured_nodes();
00259 
00260 /* maximum cpus */
00261 int numa_num_configured_cpus();
00262 
00263 /* maximum cpus allowed to current task */
00264 int numa_num_task_cpus();
00265 int numa_num_thread_cpus(); /* backward compatibility */
00266 
00267 /* maximum nodes allowed to current task */
00268 int numa_num_task_nodes();
00269 int numa_num_thread_nodes(); /* backward compatibility */
00270 
00271 /* allocate a bitmask the size of the kernel cpumask_t */
00272 struct bitmask *numa_allocate_cpumask();
00273 
00274 static inline void numa_free_cpumask(struct bitmask *b)
00275 {
00276        numa_bitmask_free(b);
00277 }
00278 
00279 /* Convert node to CPU mask. -1/errno on failure, otherwise 0. */
00280 int numa_node_to_cpus(int, struct bitmask *);
00281 
00282 /* report the node of the specified cpu. -1/errno on invalid cpu. */
00283 int numa_node_of_cpu(int cpu);
00284 
00285 /* Report distance of node1 from node2. 0 on error.*/
00286 int numa_distance(int node1, int node2);
00287 
00288 /* Error handling. */
00289 /* This is an internal function in libnuma that can be overwritten by an user
00290    program. Default is to print an error to stderr and exit if numa_exit_on_error
00291    is true. */
00292 void numa_error(char *where);
00293 
00294 /* When true exit the program when a NUMA system call (except numa_available)
00295    fails */
00296 extern int numa_exit_on_error;
00297 /* Warning function. Can also be overwritten. Default is to print on stderr
00298    once. */
00299 void numa_warn(int num, char *fmt, ...);
00300 
00301 /* When true exit the program on a numa_warn() call */
00302 extern int numa_exit_on_warn;
00303 
00304 int numa_migrate_pages(int pid, struct bitmask *from, struct bitmask *to);
00305 
00306 int numa_move_pages(int pid, unsigned long count, void **pages,
00307               const int *nodes, int *status, int flags);
00308 
00309 int numa_sched_getaffinity(pid_t, struct bitmask *);
00310 int numa_sched_setaffinity(pid_t, struct bitmask *);
00311 
00312 /* Convert an ascii list of nodes to a bitmask */
00313 struct bitmask *numa_parse_nodestring(char *);
00314 
00315 /* Convert an ascii list of cpu to a bitmask */
00316 struct bitmask *numa_parse_cpustring(char *);
00317 
00318 /*
00319  * The following functions are for source code compatibility
00320  * with releases prior to version 2.
00321  * Such codes should be compiled with NUMA_VERSION1_COMPATIBILITY defined.
00322  */
00323 
00324 static inline void numa_set_interleave_mask_compat(nodemask_t *nodemask)
00325 {
00326        struct bitmask tmp;
00327 
00328        tmp.maskp = (unsigned long *)nodemask;
00329        tmp.size = sizeof(nodemask_t) * 8;
00330        numa_set_interleave_mask(&tmp);
00331 }
00332 
00333 static inline nodemask_t numa_get_interleave_mask_compat()
00334 {
00335        struct bitmask *tp;
00336        nodemask_t mask;
00337 
00338        tp = numa_get_interleave_mask();
00339        copy_bitmask_to_nodemask(tp, &mask);
00340        numa_bitmask_free(tp);
00341        return mask;
00342 }
00343 
00344 static inline void numa_bind_compat(nodemask_t *mask)
00345 {
00346        struct bitmask *tp;
00347 
00348        tp = numa_allocate_nodemask();
00349        copy_nodemask_to_bitmask(mask, tp);
00350        numa_bind(tp);
00351        numa_bitmask_free(tp);
00352 }
00353 
00354 static inline void numa_set_membind_compat(nodemask_t *mask)
00355 {
00356        struct bitmask tmp;
00357 
00358        tmp.maskp = (unsigned long *)mask;
00359        tmp.size = sizeof(nodemask_t) * 8;
00360        numa_set_membind(&tmp);
00361 }
00362 
00363 static inline nodemask_t numa_get_membind_compat()
00364 {
00365        struct bitmask *tp;
00366        nodemask_t mask;
00367 
00368        tp = numa_get_membind();
00369        copy_bitmask_to_nodemask(tp, &mask);
00370        numa_bitmask_free(tp);
00371        return mask;
00372 }
00373 
00374 static inline void *numa_alloc_interleaved_subset_compat(size_t size,
00375                                    const nodemask_t *mask)
00376 {
00377        struct bitmask tmp;
00378 
00379        tmp.maskp = (unsigned long *)mask;
00380        tmp.size = sizeof(nodemask_t) * 8;
00381        return numa_alloc_interleaved_subset(size, &tmp);
00382 }
00383 
00384 static inline int numa_run_on_node_mask_compat(const nodemask_t *mask)
00385 {
00386        struct bitmask tmp;
00387 
00388        tmp.maskp = (unsigned long *)mask;
00389        tmp.size = sizeof(nodemask_t) * 8;
00390        return numa_run_on_node_mask(&tmp);
00391 }
00392 
00393 static inline nodemask_t numa_get_run_node_mask_compat()
00394 {
00395        struct bitmask *tp;
00396        nodemask_t mask;
00397 
00398        tp = numa_get_run_node_mask();
00399        copy_bitmask_to_nodemask(tp, &mask);
00400        numa_bitmask_free(tp);
00401        return mask;
00402 }
00403 
00404 static inline void numa_interleave_memory_compat(void *mem, size_t size,
00405                                           const nodemask_t *mask)
00406 {
00407        struct bitmask tmp;
00408 
00409        tmp.maskp = (unsigned long *)mask;
00410        tmp.size = sizeof(nodemask_t) * 8;
00411        numa_interleave_memory(mem, size, &tmp);
00412 }
00413 
00414 static inline void numa_tonodemask_memory_compat(void *mem, size_t size,
00415                                           const nodemask_t *mask)
00416 {
00417        struct bitmask tmp;
00418 
00419        tmp.maskp = (unsigned long *)mask;
00420        tmp.size = sizeof(nodemask_t) * 8;
00421        numa_tonodemask_memory(mem, size, &tmp);
00422 }
00423 
00424 static inline int numa_sched_getaffinity_compat(pid_t pid, unsigned len,
00425                                           unsigned long *mask)
00426 {
00427        struct bitmask tmp;
00428 
00429        tmp.maskp = (unsigned long *)mask;
00430        tmp.size = len * 8;
00431        return numa_sched_getaffinity(pid, &tmp);
00432 }
00433 
00434 static inline int numa_sched_setaffinity_compat(pid_t pid, unsigned len,
00435                                           unsigned long *mask)
00436 {
00437        struct bitmask tmp;
00438 
00439        tmp.maskp = (unsigned long *)mask;
00440        tmp.size = len * 8;
00441        return numa_sched_setaffinity(pid, &tmp);
00442 }
00443 
00444 static inline int numa_node_to_cpus_compat(int node, unsigned long *buffer,
00445                                                  int buffer_len)
00446 {
00447        struct bitmask tmp;
00448 
00449        tmp.maskp = (unsigned long *)buffer;
00450        tmp.size = buffer_len * 8;
00451        return numa_node_to_cpus(node, &tmp);
00452 }
00453 
00454 /* end of version 1 compatibility functions */
00455 
00456 /*
00457  * To compile an application that uses libnuma version 1:
00458  *   add -DNUMA_VERSION1_COMPATIBILITY to your Makefile's CFLAGS
00459  */
00460 #ifdef NUMA_VERSION1_COMPATIBILITY
00461 #include <numacompat1.h>
00462 #endif
00463 
00464 #ifdef __cplusplus
00465 }
00466 #endif
00467 
00468 #endif