+always_inline uword
+clib_mem_round_to_page_size (uword size, clib_mem_page_sz_t log2_page_size)
+{
+ ASSERT (log2_page_size != CLIB_MEM_PAGE_SZ_UNKNOWN);
+
+ if (log2_page_size == CLIB_MEM_PAGE_SZ_DEFAULT)
+ log2_page_size = clib_mem_get_log2_page_size ();
+ else if (log2_page_size == CLIB_MEM_PAGE_SZ_DEFAULT_HUGE)
+ log2_page_size = clib_mem_get_log2_default_hugepage_size ();
+
+ return round_pow2 (size, 1ULL << log2_page_size);
+}
+
+typedef struct
+{
+ clib_mem_page_sz_t log2_page_sz;
+ uword total;
+ uword mapped;
+ uword not_mapped;
+ uword per_numa[CLIB_MAX_NUMAS];
+ uword unknown;
+} clib_mem_page_stats_t;
+
+void clib_mem_get_page_stats (void *start, clib_mem_page_sz_t log2_page_size,
+ uword n_pages, clib_mem_page_stats_t * stats);
+
+static_always_inline int
+vlib_mem_get_next_numa_node (int numa)
+{
+ clib_mem_main_t *mm = &clib_mem_main;
+ u32 bitmap = mm->numa_node_bitmap;
+
+ if (numa >= 0)
+ bitmap &= ~pow2_mask (numa + 1);
+ if (bitmap == 0)
+ return -1;
+
+ return count_trailing_zeros (bitmap);
+}
+
+static_always_inline clib_mem_page_sz_t
+clib_mem_log2_page_size_validate (clib_mem_page_sz_t log2_page_size)
+{
+ if (log2_page_size == CLIB_MEM_PAGE_SZ_DEFAULT)
+ return clib_mem_get_log2_page_size ();
+ if (log2_page_size == CLIB_MEM_PAGE_SZ_DEFAULT_HUGE)
+ return clib_mem_get_log2_default_hugepage_size ();
+ return log2_page_size;
+}
+
+static_always_inline uword
+clib_mem_page_bytes (clib_mem_page_sz_t log2_page_size)
+{
+ return 1ULL << clib_mem_log2_page_size_validate (log2_page_size);
+}
+
+static_always_inline clib_error_t *
+clib_mem_get_last_error (void)
+{
+ return clib_mem_main.error;
+}
+
+/* bulk allocator */
+
+typedef void *clib_mem_bulk_handle_t;
+clib_mem_bulk_handle_t clib_mem_bulk_init (u32 elt_sz, u32 align,
+ u32 min_elts_per_chunk);
+void clib_mem_bulk_destroy (clib_mem_bulk_handle_t h);
+void *clib_mem_bulk_alloc (clib_mem_bulk_handle_t h);
+void clib_mem_bulk_free (clib_mem_bulk_handle_t h, void *p);
+u8 *format_clib_mem_bulk (u8 *s, va_list *args);
+