Commit 36bc84c1 authored by Swann Perarnau's avatar Swann Perarnau
Browse files

Merge branch 'remove-dma-move' into 'master'

Remove DMA move operations

See merge request !41
parents 6c2c6cdb f8c0ce7d
Pipeline #6796 passed with stage
in 9 minutes and 42 seconds
...@@ -78,7 +78,6 @@ void *th_work(void *arg) ...@@ -78,7 +78,6 @@ void *th_work(void *arg)
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
AML_BINDING_SINGLE_DECL(binding);
AML_ARENA_JEMALLOC_DECL(arena); AML_ARENA_JEMALLOC_DECL(arena);
AML_DMA_LINUX_SEQ_DECL(dma); AML_DMA_LINUX_SEQ_DECL(dma);
struct bitmask *slowb, *fastb; struct bitmask *slowb, *fastb;
...@@ -101,7 +100,6 @@ int main(int argc, char *argv[]) ...@@ -101,7 +100,6 @@ int main(int argc, char *argv[])
} }
/* initialize all the supporting struct */ /* initialize all the supporting struct */
assert(!aml_binding_init(&binding, AML_BINDING_TYPE_SINGLE, 0));
assert(!aml_tiling_init(&tiling, AML_TILING_TYPE_1D, tilesz, memsize)); assert(!aml_tiling_init(&tiling, AML_TILING_TYPE_1D, tilesz, memsize));
assert(!aml_arena_jemalloc_init(&arena, AML_ARENA_JEMALLOC_TYPE_REGULAR)); assert(!aml_arena_jemalloc_init(&arena, AML_ARENA_JEMALLOC_TYPE_REGULAR));
...@@ -159,7 +157,6 @@ int main(int argc, char *argv[]) ...@@ -159,7 +157,6 @@ int main(int argc, char *argv[])
aml_area_linux_destroy(&slow); aml_area_linux_destroy(&slow);
aml_area_linux_destroy(&fast); aml_area_linux_destroy(&fast);
aml_tiling_destroy(&tiling, AML_TILING_TYPE_1D); aml_tiling_destroy(&tiling, AML_TILING_TYPE_1D);
aml_binding_destroy(&binding, AML_BINDING_TYPE_SINGLE);
aml_finalize(); aml_finalize();
return 0; return 0;
} }
...@@ -83,7 +83,6 @@ AC_CONFIG_FILES([Makefile ...@@ -83,7 +83,6 @@ AC_CONFIG_FILES([Makefile
src/area/Makefile src/area/Makefile
src/dma/Makefile src/dma/Makefile
src/tiling/Makefile src/tiling/Makefile
src/binding/Makefile
src/scratch/Makefile src/scratch/Makefile
src/arena/Makefile src/arena/Makefile
src/utils/Makefile src/utils/Makefile
......
...@@ -23,8 +23,7 @@ ...@@ -23,8 +23,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <unistd.h> #include <unistd.h>
/* Used by bindings, specifically in aml_binding_nbpages() and /* Used by mbind */
* aml_binding_pages(). */
#ifndef PAGE_SIZE #ifndef PAGE_SIZE
#define PAGE_SIZE 4096 #define PAGE_SIZE 4096
#endif #endif
...@@ -56,7 +55,6 @@ int aml_finalize(void); ...@@ -56,7 +55,6 @@ int aml_finalize(void);
******************************************************************************/ ******************************************************************************/
struct aml_area; struct aml_area;
struct aml_binding;
/******************************************************************************* /*******************************************************************************
* Arenas: * Arenas:
...@@ -221,8 +219,6 @@ struct aml_area_ops { ...@@ -221,8 +219,6 @@ struct aml_area_ops {
void (*release)(struct aml_area_data *area, void *ptr); void (*release)(struct aml_area_data *area, void *ptr);
void *(*mmap)(struct aml_area_data *area, void *ptr, size_t size); void *(*mmap)(struct aml_area_data *area, void *ptr, size_t size);
int (*available)(const struct aml_area_data *area); int (*available)(const struct aml_area_data *area);
int (*binding)(const struct aml_area_data *area,
struct aml_binding **binding);
}; };
struct aml_area { struct aml_area {
...@@ -319,8 +315,6 @@ struct aml_area_linux_mbind_ops { ...@@ -319,8 +315,6 @@ struct aml_area_linux_mbind_ops {
int (*pre_bind)(struct aml_area_linux_mbind_data *data); int (*pre_bind)(struct aml_area_linux_mbind_data *data);
int (*post_bind)(struct aml_area_linux_mbind_data *data, void *ptr, int (*post_bind)(struct aml_area_linux_mbind_data *data, void *ptr,
size_t size); size_t size);
int (*binding)(const struct aml_area_linux_mbind_data *data,
struct aml_binding **binding);
}; };
/* /*
...@@ -331,16 +325,6 @@ struct aml_area_linux_mbind_ops { ...@@ -331,16 +325,6 @@ struct aml_area_linux_mbind_ops {
*/ */
int aml_area_linux_mbind_setdata(struct aml_area_linux_mbind_data *data, int aml_area_linux_mbind_setdata(struct aml_area_linux_mbind_data *data,
int policy, const struct aml_bitmap *nodemask); int policy, const struct aml_bitmap *nodemask);
/*
* Creates a new binding structure based on an existing Linux memory policy
* structure.
* "data": an initialized Linux memory policy structure.
* "binding": an address where the pointer to the newly allocated binding
* structure will be stored.
* Returns 0 if successful; an error code otherwise.
*/
int aml_area_linux_mbind_generic_binding(const struct aml_area_linux_mbind_data *data,
struct aml_binding **binding);
/* /*
* Sets current memory policy before memory allocation using the Linux memory * Sets current memory policy before memory allocation using the Linux memory
* area. * area.
...@@ -655,14 +639,6 @@ void aml_area_release(struct aml_area *area, void *ptr); ...@@ -655,14 +639,6 @@ void aml_area_release(struct aml_area *area, void *ptr);
void *aml_area_mmap(struct aml_area *area, void *ptr, size_t size); void *aml_area_mmap(struct aml_area *area, void *ptr, size_t size);
/* FIXME! */ /* FIXME! */
int aml_area_available(const struct aml_area *area); int aml_area_available(const struct aml_area *area);
/*
* Creates a new binding structure based on an existing Linux memory area.
* "area": an initialized memory area structure.
* "binding": an address where the pointer to the newly allocated binding
* structure will be stored.
* Returns 0 if successful; an error code otherwise.
*/
int aml_area_binding(const struct aml_area *area, struct aml_binding **binding);
/******************************************************************************* /*******************************************************************************
* Tiling: * Tiling:
...@@ -948,164 +924,6 @@ struct aml_tiling_iterator_2d_data { ...@@ -948,164 +924,6 @@ struct aml_tiling_iterator_2d_data {
(sizeof(struct aml_tiling_iterator_2d_data) + \ (sizeof(struct aml_tiling_iterator_2d_data) + \
sizeof(struct aml_tiling_iterator)) sizeof(struct aml_tiling_iterator))
/*******************************************************************************
* Binding:
* Representation of page bindings in an area
******************************************************************************/
/* opaque handle to all bindings */
struct aml_binding_data;
struct aml_binding_ops {
int (*nbpages)(const struct aml_binding_data *binding,
const struct aml_tiling *tiling, const void *ptr,
int tileid);
int (*pages)(const struct aml_binding_data *binding, void **pages,
const struct aml_tiling *tiling, const void *ptr,
int tileid);
int (*nodes)(const struct aml_binding_data *binding, int *nodes,
const struct aml_tiling *tiling, const void *ptr,
int tileid);
};
struct aml_binding {
struct aml_binding_ops *ops;
struct aml_binding_data *data;
};
/*
* Provides the size of a tile in memory, in pages.
* "binding": an initialized binding structure.
* "tiling": an initialized tiling structure.
* "ptr", "tileid": see aml_tiling_tilestart().
* Returns the total number of pages that a tile occupies, including partial
* pages.
*/
int aml_binding_nbpages(const struct aml_binding *binding,
const struct aml_tiling *tiling,
const void *ptr, int tileid);
/*
* Provides the addresses of pages that a tile occupies.
* "binding": an initialized binding structure.
* "pages": an array that will be filled with start addresses of all pages
* that a tile occupies. The array must be at least
* aml_binding_nbpages() elements long.
* "tiling": an initialized tiling structure.
* "ptr", "tileid": see aml_tiling_tilestart().
* Returns 0 if successful; an error code otherwise.
*/
int aml_binding_pages(const struct aml_binding *binding, void **pages,
const struct aml_tiling *tiling, const void *ptr,
int tileid);
/*
* Provides the NUMA node information of pages that a tile occupies.
* "binding": an initialized binding structure.
* "nodes": an array that will be filled with NUMA node id's of all pages
* that a tile occupies. The array must be at least
* aml_binding_nbpages() elements long.
* "tiling": an initialized tiling structure.
* "ptr", "tileid": see aml_tiling_tilestart().
* Returns 0 if successful; an error code otherwise.
*/
int aml_binding_nodes(const struct aml_binding *binding, int *nodes,
const struct aml_tiling *tiling, const void *ptr,
int tileid);
/* Binding types passed to the binding create()/init()/vinit() routines. */
/* Binding where all pages are bound to the same NUMA node. */
#define AML_BINDING_TYPE_SINGLE 0
/* Binding where pages are interleaved among multiple NUMA nodes. */
#define AML_BINDING_TYPE_INTERLEAVE 1
/*
* Allocates and initializes a new binding.
* "binding": an address where the pointer to the newly allocated binding
* structure will be stored.
* "type": see AML_BINDING_TYPE_*.
* Variadic arguments:
* - if "type" equals AML_BINDING_TYPE_SINGLE, one additional argument is
* needed:
* - "node": an argument of type int; provides a NUMA node id where pages
* will be allocated from.
* - if "type" equals AML_BINDING_TYPE_INTERLEAVE, one additional argument is
* needed:
* - "mask": an argument of type const struct aml_bitmap*; storing a bitmask of
* NUMA node ids where pages will be allocated from. See
* aml_bitmap for more information.
* Returns 0 if successful; an error code otherwise.
*/
int aml_binding_create(struct aml_binding **binding, int type, ...);
/*
* Initializes a new binding. This is a varags-variant of the
* aml_binding_vinit() routine.
* "binding": an allocated binding structure.
* "type": see aml_binding_create().
* Variadic arguments: see aml_binding_create().
* Returns 0 if successful; an error code otherwise.
*/
int aml_binding_init(struct aml_binding *binding, int type, ...);
/*
* Initializes a new binding.
* "binding": an allocated binding structure.
* "type": see aml_binding_create().
* "args": see the variadic arguments of aml_binding_create().
* Returns 0 if successful; an error code otherwise.
*/
int aml_binding_vinit(struct aml_binding *binding, int type, va_list args);
/*
* Tears down an initialized binding.
* "binding": an initialized binding structure.
* "type": see aml_binding_create().
* Returns 0 if successful; an error code otherwise.
*/
int aml_binding_destroy(struct aml_binding *binding, int type);
/*******************************************************************************
* Single Binding:
* All pages on the same node
******************************************************************************/
extern struct aml_binding_ops aml_binding_single_ops;
struct aml_binding_single_data {
int node;
};
#define AML_BINDING_SINGLE_DECL(name) \
struct aml_binding_single_data __ ##name## _inner_data; \
struct aml_binding name = { \
&aml_binding_single_ops, \
(struct aml_binding_data *)&__ ## name ## _inner_data, \
};
#define AML_BINDING_SINGLE_ALLOCSIZE (sizeof(struct aml_binding_single_data) + \
sizeof(struct aml_binding))
/*******************************************************************************
* Interleave Binding:
* each page, of each tile, interleaved across nodes.
******************************************************************************/
#define AML_MAX_NUMA_NODES AML_BITMAP_MAX
extern struct aml_binding_ops aml_binding_interleave_ops;
struct aml_binding_interleave_data {
int nodes[AML_MAX_NUMA_NODES];
int count;
};
#define AML_BINDING_INTERLEAVE_DECL(name) \
struct aml_binding_interleave_data __ ##name## _inner_data; \
struct aml_binding name = { \
&aml_binding_interleave_ops, \
(struct aml_binding_data *)&__ ## name ## _inner_data, \
};
#define AML_BINDING_INTERLEAVE_ALLOCSIZE \
(sizeof(struct aml_binding_interleave_data) + \
sizeof(struct aml_binding))
/******************************************************************************* /*******************************************************************************
* DMA: * DMA:
* Management of low-level movement of memory. * Management of low-level movement of memory.
...@@ -1116,8 +934,6 @@ struct aml_binding_interleave_data { ...@@ -1116,8 +934,6 @@ struct aml_binding_interleave_data {
#define AML_DMA_REQUEST_TYPE_INVALID -1 #define AML_DMA_REQUEST_TYPE_INVALID -1
/* Copy request type. Uses memcpy() for data migration. */ /* Copy request type. Uses memcpy() for data migration. */
#define AML_DMA_REQUEST_TYPE_COPY 0 #define AML_DMA_REQUEST_TYPE_COPY 0
/* Move request type. Uses move_pages() for data migration. */
#define AML_DMA_REQUEST_TYPE_MOVE 1
struct aml_dma_request; struct aml_dma_request;
struct aml_dma_data; struct aml_dma_data;
...@@ -1164,31 +980,6 @@ int aml_dma_copy(struct aml_dma *dma, ...); ...@@ -1164,31 +980,6 @@ int aml_dma_copy(struct aml_dma *dma, ...);
* Returns 0 if successful; an error code otherwise. * Returns 0 if successful; an error code otherwise.
*/ */
int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request **req, ...); int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request **req, ...);
/*
* Requests a synchronous data move of a tile to a new memory area, using
* move_pages() or equivalent.
* "dma": an initialized DMA structure.
* Variadic arguments:
* - "darea": an argument of type struct aml_area*; the destination memory area
* structure.
* - "st": an argument of type struct aml_tiling*; the tiling structure.
* - "sptr": an argument of type void*; the start address of the complete
* user data structure.
* - "stid": an argument of type int; the tile identifier.
* Returns 0 if successful; an error code otherwise.
*/
int aml_dma_move(struct aml_dma *dma, ...);
/*
* Requests a data move of a tile to a new memory area. This is an asynchronous
* version of aml_dma_move().
* "dma": an initialized DMA structure.
* "req": an address where the pointer to the newly assigned DMA request will be
* stored.
* Variadic arguments: see aml_dma_move().
* Returns 0 if successful; an error code otherwise.
*
*/
int aml_dma_async_move(struct aml_dma *dma, struct aml_dma_request **req, ...);
/* /*
* Waits for an asynchronous DMA request to complete. * Waits for an asynchronous DMA request to complete.
* "dma": an initialized DMA structure. * "dma": an initialized DMA structure.
......
...@@ -31,9 +31,6 @@ struct aml_dma_request_linux_par { ...@@ -31,9 +31,6 @@ struct aml_dma_request_linux_par {
void *dest; void *dest;
void *src; void *src;
size_t size; size_t size;
int count;
void **pages;
int *nodes;
struct aml_dma_linux_par_thread_data *thread_data; struct aml_dma_linux_par_thread_data *thread_data;
}; };
...@@ -47,8 +44,6 @@ struct aml_dma_linux_par_ops { ...@@ -47,8 +44,6 @@ struct aml_dma_linux_par_ops {
void *(*do_thread)(void *); void *(*do_thread)(void *);
int (*do_copy)(struct aml_dma_linux_par_data *, int (*do_copy)(struct aml_dma_linux_par_data *,
struct aml_dma_request_linux_par *, int tid); struct aml_dma_request_linux_par *, int tid);
int (*do_move)(struct aml_dma_linux_par_data *,
struct aml_dma_request_linux_par *, int tid);
}; };
struct aml_dma_linux_par { struct aml_dma_linux_par {
......
...@@ -24,9 +24,6 @@ struct aml_dma_request_linux_seq { ...@@ -24,9 +24,6 @@ struct aml_dma_request_linux_seq {
void *dest; void *dest;
void *src; void *src;
size_t size; size_t size;
int count;
void **pages;
int *nodes;
}; };
struct aml_dma_linux_seq_data { struct aml_dma_linux_seq_data {
...@@ -37,8 +34,6 @@ struct aml_dma_linux_seq_data { ...@@ -37,8 +34,6 @@ struct aml_dma_linux_seq_data {
struct aml_dma_linux_seq_ops { struct aml_dma_linux_seq_ops {
int (*do_copy)(struct aml_dma_linux_seq_data *dma, int (*do_copy)(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq *req); struct aml_dma_request_linux_seq *req);
int (*do_move)(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq *req);
}; };
struct aml_dma_linux_seq { struct aml_dma_linux_seq {
...@@ -98,12 +93,4 @@ int aml_dma_linux_seq_destroy(struct aml_dma *dma); ...@@ -98,12 +93,4 @@ int aml_dma_linux_seq_destroy(struct aml_dma *dma);
int aml_dma_linux_seq_do_copy(struct aml_dma_linux_seq_data *dma, int aml_dma_linux_seq_do_copy(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq *req); struct aml_dma_request_linux_seq *req);
/* Performs a move request.
* "dma" the dma_linux_seq_data associated with a linux_seq dma.
* "req" a valid linux_seq request.
* Returns 0 if successful; an error code otherwise.
*/
int aml_dma_linux_seq_do_move(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq *req);
#endif // AML_DMA_LINUX_SEQ_H #endif // AML_DMA_LINUX_SEQ_H
...@@ -20,9 +20,6 @@ libaml_la_LIBADD+=$(top_srcdir)/src/dma/libamldma.la ...@@ -20,9 +20,6 @@ libaml_la_LIBADD+=$(top_srcdir)/src/dma/libamldma.la
SUBDIRS+=tiling SUBDIRS+=tiling
libaml_la_LIBADD+=$(top_srcdir)/src/tiling/libamltiling.la libaml_la_LIBADD+=$(top_srcdir)/src/tiling/libamltiling.la
SUBDIRS+=binding
libaml_la_LIBADD+=$(top_srcdir)/src/binding/libamlbinding.la
SUBDIRS+=scratch SUBDIRS+=scratch
libaml_la_LIBADD+=$(top_srcdir)/src/scratch/libamlscratch.la libaml_la_LIBADD+=$(top_srcdir)/src/scratch/libamlscratch.la
......
...@@ -70,9 +70,3 @@ int aml_area_available(const struct aml_area *area) ...@@ -70,9 +70,3 @@ int aml_area_available(const struct aml_area *area)
assert(area != NULL); assert(area != NULL);
return area->ops->available(area->data); return area->ops->available(area->data);
} }
int aml_area_binding(const struct aml_area *area, struct aml_binding **binding)
{
assert(area != NULL);
return area->ops->binding(area->data, binding);
}
...@@ -34,13 +34,6 @@ int aml_area_linux_available(const struct aml_area_data *a) ...@@ -34,13 +34,6 @@ int aml_area_linux_available(const struct aml_area_data *a)
return 1; return 1;
} }
int aml_area_linux_binding(const struct aml_area_data *a, struct aml_binding **b)
{
assert(a != NULL);
const struct aml_area_linux *area = (const struct aml_area_linux *)a;
return area->ops.mbind.binding(&area->data.mbind, b);
}
/******************************************************************************* /*******************************************************************************
* Public API: * Public API:
* The actual functions that will be called on the area from users * The actual functions that will be called on the area from users
...@@ -156,7 +149,6 @@ struct aml_area_ops aml_area_linux_ops = { ...@@ -156,7 +149,6 @@ struct aml_area_ops aml_area_linux_ops = {
aml_area_linux_release, aml_area_linux_release,
aml_area_linux_mmap, aml_area_linux_mmap,
aml_area_linux_available, aml_area_linux_available,
aml_area_linux_binding,
}; };
/******************************************************************************* /*******************************************************************************
......
...@@ -18,30 +18,6 @@ ...@@ -18,30 +18,6 @@
* Only handles the actual mbind/mempolicy calls * Only handles the actual mbind/mempolicy calls
******************************************************************************/ ******************************************************************************/
/* common to both methods */
int aml_area_linux_mbind_generic_binding(const struct aml_area_linux_mbind_data *data,
struct aml_binding **b)
{
assert(data != NULL);
const struct aml_bitmap *nodemask = &data->nodemask;
/* not exactly proper, we should inspect the nodemask to find the real
* binding policy.
*/
if(data->policy == MPOL_BIND)
{
for(int i = 0; i < AML_BITMAP_MAX; i++)
if(aml_bitmap_isset(nodemask, i))
return aml_binding_create(b, AML_BINDING_TYPE_SINGLE,i);
}
else if(data->policy == MPOL_INTERLEAVE)
{
return aml_binding_create(b, AML_BINDING_TYPE_INTERLEAVE,
nodemask);
}
return 0;
}
int aml_area_linux_mbind_regular_pre_bind(struct aml_area_linux_mbind_data *data) int aml_area_linux_mbind_regular_pre_bind(struct aml_area_linux_mbind_data *data)
{ {
assert(data != NULL); assert(data != NULL);
...@@ -61,7 +37,6 @@ int aml_area_linux_mbind_regular_post_bind(struct aml_area_linux_mbind_data *dat ...@@ -61,7 +37,6 @@ int aml_area_linux_mbind_regular_post_bind(struct aml_area_linux_mbind_data *dat
struct aml_area_linux_mbind_ops aml_area_linux_mbind_regular_ops = { struct aml_area_linux_mbind_ops aml_area_linux_mbind_regular_ops = {
aml_area_linux_mbind_regular_pre_bind, aml_area_linux_mbind_regular_pre_bind,
aml_area_linux_mbind_regular_post_bind, aml_area_linux_mbind_regular_post_bind,
aml_area_linux_mbind_generic_binding,
}; };
int aml_area_linux_mbind_setdata(struct aml_area_linux_mbind_data *data, int aml_area_linux_mbind_setdata(struct aml_area_linux_mbind_data *data,
...@@ -111,7 +86,6 @@ int aml_area_linux_mbind_mempolicy_post_bind(struct aml_area_linux_mbind_data *d ...@@ -111,7 +86,6 @@ int aml_area_linux_mbind_mempolicy_post_bind(struct aml_area_linux_mbind_data *d
struct aml_area_linux_mbind_ops aml_area_linux_mbind_mempolicy_ops = { struct aml_area_linux_mbind_ops aml_area_linux_mbind_mempolicy_ops = {
aml_area_linux_mbind_mempolicy_pre_bind, aml_area_linux_mbind_mempolicy_pre_bind,
aml_area_linux_mbind_mempolicy_post_bind, aml_area_linux_mbind_mempolicy_post_bind,
aml_area_linux_mbind_generic_binding,
}; };
int aml_area_linux_mbind_init(struct aml_area_linux_mbind_data *data, int aml_area_linux_mbind_init(struct aml_area_linux_mbind_data *data,
......
...@@ -33,16 +33,6 @@ int aml_area_posix_available(const struct aml_area_data *data) ...@@ -33,16 +33,6 @@ int aml_area_posix_available(const struct aml_area_data *data)
return 1; return 1;
} }
/* same thing here, it makes no sense to ask for this area to provide its
* binding scheme, as no-one should migrate to this area.
*/
int aml_area_posix_binding(const struct aml_area_data *data, struct aml_binding **b)
{
assert(data != NULL);
/* numa node 0 should always be available */
return aml_binding_create(b, AML_BINDING_TYPE_SINGLE, 0);
}
/******************************************************************************* /*******************************************************************************
* Public API: * Public API:
* The actual functions that will be called on the area from users * The actual functions that will be called on the area from users
...@@ -102,7 +92,6 @@ struct aml_area_ops aml_area_posix_ops = { ...@@ -102,7 +92,6 @@ struct aml_area_ops aml_area_posix_ops = {
aml_area_posix_release, aml_area_posix_release,
aml_area_posix_mmap, aml_area_posix_mmap,
aml_area_posix_available, aml_area_posix_available,
aml_area_posix_binding,
}; };
/******************************************************************************* /*******************************************************************************
......
AM_CFLAGS=-I$(top_srcdir)/include
AM_CPPFLAGS=$(AM_CFLAGS)
noinst_LTLIBRARIES=libamlbinding.la
libamlbinding_la_SOURCES=\
binding.c \
binding_single.c \
binding_interleave.c
libamlbinding_la_CFLAGS=$(AM_CFLAGS)
/*******************************************************************************
* Copyright 2019 UChicago Argonne, LLC.
* (c.f. AUTHORS, LICENSE)
*
* This file is part of the AML project.
* For more info, see https://xgitlab.cels.anl.gov/argo/aml
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
#include "aml.h"
#include <assert.h>
/*******************************************************************************
* Binding functions
* Most of the stuff is dispatched to a different layer, using type-specific
* functions.
******************************************************************************/
int aml_binding_nbpages(const struct aml_binding *binding,
const struct aml_