libnuma: adding interface specification numa.h
authorReto Achermann <reto.achermann@inf.ethz.ch>
Fri, 12 Dec 2014 10:31:15 +0000 (11:31 +0100)
committerReto Achermann <reto.achermann@inf.ethz.ch>
Fri, 12 Dec 2014 10:31:15 +0000 (11:31 +0100)
adding the a ported version of libnuma's header to the include directory

Specified NUMA_ERR related error codes in errno.fugu

errors/errno.fugu
include/numa.h [new file with mode: 0644]

index 3054826..452f08d 100755 (executable)
@@ -1076,21 +1076,6 @@ errors xeon_phi XEON_PHI_ERR_ {
     failure CLIENT_REGISTER      "Xeon Phi client could not be registered with the driver",
     failure CLIENT_BUSY          "The connection to the Xeon Phi driver is busy",
     failure INVALID_ID           "Supplied Xeon Phi ID is invalid",
-    
-    
- //   failure DMA_NOT_INITIALIZED  "DMA library has not been initialized",
- //   failure DMA_NUM_DESC         "Descriptor number must be a power of two",
- //   failure DMA_ID_NOT_EXISTS    "The DMA transfer with that ID does not exist ",
- //   failure DMA_NOT_SUPPORTED    "The DMA transfer is not supported.",
- //   failure DMA_BUSY             "All DMA channels are busy",
- //   failure DMA_IDLE             "All DMA channels are idle",
- //  failure DMA_MEM_REGISTERED   "The memory has not been registered",
- //   failure DMA_MEM_ALIGN        "The address / bytes has a wrong alignment",
- //   failure DMA_MEM_OVERLAP      "The memory addresses overlap",
- //   failure DMA_RPC_IN_PROGRESS  "There is currently an RPC going on",
- //   failure DMA_NO_DESC          "There are not enough DMA descriptors left",
- //   failure DMA_REQ_SIZE         "The requested transfer size is too big",
- //   failure DMA_MEM_OUT_OF_RANGE "The physical address is out of range",
 };
 
 errors dma DMA_ERR_ {
@@ -1131,3 +1116,10 @@ errors xomp XOMP_ERR_ {
     failure INVALID_TOKEN         "the token was invalid",
     failure INVALID_ARGUMENTS     "the library was initialized with invalid args",
 };
+
+errors numa NUMA_ERR_ {
+    failure NOT_AVAILABLE         "NUMA functionality is not available",
+    failure BITMAP_PARSE          "Parsing of the bitmap character string failed",
+    failure BITMAP_RANGE          "The bitmap is too small to hold the data",
+    failure NUMA_MEMBIND          "Setting the memory binding failed",
+};
diff --git a/include/numa.h b/include/numa.h
new file mode 100644 (file)
index 0000000..fcf2337
--- /dev/null
@@ -0,0 +1,752 @@
+/**
+ * \file
+ * \brief header specifying the interface of libnuma
+ *
+ * This is derived from:
+ *
+ * Linux man pages "numa"
+ * libnuma from http://oss.sgi.com/projects/libnuma/
+ *
+ */
+
+/*
+ * Copyright (c) 2014, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich.
+ * Attn: Systems Group.
+ */
+
+#ifndef __NUMA_H
+#define __NUMA_H 1
+
+///< typedef for the NUMA node IDs
+typedef coreid_t nodeid_t;
+
+///< the maximum number of nodes supported
+#define NUMA_MAX_NUMNODES 256
+
+///< specify the local node for allocation
+#define NUMA_NODE_LOCAL ((nodeid_t)-1)
+
+///< error value for the numa node size
+#define NUMA_NODE_INVALID ((uintptr_t)-1)
+
+typedef enum numa_policy {
+    NUMA_POLICY_DEFAULT,  ///< default numa policy
+    NUMA_POLICY_STRICT   ///< strict numa policy
+} numa_policy_t;
+
+struct numa_bm {
+
+};
+
+/**
+ * \brief checks if numa support is available
+ *
+ * \returns NUMA_ERR_NOT_AVAILABLE  value all other functions are undefined
+ *          SYS_ERR_OK:             NUMA functionality is available
+ *
+ * this function must be called before any of the other functions of libnuma.
+ * during the call to numa_available the library also gets initialized
+ */
+errval_t numa_available(void);
+
+/**
+ * \brief returns the highest node number available on the current system.
+ *
+ * \returns ID of the max NUMA node
+ */
+nodeid_t numa_max_node(void);
+
+/**
+ * \brief returns the highest ID of the present cores
+ *
+ * \returns the maximum number of cores in the system
+ */
+coreid_t numa_max_cores(void);
+
+/**
+ * \brief returns the current node the domain is running on
+ *
+ * \return ID of the current node
+ */
+nodeid_t numa_current_node();
+
+/**
+ * \brief Obtains the maximum number of nodes the system can handle
+ *
+ * \return maximum nodes supported
+ *
+ * returns the number of the highest possible node in a system. In other words,
+ * the size of a kernel type nodemask_t (in bits) minus 1
+ */
+static inline nodeid_t numa_max_possible_node(void)
+{
+    return numa_num_possible_nodes() - 1;
+}
+
+/**
+ * \brief returns the size of the node mask
+ *
+ * \return size of the node mask
+ */
+nodeid_t numa_num_possible_nodes();
+
+/**
+ * \brief Obtains the number of all memory nodes in the system
+ *
+ * \return number of memory nodes in the system
+ *
+ * returns the number of memory nodes in the system. This count includes any nodes
+ * that are currently disabled.
+ */
+nodeid_t numa_num_configured_nodes(void);
+
+/**
+ * \brief obtains the nodes the domain is allowed to allocate memory from
+ *
+ * \returns bitmask representing the allowing nodes
+ *
+ * returns the mask of nodes from which the process is allowed to allocate memory
+ * in it's current cpuset context.
+ */
+struct numa_bm *numa_get_mems_allowed(void);
+
+/**
+ * \brief returns the total numberof CPUs in the system
+ *
+ * \returns total number of CPUs in the system
+ *
+ * returns the number of cpus in the system. This count includes any cpus that are
+ * currently disabled.
+ */
+coreid_t numa_num_configured_cpus(void);
+
+/**
+ * \brief bitmask that is allocated by the library with bits representing all nodes
+ *        on which the calling task may allocate memory.
+ */
+extern struct numa_bm *numa_all_nodes_ptr;
+
+/**
+ * \brief points to a bitmask that is allocated by the library and left all zeroes.
+ */
+extern struct numa_bm *numa_no_nodes_ptr;
+
+/**
+ * \brief points to a bitmask that is allocated by the library with bits
+ *        representing all cpus on which the calling task may execute.
+ */
+extern struct numa_bm *numa_all_cpus_ptr;
+
+/**
+ * \brief returns the number of cpus that the calling domain is allowed to use.
+ *
+ * \returns number of CPUs the domain is allowed to use
+ */
+coreid_t numa_num_task_cpus();
+
+/**
+ * \brief returns the number of nodes on which the calling domain is allowed to
+ *        allocate memory
+ *
+ * \returns number of nodes the domain is allowed to use
+ */
+nodeid_t numa_num_task_nodes();
+
+/**
+ * \brief parses line , which is a character string
+ *
+ * \param line  character string to parse
+ * \param mask  bitmap to store the result
+ *
+ * \returns SYS_ERR_OK            on SUCCESS
+ *          NUMA_ERR_BITMAP_PARSE on FAILURE
+ *
+ * The string contains the hexadecimal representation of a bit map.
+ *
+ * XXX according to the man pages this function is only used internally
+ */
+errval_t numa_parse_bitmap(char *line, struct numa_bm *mask);
+
+/**
+ * \brief parses a character string list of nodes into a bit mask.
+ *
+ * \param string character string to parse
+ *
+ * \returns NUMA bitmask on SUCCESS
+ *          NULL if the string is invalid
+ *
+ * The string is a comma-separated list of node numbers or node ranges
+ * Examples: 1-5,7,10 !4-5 +0-3
+ *
+ * If the string length is zero, then the numa_no_nodes_ptr is returned
+ */
+struct numa_bm *numa_parse_nodestring(char *string);
+
+/**
+ * \brief parses a character string list of cpus into a bit mask.
+ *
+ * \param string character string to parse
+ *
+ * \returns NUMA bitmask on SUCCESS
+ *          NULL if the string is invalid
+ *
+ * The string is a comma-separated list of cpu numbers or cpu ranges
+ * Examples: 1-5,7,10 !4-5 +0-3
+ */
+struct numa_bm *numa_parse_cpustring(char *string);
+
+/**
+ * \brief obtains the size of a node
+ *
+ * \param node  ID of the NUMA node
+ * \param freep
+ *
+ * \returns size of the node in bytes
+ *
+ * returns the memory size of a node. If the argument freep is not NULL, it used
+ * to return the amount of free memory on the node. On error it returns
+ * NUMA_NODE_INVALID
+ */
+size_t numa_node_size(nodeid_t node, uintptr_t *freep);
+
+///< alias for NUMA node size 64bit variants
+#define numa_node_size64(_node, _freep) numa_node_size(_node, _freep)
+
+/**
+ * \brief obtains the base address of the numa node
+ *
+ * \returns physical address of the start of the numa node
+ */
+lpaddr_t numa_node_base(nodeid_t node);
+
+/**
+ * \brief returns the preferred node of the current task.
+ *
+ * \returns node ID where memory is preferably allocated
+ */
+nodeid_t numa_preferred(void);
+
+/**
+ * \brief  sets the preferred node for the current task to node
+ *
+ * \param node  ID of the node to set preferred
+ *
+ * The system will attempt to allocate memory from the preferred node, but will
+ * fall back to other nodes if no memory is available on the the preferred node
+ *
+ * Passing a node of -1 argument specifies local allocation
+ */
+void numa_set_preferred(nodeid_t node);
+
+/**
+ * \brief   returns the current interleave mask
+ *
+ * \returns bitmask representing the current interleave state
+ *
+ * returns the current interleave mask if the task's memory allocation policy is
+ * page interleaved. Otherwise, this function returns an empty mask.
+ */
+struct numa_bm *numa_get_interleave_mask(void);
+
+/**
+ * \brief sets the memory interleave mask for the current task to nodemask
+ *
+ * \param nodemask bitmask representing the nodes
+ *
+ * All new memory allocations are page interleaved over all nodes in the interleave
+ * mask. Interleaving can be turned off again by passing an empty mask.
+ *
+ * This bitmask is considered to be a hint. Fallback to other nodes may be possible
+ */
+void numa_set_interleave_mask(struct numa_bm *nodemask);
+
+/**
+ * \brief binds the current task and its children to the nodes specified in nodemask.
+ *
+ * \param nodemask  bitmap representing the nodes
+ */
+void numa_bind(struct numa_bm *nodemask);
+
+/**
+ * \brief sets the memory allocation policy for the calling task to local allocation.
+ */
+void numa_set_localalloc(void);
+
+/**
+ * \brief sets the memory allocation mask.
+ *
+ * \param nodemask  bitmap representing the nodes
+ *
+ * The task will only allocate memory from the nodes set in nodemask.
+ *
+ * an empty mask or not allowed nodes in the mask will result in an error
+ */
+errval_t numa_set_membind(struct numa_bm *nodemask);
+
+/**
+ * \brief returns the mask of nodes from which memory can currently be allocated.
+ *
+ * \return bitmap of nodes from which can be allocated
+ */
+struct numa_bm *numa_get_membind(void);
+
+/**
+ * \brief allocates memory on a specific node.
+ *
+ * \param size  size of the region in bytes
+ * \param node  ID of the node to allocate from
+ *
+ * \returns pointer to memory region
+ *
+ * The size argument will be rounded up to a multiple of the system page size.
+ * if the specified node is externally denied to this process, this call will fail.
+ * The memory must be freed with numa_free(). On errors NULL is returned.
+ */
+void *numa_alloc_onnode(size_t size, nodeid_t node);
+
+/**
+ * \brief allocates size bytes of memory on the local node
+ *
+ * \param size  size of the memory region in bytes
+ *
+ * \returns pointer to memory region
+ *
+ * The memory must be freed with numa_free(). On errors NULL is returned.
+ */
+void *numa_alloc_local(size_t size);
+
+/**
+ * \brief allocates size bytes of memory page interleaved on all nodes.
+ *
+ * \param size   size of the memory region in bytes
+ *
+ * \returns pointer to the mapped memory region
+ *
+ * should only be used for large areas consisting of multiple pages.
+ * The memory must be freed with numa_free(). On errors NULL is returned.
+ */
+void *numa_alloc_interleaved(size_t size);
+
+/**
+ * \brief allocates size bytes of memory page interleaved on all nodes.
+ *
+ * \param size     size of the memory region in bytes
+ * \param nodemask subset of nodes to consider for allocation
+ * \returns pointer to the mapped memory region
+ *
+ * should only be used for large areas consisting of multiple pages.
+ * The memory must be freed with numa_free(). On errors NULL is returned.
+ */
+void *numa_alloc_interleaved_subset(size_t size, struct numa_bm *nodemask);
+
+/**
+ * \brief allocates size bytes of memory with the current NUMA policy.
+ *
+ * \param size  size of the memory region in bytes
+ *
+ * \returns pointer to the mapped memory region
+ *
+ * The memory must be freed with numa_free(). On errors NULL is returned.
+ */
+void *numa_alloc(size_t size);
+
+/**
+ * \brief changes the size of the memory area.
+ *
+ * \param old_addr  pointer ot the old memory region
+ * \param old_size  size of the old memory region
+ * \param new_size  new size to allocate
+ */
+void *numa_realloc(void *old_addr, size_t old_size, size_t new_size);
+
+/**
+ * \brief frees size bytes of memory starting at start
+ *
+ * \param start start of the memory region
+ * \param size  number of bytes to free
+ *
+ * the memory must be previously allocated by one of the numa_alloc* functions
+ */
+void numa_free(void *start, size_t size);
+
+
+/**
+ * \brief allocates a frame on a specific node
+ *
+ * \param dest      capref to store the frame
+ * \param size      size of the frame to allocated
+ * \param node      node on which the frame should be allocated
+ * \param ret_size  returned size of the frame capability
+ *
+ * \returns SYS_ERR_OK on SUCCESS
+ *          errval on FAILURE
+ */
+errval_t numa_frame_alloc_on_node(struct capref *dest,
+                                  size_t size,
+                                  nodeid_t node,
+                                  size_t *ret_size);
+
+/**
+ * \brief allocates a frame on the local node
+ *
+ * \param dest      capref to store the frame
+ * \param size      size of the frame to allocated
+ * \param ret_size  returned size of the frame capability
+ *
+ * \returns SYS_ERR_OK on SUCCESS
+ *          errval on FAILURE
+ */
+static inline errval_t numa_frame_alloc_local(struct capref *dest,
+                                              size_t size,
+                                              size_t *ret_size)
+{
+    return numa_frame_alloc_on_node(dest, size, numa_current_node(), ret_size);
+}
+
+/**
+ * \brief frees a previously allocated frame
+ *
+ * \param frame capability to free
+ */
+errval_t numa_frame_free(struct capref frame);
+
+/**
+ * \brief runs the current domain on a specific node.
+ *
+ * \param node  ID of the node to run the domain on
+ *
+ * \returns SYS_ERR_OK on SUCCESS
+ *          errval on FAILURE
+ *
+ * Passing -1 permits the kernel to schedule on all nodes again
+ */
+errval_t numa_run_on_node(nodeid_t node);
+
+/**
+ * \brief runs the current domain only on nodes specified in nodemask.
+ *
+ * \param nodemask bitmap representing the nodes to run the domain on
+ *
+ * \returns SYS_ERR_OK on SUCCESS
+ *          errval on FAILURE
+ */
+errval_t numa_run_on_node_mask(struct numa_bm *nodemask);
+
+/**
+ * \brief returns a mask of CPUs on which the current task is allowed to run.
+ *
+ * \returns bitmap represening the coreids the domain is allowed to run
+ */
+struct numa_bm *numa_get_run_node_mask(void);
+
+/**
+ * \brief specify the memory bind policy
+ *
+ * \param strict numa policy to apply
+ *
+ * specifies whether calls that bind memory to a specific node should use the preferred policy or a strict policy.
+ */
+void numa_set_bind_policy(numa_policy_t strict);
+
+/**
+ * \brief enable or disable the strict allocation policy
+ *
+ * \param strict numa policy to apply
+ *
+ * s a flag that says whether the functions allocating on specific nodes should
+ * use a strict policy. Strict means the allocation will fail if the memory cannot
+ * be allocated on the target node.
+ */
+void numa_set_strict(numa_policy_t strict);
+
+/**
+ * \brief reports the distance in the machine topology between two nodes
+ *
+ * \param from source node to measure the distance
+ * \param to   target node to measure the distance
+ *
+ * \returns distance between two nodes
+ *          0 iff cannot be deterimed
+ *
+ * The factors are a multiple of 10.  A node has distance 10 to itself.
+ */
+uint32_t numa_distance(nodeid_t from, nodeid_t to);
+
+/**
+ * \brief retrieves a bitmask of the cpus on which a domain may run
+ *
+ * \param did   domain ID
+ * \param mask  returned bitmask
+ *
+ * \returns SYS_ERR_OK on success
+ *          errval on FAILURE
+ */
+errval_t numa_sched_getaffinity(domainid_t did, struct numa_bm *mask);
+
+/**
+ * \brief sets a domain's allowed cpu's to those cpu's specified in mask.
+ *
+ * \param did   domain ID
+ * \param mask  bitmap representing the CPUs
+ *
+ * \returns SYS_ERR_OK on success
+ *          errval on FAILURE
+ */
+errval_t numa_sched_setaffinity(domainid_t did, struct numa_bm *mask);
+
+/**
+ * \brief returns the page size
+ *
+ * \returns the number of bytes in a page
+ */
+size_t numa_pagesize(void);
+
+/**
+ * \brief converts a node number to a bitmask of CPUs
+ *
+ * \param node  the ID of the node
+ * \param mask  bitmap representing the CPUs of this node
+ *
+ * \return  SYS_ERR_OK on SUCCESS
+ *          NUMA_ERR_BITMAP_RANGE on FAILURE (too small bitmap)
+ *
+ * The user must pass a bitmask structure with a mask buffer long enough to
+ * represent all possible cpu's
+ */
+errval_t numa_node_to_cpus(nodeid_t node, struct numa_bm *mask);
+
+/**
+ * \brief returns the node that a cpu belongs to
+ *
+ * \param cpu   ID of the core
+ *
+ * \returns node ID on SUCCESS
+ *          NUMA_NODE_INVALID on FAILURE
+ */
+nodeid_t numa_node_of_cpu(coreid_t cpu);
+
+/**
+ * \brief allocates a bit mask to represent the cores in the system
+ *
+ * \returns pointer to a new bitmask
+ *          NULL on failure
+ */
+struct numa_bm *numa_allocate_cpumask();
+
+/**
+ * \brief frees a previously allocated CPU bitmask
+ *
+ * \param cpumask pointer to a previously allocated CPU bitmask
+ */
+void numa_free_cpumask(struct numa_bm *cpumask);
+
+/**
+ * \brief allocates a bit mask to represent the nodes in the system
+ *
+ * \returns pointer to a new bitmask
+ *          NULL on failure
+ */
+struct numa_bm *numa_allocate_nodemask();
+
+/**
+ * \brief frees a previously allocated node bitmask
+ *
+ * \param nodemask pointer to a previously allocated node bitmask
+ */
+void numa_free_nodemask(struct numa_bm *nodemask);
+
+/**
+ * \brief allocates a bitmask structure and its associated bit mask
+ *
+ * \param n the number of bits
+ *
+ * \returns pointer to the bitmask
+ *          NULL on error
+ */
+struct numa_bm *numa_bitmask_alloc(unsigned int n);
+
+/**
+ * \brief sets all bits in the bit mask to 0.
+ *
+ * \param bmp   pointer to the bitmap
+ *
+ * \returns pointer to the cleared bit map
+ */
+struct numa_bm *numa_bitmask_clearall(struct numa_bm *bmp);
+
+/**
+ * \brief clears the n-th bit of a bitmask
+ *
+ * \param bmp   the bitmask
+ * \param n     the bit to clear
+ *
+ * \returns pointer to the bitmask
+ */
+struct numa_bm *numa_bitmask_clearbit(struct numa_bm *bmp, unsigned int n);
+
+/**
+ * \brief checks if two bitmasks are equal
+ *
+ * \param bmp1  bitmask 1
+ * \param bmp2  bitmask 2
+ *
+ * \return TRUE if the bitmasks are equal
+ *         FALSE if the are distinct
+ */
+bool numa_bitmask_equal(const struct numa_bm *bmp1, const struct numa_bm *bmp2);
+
+/**
+ * \brief frees the memory of a bitmask
+ *
+ * \param bmp the bitmask to be freed
+ */
+void numa_bitmask_free(struct numa_bm *bmp);
+
+/**
+ * \brief checks if the n-th bit is set in the bitmask
+ *
+ * \param bmp   the bitmap
+ * \param n     which bit to check
+ *
+ * \returns TRUE if the n-th bit is set
+ *          FALSE otherwise
+ */
+bool numa_bitmask_isbitset(const struct numa_bm *bmp, unsigned int n);
+
+/**
+ * \brief returns the size (in bytes) of the bit mask
+ *
+ * \param bmp   the bitmask
+ *
+ * \returns the size of the memory in bytes rounded up to a multiple of wordsize
+ */
+size_t numa_bitmask_nbytes(struct numa_bm *bmp);
+
+/**
+ * \brief sets all bits of a bitmask to 1
+ *
+ * \param bmp the bitmask
+ *
+ * \returns the bitmask
+ */
+struct numa_bm *numa_bitmask_setall(struct numa_bm *bmp);
+
+/**
+ * \brief sets the n-th bit of a bitmask to 1
+ *
+ * \param bmp   the bitmask
+ * \param n     which bit to activate
+ *
+ * \returns the bitmask
+ */
+struct numa_bm *numa_bitmask_setbit(struct numa_bm *bmp, unsigned int n);
+
+/**
+ * \brief copies the bitmask to a nodemask
+ *
+ * \param bmp       the bitmask to copy
+ * \param nodemask  the destination nodemask
+ *
+ * If the two areas differ in size, the copy is truncated to the size of the
+ * receiving field or zero-filled.
+ */
+void copy_bitmask_to_nodemask(struct numa_bm *bmp, nodemask_t *nodemask);
+
+/**
+ * \brief copies the contents of a nodemask into the bitmask
+ *
+ * \param nodemask  node mask to copy from
+ * \param bmp       bitmap to copy into
+ *
+ * If the two areas differ in size, the copy is truncated to the size of the
+ * receiving field or zero-filled.
+ */
+void copy_nodemask_to_bitmask(nodemask_t *nodemask, struct numa_bm *bmp);
+
+/**
+ * \brief copies one bitmask into another
+ *
+ * \param bmpfrom   the source bitmask
+ * \param bmpto     the destination bitmask
+ *
+ * If the two areas differ in size, the copy is truncated to the size of the
+ * receiving field or zero-filled.
+ */
+void copy_bitmask_to_bitmask(struct numa_bm *bmpfrom, struct numa_bm *bmpto);
+
+/**
+ * \brief returns a count of the bits that are set in the body of the bitmask
+ *
+ * \param bmp   the bitmask to count the set bits
+ *
+ * \return number of set bits in this bitmask
+ */
+uint32_t numa_bitmask_weight(const struct numa_bm *bmp);
+
+/**
+ * \brief  moves a list of pages in the address space of the current domain
+ *
+ * \param did    the domain ID
+ * \param count  number of pages to move
+ * \param pages  list of pages
+ * \param nodes  list of nodes to which the pages can be moved
+ * \param status returns the outcome for each page
+ * \param flags  flags for moving the pages
+ *
+ * \returns SYS_ERR_OK on SUCCESS
+ */
+errval_t numa_move_pages(domainid_t did,
+                         size_t count,
+                         void **pages,
+                         const nodeid_t *nodes,
+                         errval_t *status,
+                         int flags);
+/**
+ * \brief migrate a domain from one set of nodes to another
+ *
+ * \param did        the domain ID
+ * \param fromnodes  bitmap representing the current nodes
+ * \param tonodes    bitmap representing the
+ *
+ * \returns SYS_ERR_OK on SUCCESS
+ */
+errval_t numa_migrate_pages(domainid_t did,
+                            struct numa_bm *fromnodes,
+                            struct numa_bm *tonodes);
+
+/**
+ * is a libnuma internal function that can be overridden by the user program. This
+ * function is called with a char * argument when a libnuma function fails.
+ * Overriding the library internal definition makes it possible to specify a
+ * different error handling strategy when a libnuma function fails. It does not
+ * affect numa_available(). The numa_error() function defined in libnuma prints an
+ * error on stderr and terminates the program if numa_exit_on_error is set to a
+ * non-zero value. The default value of numa_exit_on_error is zero.
+ *
+ * \param where
+ */
+void numa_error(char *where);
+
+extern int numa_exit_on_error;
+extern int numa_exit_on_warn;
+
+/**
+ * is a libnuma internal function that can be also overridden by the user program.
+ * It is called to warn the user when a libnuma function encounters a non-fatal
+ * error. The default implementation prints a warning to stderr. The first argument
+ * is a unique number identifying each warning. After that there is a printf(3)-style
+ * format string and a variable number of arguments. numa_warn exits the program
+ * when numa_exit_on_warn is set to a non-zero value. The default value of
+ * numa_exit_on_warn is zero.
+ *
+ * \param number
+ * \param where
+ */
+void numa_warn(int number, char *where, ...);
+
+#endif /* __NUMA_H */