diff --git a/include/aml.h b/include/aml.h index 847733401e1dd4c82ec7b5aa6bd2b260bcf679af..2276134a521c6dff768185fe1d60c6005fe4905b 100644 --- a/include/aml.h +++ b/include/aml.h @@ -877,7 +877,7 @@ struct aml_dma_ops { * @return an AML error code. **/ int (*destroy_request)(struct aml_dma_data *dma, - struct aml_dma_request *req); + struct aml_dma_request **req); /** * Wait for termination of a data movement and destroy the request @@ -888,7 +888,7 @@ struct aml_dma_ops { * @return an AML error code. **/ int (*wait_request)(struct aml_dma_data *dma, - struct aml_dma_request *req); + struct aml_dma_request **req); }; /** @@ -931,7 +931,7 @@ int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request **req, * @param req: a DMA request obtained using aml_dma_async_*() calls. * @return 0 if successful; an error code otherwise. **/ -int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request *req); +int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request **req); /** * Tears down an asynchronous DMA request before it completes. @@ -939,7 +939,7 @@ int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request *req); * @param req: a DMA request obtained using aml_dma_async_*() calls. * @return 0 if successful; an error code otherwise. **/ -int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request *req); +int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request **req); /** * Generic helper to copy from one layout to another. diff --git a/include/aml/dma/linux-par.h b/include/aml/dma/linux-par.h index 1b7fc635a0d8b5a22abc95afcbecabddf3656185..f3d21e51e2c1905728df7f8db81fbc08ab56146f 100644 --- a/include/aml/dma/linux-par.h +++ b/include/aml/dma/linux-par.h @@ -50,7 +50,7 @@ struct aml_dma_linux_par_request_data { pthread_t thread; }; -/** Inside of a parallel request for linux movement. **/ +/** Inside of a parallel dma for linux movement. **/ struct aml_dma_linux_par_data { struct aml_vector *requests; pthread_mutex_t lock; diff --git a/include/aml/utils/bitmap.h b/include/aml/utils/bitmap.h index 796480facc1736c85d14e821552cb4be6b44239e..006b5e73dc5c1846f1aacb8bfe492f3836ab3990 100644 --- a/include/aml/utils/bitmap.h +++ b/include/aml/utils/bitmap.h @@ -27,9 +27,9 @@ /** The type used to store bits **/ #define AML_BITMAP_TYPE unsigned long /** The number of basic type elements used to store bits **/ -#define AML_BITMAP_SIZE (AML_BITMAP_BYTES/sizeof(AML_BITMAP_TYPE)) +#define AML_BITMAP_SIZE ((int)(AML_BITMAP_BYTES/sizeof(AML_BITMAP_TYPE))) /** The number of bits held in each basic type element **/ -#define AML_BITMAP_NBITS (8 * sizeof(AML_BITMAP_TYPE)) +#define AML_BITMAP_NBITS ((int)(8 * sizeof(AML_BITMAP_TYPE))) /** * aml_bitmap is a static array of elements wrapped in a structure. @@ -50,13 +50,13 @@ void aml_bitmap_copy(struct aml_bitmap *dst, const struct aml_bitmap *src); * Empty a bitmap with all bits cleared. * @param bitmap: The bitmap to set. **/ -void aml_bitmap_zero(struct aml_bitmap *bitmap); +int aml_bitmap_zero(struct aml_bitmap *bitmap); /** * Fill a bitmap with all bits set. * @param bitmap: The bitmap to set. **/ -void aml_bitmap_fill(struct aml_bitmap *bitmap); +int aml_bitmap_fill(struct aml_bitmap *bitmap); /** * Check whether a bit in bitmap is set. @@ -135,7 +135,7 @@ int aml_bitmap_clear_range(struct aml_bitmap *bitmap, * @param bitmap: The bitmap to inspect. * @return The number of bits set in bitmap. **/ -unsigned long aml_bitmap_nset(const struct aml_bitmap *bitmap); +int aml_bitmap_nset(const struct aml_bitmap *bitmap); /** * Copy a unsigned long array used as a bitmap into an actual bitmap. diff --git a/src/dma/dma.c b/src/dma/dma.c index ba8854eda797772ccde03eb3ad214559a6049b97..d9566488948a00c324c97064e5e964cbc3e4114e 100644 --- a/src/dma/dma.c +++ b/src/dma/dma.c @@ -88,7 +88,9 @@ int aml_dma_copy(struct aml_dma *dma, int type, ...) va_start(ap, type); ret = dma->ops->create_request(dma->data, &req, type, ap); va_end(ap); - ret = dma->ops->wait_request(dma->data, req); + if (ret != AML_SUCCESS) + return ret; + ret = dma->ops->wait_request(dma->data, &req); return ret; } @@ -107,16 +109,16 @@ int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request **req, return ret; } -int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request *req) +int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request **req) { - assert(dma != NULL); - assert(req != NULL); + if (dma == NULL || req == NULL) + return -AML_EINVAL; return dma->ops->destroy_request(dma->data, req); } -int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request *req) +int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request **req) { - assert(dma != NULL); - assert(req != NULL); + if (dma == NULL || req == NULL) + return -AML_EINVAL; return dma->ops->wait_request(dma->data, req); } diff --git a/src/dma/dma_linux_par.c b/src/dma/dma_linux_par.c index d4427a1fcbfad8d03882e1dce9ddec4b432b5c61..5d487e11f501c35498ef3f62762c2b0a38802afa 100644 --- a/src/dma/dma_linux_par.c +++ b/src/dma/dma_linux_par.c @@ -68,6 +68,7 @@ void *aml_dma_linux_par_do_thread(void *arg) struct aml_dma_linux_par_request_data *req = (struct aml_dma_linux_par_request_data *)arg; + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); if (req->type != AML_DMA_REQUEST_TYPE_INVALID) aml_copy_layout_generic(req->dest, req->src); return NULL; @@ -91,6 +92,7 @@ int aml_dma_linux_par_create_request(struct aml_dma_data *d, (struct aml_dma_linux_par *)d; struct aml_dma_request_linux_par *ret; struct aml_dma_linux_par_request_data *req; + int err = AML_SUCCESS; pthread_mutex_lock(&dma->data.lock); req = aml_vector_add(dma->data.requests); @@ -101,6 +103,10 @@ int aml_dma_linux_par_create_request(struct aml_dma_data *d, dl = va_arg(ap, struct aml_layout *); sl = va_arg(ap, struct aml_layout *); + if (dl == NULL || sl == NULL) { + err = -AML_EINVAL; + goto unlock; + } aml_dma_linux_par_request_data_init(req, AML_DMA_REQUEST_TYPE_LAYOUT, dl, sl); @@ -112,17 +118,21 @@ int aml_dma_linux_par_create_request(struct aml_dma_data *d, dp = va_arg(ap, void *); sp = va_arg(ap, void *); sz = va_arg(ap, size_t); + if (dp == NULL || sp == NULL || sz == 0) { + err = -AML_EINVAL; + goto unlock; + } /* simple 1D layout, none of the parameters really matter, as * long as the copy generates a single memcpy. */ - aml_layout_dense_create(&dl, dp, 0, sizeof(size_t), 1, - &sz, NULL, NULL); - aml_layout_dense_create(&sl, sp, 0, sizeof(size_t), 1, - &sz, NULL, NULL); + aml_layout_dense_create(&dl, dp, 0, 1, 1, &sz, NULL, NULL); + aml_layout_dense_create(&sl, sp, 0, 1, 1, &sz, NULL, NULL); aml_dma_linux_par_request_data_init(req, AML_DMA_REQUEST_TYPE_PTR, dl, sl); - } + } else + err = -AML_EINVAL; +unlock: pthread_mutex_unlock(&dma->data.lock); if (req->type != AML_DMA_REQUEST_TYPE_INVALID) { int uuid = aml_vector_getid(dma->data.requests, req); @@ -131,21 +141,23 @@ int aml_dma_linux_par_create_request(struct aml_dma_data *d, aml_dma_request_linux_par_create(&ret, uuid); *r = (struct aml_dma_request *)ret; } - return 0; + return err; } int aml_dma_linux_par_destroy_request(struct aml_dma_data *d, - struct aml_dma_request *r) + struct aml_dma_request **r) { assert(d != NULL); assert(r != NULL); struct aml_dma_linux_par *dma = (struct aml_dma_linux_par *)d; - - struct aml_dma_request_linux_par *req = - (struct aml_dma_request_linux_par *)r; + struct aml_dma_request_linux_par *req; struct aml_dma_linux_par_request_data *inner_req; + if (*r == NULL) + return -AML_EINVAL; + req = (struct aml_dma_request_linux_par *)*r; + inner_req = aml_vector_get(dma->data.requests, req->uuid); if (inner_req == NULL) return -AML_EINVAL; @@ -154,44 +166,49 @@ int aml_dma_linux_par_destroy_request(struct aml_dma_data *d, if (inner_req->type != AML_DMA_REQUEST_TYPE_INVALID) { pthread_cancel(inner_req->thread); pthread_join(inner_req->thread, NULL); - if (inner_req->type == AML_DMA_REQUEST_TYPE_PTR) { - aml_layout_dense_destroy(&inner_req->dest); - aml_layout_dense_destroy(&inner_req->src); - } + } + + if (inner_req->type == AML_DMA_REQUEST_TYPE_PTR) { + aml_layout_dense_destroy(&inner_req->dest); + aml_layout_dense_destroy(&inner_req->src); } pthread_mutex_lock(&dma->data.lock); aml_vector_remove(dma->data.requests, inner_req); pthread_mutex_unlock(&dma->data.lock); aml_dma_request_linux_par_destroy(&req); + *r = NULL; return 0; } int aml_dma_linux_par_wait_request(struct aml_dma_data *d, - struct aml_dma_request *r) + struct aml_dma_request **r) { assert(d != NULL); assert(r != NULL); struct aml_dma_linux_par *dma = (struct aml_dma_linux_par *)d; - struct aml_dma_request_linux_par *req = - (struct aml_dma_request_linux_par *)r; + struct aml_dma_request_linux_par *req; struct aml_dma_linux_par_request_data *inner_req; + if (*r == NULL) + return -AML_EINVAL; + req = (struct aml_dma_request_linux_par *)*r; + inner_req = aml_vector_get(dma->data.requests, req->uuid); if (inner_req == NULL) return -AML_EINVAL; - if (inner_req->type != AML_DMA_REQUEST_TYPE_INVALID) { + if (inner_req->type != AML_DMA_REQUEST_TYPE_INVALID) pthread_join(inner_req->thread, NULL); - if (inner_req->type == AML_DMA_REQUEST_TYPE_PTR) { - aml_layout_dense_destroy(&inner_req->dest); - aml_layout_dense_destroy(&inner_req->src); - } - } + if (inner_req->type == AML_DMA_REQUEST_TYPE_PTR) { + aml_layout_dense_destroy(&inner_req->dest); + aml_layout_dense_destroy(&inner_req->src); + } pthread_mutex_lock(&dma->data.lock); aml_vector_remove(dma->data.requests, inner_req); pthread_mutex_unlock(&dma->data.lock); aml_dma_request_linux_par_destroy(&req); + *r = NULL; return 0; } @@ -236,22 +253,28 @@ int aml_dma_linux_par_create(struct aml_dma **dma, size_t nbreqs) return 0; } -void aml_dma_linux_par_destroy(struct aml_dma **dma) +void aml_dma_linux_par_destroy(struct aml_dma **d) { - struct aml_dma *d; - struct aml_dma_linux_par *l; + struct aml_dma_linux_par *dma; - if (dma == NULL) - return; - d = *dma; - if (d == NULL) + if (d == NULL || *d == NULL) return; - - assert(d->data != NULL); - l = (struct aml_dma_linux_par *)d->data; - aml_vector_destroy(&l->data.requests); - pthread_mutex_destroy(&l->data.lock); - - free(d); - *dma = NULL; + dma = (struct aml_dma_linux_par *)(*d)->data; + for (size_t i = 0; i < aml_vector_size(dma->data.requests); i++) { + struct aml_dma_linux_par_request_data *req; + + req = aml_vector_get(dma->data.requests, i); + if (req->type != AML_DMA_REQUEST_TYPE_INVALID) { + pthread_cancel(req->thread); + pthread_join(req->thread, NULL); + } + if (req->type == AML_DMA_REQUEST_TYPE_PTR) { + aml_layout_dense_destroy(&req->dest); + aml_layout_dense_destroy(&req->src); + } + } + aml_vector_destroy(&dma->data.requests); + pthread_mutex_destroy(&dma->data.lock); + free(*d); + *d = NULL; } diff --git a/src/dma/dma_linux_seq.c b/src/dma/dma_linux_seq.c index 71eca966d115f3efc940d627cf662a3c91645320..a9a8be266873c9c03e2d8a4316cb90ae5f45d83c 100644 --- a/src/dma/dma_linux_seq.c +++ b/src/dma/dma_linux_seq.c @@ -90,6 +90,7 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d, (struct aml_dma_linux_seq *)d; struct aml_dma_request_linux_seq *ret; struct aml_dma_linux_seq_request_data *req; + int err = AML_SUCCESS; pthread_mutex_lock(&dma->data.lock); req = aml_vector_add(dma->data.requests); @@ -100,6 +101,10 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d, dl = va_arg(ap, struct aml_layout *); sl = va_arg(ap, struct aml_layout *); + if (dl == NULL || sl == NULL) { + err = -AML_EINVAL; + goto unlock; + } aml_dma_linux_seq_request_data_init(req, AML_DMA_REQUEST_TYPE_LAYOUT, dl, sl); @@ -111,38 +116,46 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d, dp = va_arg(ap, void *); sp = va_arg(ap, void *); sz = va_arg(ap, size_t); + if (dp == NULL || sp == NULL || sz == 0) { + err = -AML_EINVAL; + goto unlock; + } /* simple 1D layout, none of the parameters really matter, as * long as the copy generates a single memcpy. */ - aml_layout_dense_create(&dl, dp, 0, sizeof(size_t), 1, - &sz, NULL, NULL); - aml_layout_dense_create(&sl, sp, 0, sizeof(size_t), 1, - &sz, NULL, NULL); + aml_layout_dense_create(&dl, dp, 0, 1, 1, &sz, NULL, NULL); + aml_layout_dense_create(&sl, sp, 0, 1, 1, &sz, NULL, NULL); aml_dma_linux_seq_request_data_init(req, AML_DMA_REQUEST_TYPE_PTR, dl, sl); - } - int uuid = aml_vector_getid(dma->data.requests, req); - - assert(uuid != AML_DMA_REQUEST_TYPE_INVALID); - aml_dma_request_linux_seq_create(&ret, uuid); - *r = (struct aml_dma_request *)ret; + } else + err = -AML_EINVAL; +unlock: pthread_mutex_unlock(&dma->data.lock); - return 0; + if (req->type != AML_DMA_REQUEST_TYPE_INVALID) { + int uuid = aml_vector_getid(dma->data.requests, req); + + assert(uuid != AML_DMA_REQUEST_TYPE_INVALID); + aml_dma_request_linux_seq_create(&ret, uuid); + *r = (struct aml_dma_request *)ret; + } + return err; } int aml_dma_linux_seq_destroy_request(struct aml_dma_data *d, - struct aml_dma_request *r) + struct aml_dma_request **r) { assert(d != NULL); assert(r != NULL); struct aml_dma_linux_seq *dma = (struct aml_dma_linux_seq *)d; - - struct aml_dma_request_linux_seq *req = - (struct aml_dma_request_linux_seq *)r; + struct aml_dma_request_linux_seq *req; struct aml_dma_linux_seq_request_data *inner_req; + if (*r == NULL) + return -AML_EINVAL; + req = (struct aml_dma_request_linux_seq *)*r; + inner_req = aml_vector_get(dma->data.requests, req->uuid); if (inner_req == NULL) return -AML_EINVAL; @@ -153,23 +166,26 @@ int aml_dma_linux_seq_destroy_request(struct aml_dma_data *d, aml_layout_dense_destroy(&inner_req->src); } - /* enough to remove from request vector */ aml_vector_remove(dma->data.requests, inner_req); pthread_mutex_unlock(&dma->data.lock); aml_dma_request_linux_seq_destroy(&req); + *r = NULL; return 0; } int aml_dma_linux_seq_wait_request(struct aml_dma_data *d, - struct aml_dma_request *r) + struct aml_dma_request **r) { assert(d != NULL); assert(r != NULL); struct aml_dma_linux_seq *dma = (struct aml_dma_linux_seq *)d; - struct aml_dma_request_linux_seq *req = - (struct aml_dma_request_linux_seq *)r; + struct aml_dma_request_linux_seq *req; struct aml_dma_linux_seq_request_data *inner_req; + if (*r == NULL) + return -AML_EINVAL; + req = (struct aml_dma_request_linux_seq *)*r; + inner_req = aml_vector_get(dma->data.requests, req->uuid); if (inner_req == NULL) return -AML_EINVAL; diff --git a/src/layout/dense.c b/src/layout/dense.c index 2b2b3b82bdf518499b98469afde4f475277d3193..082f246f6aca51cb602a9ab283a77b977c1601e2 100644 --- a/src/layout/dense.c +++ b/src/layout/dense.c @@ -87,7 +87,8 @@ int aml_layout_dense_create(struct aml_layout **layout, struct aml_layout_dense *data; int err; - if (layout == NULL) + if (layout == NULL || ptr == NULL || !element_size || !ndims || + dims == NULL) return -AML_EINVAL; err = aml_layout_dense_alloc(&l, ndims); @@ -111,8 +112,6 @@ int aml_layout_dense_create(struct aml_layout **layout, else data->pitch[i] = dims[ndims-i-1]; } - for (size_t i = 1; i <= ndims; i++) - data->cpitch[i] = data->cpitch[i-1]*pitch[ndims-i]; break; case AML_LAYOUT_ORDER_COLUMN_MAJOR: @@ -124,14 +123,14 @@ int aml_layout_dense_create(struct aml_layout **layout, memcpy(data->pitch, pitch, ndims * sizeof(size_t)); else memcpy(data->pitch, dims, ndims * sizeof(size_t)); - for (size_t i = 1; i <= ndims; i++) - data->cpitch[i] = data->cpitch[i-1]*data->pitch[i-1]; break; default: free(l); return -AML_EINVAL; } + for (size_t i = 1; i <= ndims; i++) + data->cpitch[i] = data->cpitch[i-1]*data->pitch[i-1]; *layout = l; return AML_SUCCESS; diff --git a/src/scratch/scratch_seq.c b/src/scratch/scratch_seq.c index f5e68ed81cc585e50ef3a28a0d5bfa4f73e568ad..bcec3b38c077e7fc1ca4b5167eb184654edc26b1 100644 --- a/src/scratch/scratch_seq.c +++ b/src/scratch/scratch_seq.c @@ -183,7 +183,7 @@ int aml_scratch_seq_destroy_request(struct aml_scratch_data *d, return -AML_EINVAL; if (inner_req->type != AML_SCRATCH_REQUEST_TYPE_NOOP) - aml_dma_cancel(scratch->data.dma, inner_req->dma_req); + aml_dma_cancel(scratch->data.dma, &inner_req->dma_req); /* destroy removes the tile from the scratch */ if (inner_req->type == AML_SCRATCH_REQUEST_TYPE_PUSH) @@ -215,7 +215,7 @@ int aml_scratch_seq_wait_request(struct aml_scratch_data *d, /* wait for completion of the request */ if (inner_req->type != AML_SCRATCH_REQUEST_TYPE_NOOP) - aml_dma_wait(scratch->data.dma, inner_req->dma_req); + aml_dma_wait(scratch->data.dma, &inner_req->dma_req); /* cleanup a completed request. In case of push, free up the tile */ pthread_mutex_lock(&scratch->data.lock); diff --git a/src/utils/bitmap.c b/src/utils/bitmap.c index f282e3fd4b4c67a70d476fe74954432d283435ea..aba41152ed2b9a0cb84b7ab6332b9e8957e4930e 100644 --- a/src/utils/bitmap.c +++ b/src/utils/bitmap.c @@ -50,13 +50,18 @@ void aml_bitmap_copy_to_ulong(const struct aml_bitmap *dst, src[AML_BITMAP_NTH(i)] |= (1UL << AML_BITMAP_ITH(i)); } -void aml_bitmap_zero(struct aml_bitmap *bitmap) +int aml_bitmap_zero(struct aml_bitmap *bitmap) { + if (bitmap == NULL) + return -AML_EINVAL; memset(bitmap, 0, sizeof(struct aml_bitmap)); + return 0; } int aml_bitmap_iszero(const struct aml_bitmap *bitmap) { + if (bitmap == NULL) + return -AML_EINVAL; for (unsigned int i = 0; i < AML_BITMAP_SIZE; i++) if (bitmap->mask[i] != AML_BITMAP_EMPTY) return 0; @@ -65,35 +70,46 @@ int aml_bitmap_iszero(const struct aml_bitmap *bitmap) int aml_bitmap_isfull(const struct aml_bitmap *bitmap) { + if (bitmap == NULL) + return -AML_EINVAL; for (unsigned int i = 0; i < AML_BITMAP_SIZE; i++) if (bitmap->mask[i] != AML_BITMAP_FULL) return 0; return 1; } -void aml_bitmap_fill(struct aml_bitmap *bitmap) +int aml_bitmap_fill(struct aml_bitmap *bitmap) { + if (bitmap == NULL) + return -AML_EINVAL; memset(bitmap, ~0, sizeof(struct aml_bitmap)); + return 0; } int aml_bitmap_isset(const struct aml_bitmap *bitmap, const unsigned int i) { + if (bitmap == NULL) + return -AML_EINVAL; if (i >= AML_BITMAP_MAX) - return -1; + return -AML_EINVAL; return (bitmap->mask[AML_BITMAP_NTH(i)] & (1UL << AML_BITMAP_ITH(i))) > 0UL; } int aml_bitmap_set(struct aml_bitmap *bitmap, const unsigned int i) { + if (bitmap == NULL) + return -AML_EINVAL; if (i >= AML_BITMAP_MAX) - return -1; + return -AML_EINVAL; bitmap->mask[AML_BITMAP_NTH(i)] |= (1UL << AML_BITMAP_ITH(i)); return 0; } int aml_bitmap_isequal(const struct aml_bitmap *a, const struct aml_bitmap *b) { + if (a == NULL || b == NULL) + return -AML_EINVAL; for (unsigned int i = 0; i < AML_BITMAP_SIZE; i++) if (a->mask[i] != b->mask[i]) return 0; @@ -102,8 +118,10 @@ int aml_bitmap_isequal(const struct aml_bitmap *a, const struct aml_bitmap *b) int aml_bitmap_clear(struct aml_bitmap *bitmap, const unsigned int i) { + if (bitmap == NULL) + return -AML_EINVAL; if (i >= AML_BITMAP_MAX) - return -1; + return -AML_EINVAL; bitmap->mask[AML_BITMAP_NTH(i)] &= ~(1UL << AML_BITMAP_ITH(i)); return 0; } @@ -111,8 +129,10 @@ int aml_bitmap_clear(struct aml_bitmap *bitmap, const unsigned int i) int aml_bitmap_set_range(struct aml_bitmap *bitmap, const unsigned int i, const unsigned int ii) { + if (bitmap == NULL) + return -AML_EINVAL; if (i >= AML_BITMAP_MAX || ii >= AML_BITMAP_MAX || i > ii) - return -1; + return -AML_EINVAL; if (i == ii) return aml_bitmap_set(bitmap, i); @@ -136,8 +156,10 @@ int aml_bitmap_set_range(struct aml_bitmap *bitmap, int aml_bitmap_clear_range(struct aml_bitmap *bitmap, const unsigned int i, const unsigned int ii) { + if (bitmap == NULL) + return -AML_EINVAL; if (i >= AML_BITMAP_MAX || ii >= AML_BITMAP_MAX || i > ii) - return -1; + return -AML_EINVAL; if (i == ii) return aml_bitmap_clear(bitmap, i); @@ -158,15 +180,18 @@ int aml_bitmap_clear_range(struct aml_bitmap *bitmap, return 0; } -unsigned long aml_bitmap_nset(const struct aml_bitmap *bitmap) +int aml_bitmap_nset(const struct aml_bitmap *bitmap) { - unsigned long i, b, n; unsigned long test = 1UL; - unsigned long nset = 0; + int nset = 0; - for (n = 0; n < AML_BITMAP_SIZE; n++) { - b = bitmap->mask[n]; - for (i = 0; i < AML_BITMAP_NBITS; i++) { + if (bitmap == NULL) + return -AML_EINVAL; + + for (int n = 0; n < AML_BITMAP_SIZE; n++) { + unsigned long b = bitmap->mask[n]; + + for (int i = 0; i < AML_BITMAP_NBITS; i++) { nset += b & test ? 1 : 0; b = b >> 1; } @@ -176,11 +201,12 @@ unsigned long aml_bitmap_nset(const struct aml_bitmap *bitmap) int aml_bitmap_last(const struct aml_bitmap *bitmap) { - if (bitmap == NULL) - return -1; int n; unsigned int i = 0; + if (bitmap == NULL) + return -AML_EINVAL; + for (n = AML_BITMAP_SIZE - 1; n >= 0 && bitmap->mask[n] == 0; n--) ; @@ -301,6 +327,9 @@ int aml_bitmap_from_string(struct aml_bitmap *bitmap, const char *bitmap_str) int aml_bitmap_create(struct aml_bitmap **map) { + if (map == NULL) + return -AML_EINVAL; + struct aml_bitmap *b = calloc(1, sizeof(struct aml_bitmap)); if (b == NULL) { @@ -319,6 +348,9 @@ int aml_bitmap_create(struct aml_bitmap **map) **/ void aml_bitmap_destroy(struct aml_bitmap **map) { + if (map == NULL) + return; + free(*map); *map = NULL; } diff --git a/tests/dma/test_dma_linux_par.c b/tests/dma/test_dma_linux_par.c index ac3f67fe4202ec4243988b9e2525b6d2bd29e19e..ebf37559742b3ed45c99459bd3a0b77f0cd70450 100644 --- a/tests/dma/test_dma_linux_par.c +++ b/tests/dma/test_dma_linux_par.c @@ -9,56 +9,94 @@ *******************************************************************************/ #include "aml.h" -#include "aml/area/linux.h" +#include "aml/layout/dense.h" #include "aml/dma/linux-par.h" -#include "aml/tiling/1d.h" #include -#define TILESIZE (2) -#define NBTILES (16) - int main(int argc, char *argv[]) { - struct aml_tiling *tiling; struct aml_dma *dma; - void *dst, *src; + size_t isz = 1<<16; + int idest[isz]; + int isrc[isz]; + struct aml_layout *idl, *isl; /* library initialization */ aml_init(&argc, &argv); - /* initialize all the supporting struct */ - assert(!aml_tiling_1d_create(&tiling, TILESIZE*_SC_PAGE_SIZE, - TILESIZE*_SC_PAGE_SIZE*NBTILES)); + /* support data structures */ + assert(!aml_layout_dense_create(&idl, idest, 0, sizeof(int), 1, &isz, + NULL, NULL)); + assert(!aml_layout_dense_create(&isl, isrc, 0, sizeof(int), 1, &isz, + NULL, NULL)); + for (size_t i = 0; i < isz; i++) { + idest[i] = 42; + isrc[i] = 24; + } + /* invalid create input */ + assert(aml_dma_linux_par_create(NULL, 1) == -AML_EINVAL); + + /* invalid requests */ assert(!aml_dma_linux_par_create(&dma, 1)); + assert(aml_dma_copy(dma, 42) == -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_PTR, NULL, isrc, isz) == + -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_PTR, idest, NULL, isz) == + -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_PTR, idest, isrc, 0) == + -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_LAYOUT, NULL, isl) == + -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_LAYOUT, idl, NULL) == + -AML_EINVAL); - /* allocate some memory */ - src = aml_area_mmap(&aml_area_linux, NULL, TILESIZE*_SC_PAGE_SIZE*NBTILES); - assert(src != NULL); - dst = aml_area_mmap(&aml_area_linux, NULL, TILESIZE*_SC_PAGE_SIZE*NBTILES); - assert(dst != NULL); + struct aml_dma_request *r1, *r2; + /* force dma to increase its requests queue */ + assert(!aml_dma_async_copy(dma, &r1, AML_DMA_REQUEST_TYPE_LAYOUT, + idl, isl)); + assert(!aml_dma_async_copy(dma, &r2, AML_DMA_REQUEST_TYPE_LAYOUT, + idl, isl)); - memset(src, 42, TILESIZE*_SC_PAGE_SIZE*NBTILES); - memset(dst, 24, TILESIZE*_SC_PAGE_SIZE*NBTILES); + assert(aml_dma_wait(dma, NULL) == -AML_EINVAL); + assert(!aml_dma_wait(dma, &r1)); + assert(!aml_dma_wait(dma, &r2)); + aml_dma_linux_par_destroy(&dma); + + /* cancel a request on the fly */ + assert(!aml_dma_linux_par_create(&dma, 1)); + assert(aml_dma_cancel(dma, NULL) == -AML_EINVAL); + assert(!aml_dma_async_copy(dma, &r1, AML_DMA_REQUEST_TYPE_LAYOUT, + idl, isl)); + assert(!aml_dma_cancel(dma, &r1)); - /* move some stuff by copy */ - struct aml_dma_request *requests[NBTILES]; - for(int i = 0; i < NBTILES; i++) { - void *d = aml_tiling_tilestart(tiling, dst, i); - void *s = aml_tiling_tilestart(tiling, src, i); - aml_dma_async_copy(dma, &requests[i], AML_DMA_REQUEST_TYPE_PTR, - d, s, TILESIZE*_SC_PAGE_SIZE); + /* destroy a running dma */ + assert(!aml_dma_async_copy(dma, &r1, AML_DMA_REQUEST_TYPE_LAYOUT, + idl, isl)); + aml_dma_linux_par_destroy(&dma); + + /* move data around */ + assert(!aml_dma_linux_par_create(&dma, 1)); + struct aml_dma_request *requests[16]; + for (int i = 0; i < 16; i++) { + size_t sz = isz/16; + size_t off = i*sz; + void *dptr = (void *)&(idest[off]); + void *sptr = (void *)&(isrc[off]); + + assert(!aml_dma_async_copy(dma, &requests[i], + AML_DMA_REQUEST_TYPE_PTR, + dptr, sptr, sz*sizeof(int))); + assert(requests[i] != NULL); } - for(int i = 0; i < NBTILES; i++) - aml_dma_wait(dma, requests[i]); + for(int i = 0; i < 16; i++) + assert(!aml_dma_wait(dma, &requests[i])); - assert(!memcmp(src, dst, TILESIZE*_SC_PAGE_SIZE*NBTILES)); + assert(!memcmp(isrc, idest, isz*sizeof(int))); /* delete everything */ aml_dma_linux_par_destroy(&dma); - aml_area_munmap(&aml_area_linux, dst, TILESIZE*_SC_PAGE_SIZE*NBTILES); - aml_area_munmap(&aml_area_linux, src, TILESIZE*_SC_PAGE_SIZE*NBTILES); - aml_tiling_1d_destroy(&tiling); - + aml_layout_dense_destroy(&idl); + aml_layout_dense_destroy(&isl); aml_finalize(); return 0; } diff --git a/tests/dma/test_dma_linux_seq.c b/tests/dma/test_dma_linux_seq.c index 393cdde39e7e156f1f2a1c340d7bf5486eefc225..c3e1c1a04af1cdb30e69f6a3e3db8c2b29422c7a 100644 --- a/tests/dma/test_dma_linux_seq.c +++ b/tests/dma/test_dma_linux_seq.c @@ -9,58 +9,91 @@ *******************************************************************************/ #include "aml.h" -#include "aml/area/linux.h" +#include "aml/layout/dense.h" #include "aml/dma/linux-seq.h" -#include "aml/tiling/1d.h" #include -#define TILESIZE (2) -#define NBTILES (16) - int main(int argc, char *argv[]) { - struct aml_tiling *tiling; struct aml_dma *dma; - void *dst, *src; + size_t isz = 1<<16; + int idest[isz]; + int isrc[isz]; + struct aml_layout *idl, *isl; /* library initialization */ aml_init(&argc, &argv); - /* initialize all the supporting struct */ - assert(!aml_tiling_1d_create(&tiling, TILESIZE*_SC_PAGE_SIZE, - TILESIZE*_SC_PAGE_SIZE*NBTILES)); + /* support data structures */ + assert(!aml_layout_dense_create(&idl, idest, 0, sizeof(int), 1, &isz, + NULL, NULL)); + assert(!aml_layout_dense_create(&isl, isrc, 0, sizeof(int), 1, &isz, + NULL, NULL)); + for (size_t i = 0; i < isz; i++) { + idest[i] = 42; + isrc[i] = 24; + } + /* invalid create input */ + assert(aml_dma_linux_seq_create(NULL, 1) == -AML_EINVAL); + + /* invalid requests */ assert(!aml_dma_linux_seq_create(&dma, 1)); + assert(aml_dma_copy(dma, 42) == -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_PTR, NULL, isrc, isz) == + -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_PTR, idest, NULL, isz) == + -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_PTR, idest, isrc, 0) == + -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_LAYOUT, NULL, isl) == + -AML_EINVAL); + assert(aml_dma_copy(dma, AML_DMA_REQUEST_TYPE_LAYOUT, idl, NULL) == + -AML_EINVAL); + + struct aml_dma_request *r1, *r2; + /* force dma to increase its requests queue */ + assert(!aml_dma_async_copy(dma, &r1, AML_DMA_REQUEST_TYPE_LAYOUT, + idl, isl)); + assert(!aml_dma_async_copy(dma, &r2, AML_DMA_REQUEST_TYPE_LAYOUT, + idl, isl)); + + assert(aml_dma_wait(dma, NULL) == -AML_EINVAL); + assert(!aml_dma_wait(dma, &r1)); + assert(!aml_dma_wait(dma, &r2)); - /* allocate some memory */ - src = aml_area_mmap(&aml_area_linux, NULL, TILESIZE*_SC_PAGE_SIZE*NBTILES); - assert(src != NULL); - dst = aml_area_mmap(&aml_area_linux, NULL, TILESIZE*_SC_PAGE_SIZE*NBTILES); - assert(dst != NULL); + /* cancel a request on the fly */ + assert(aml_dma_cancel(dma, NULL) == -AML_EINVAL); + assert(!aml_dma_async_copy(dma, &r1, AML_DMA_REQUEST_TYPE_LAYOUT, + idl, isl)); + assert(!aml_dma_cancel(dma, &r1)); - memset(src, 42, TILESIZE*_SC_PAGE_SIZE*NBTILES); - memset(dst, 24, TILESIZE*_SC_PAGE_SIZE*NBTILES); - /* move some stuff by copy */ - struct aml_dma_request *requests[NBTILES]; - for(int i = 0; i < NBTILES; i++) { - void *d = aml_tiling_tilestart(tiling, dst, i); - void *s = aml_tiling_tilestart(tiling, src, i); + /* destroy a running dma */ + assert(!aml_dma_async_copy(dma, &r1, AML_DMA_REQUEST_TYPE_LAYOUT, + idl, isl)); + aml_dma_linux_seq_destroy(&dma); + + /* move data around */ + assert(!aml_dma_linux_seq_create(&dma, 1)); + struct aml_dma_request *requests[16]; + for (int i = 0; i < 16; i++) { + size_t sz = isz/16; + size_t off = i*sz; + void *dptr = (void *)&(idest[off]); + void *sptr = (void *)&(isrc[off]); + assert(!aml_dma_async_copy(dma, &requests[i], AML_DMA_REQUEST_TYPE_PTR, - d, s, (size_t)TILESIZE*_SC_PAGE_SIZE)); + dptr, sptr, sz*sizeof(int))); assert(requests[i] != NULL); } - for(int i = 0; i < NBTILES; i++) - assert(!aml_dma_wait(dma, requests[i])); + for(int i = 0; i < 16; i++) + assert(!aml_dma_wait(dma, &requests[i])); - assert(!memcmp(src, dst, TILESIZE*_SC_PAGE_SIZE*NBTILES)); + assert(!memcmp(isrc, idest, isz*sizeof(int))); /* delete everything */ aml_dma_linux_seq_destroy(&dma); - aml_area_munmap(&aml_area_linux, dst, TILESIZE*_SC_PAGE_SIZE*NBTILES); - aml_area_munmap(&aml_area_linux, src, TILESIZE*_SC_PAGE_SIZE*NBTILES); - aml_tiling_1d_destroy(&tiling); - aml_finalize(); return 0; } diff --git a/tests/layout/test_layout.c b/tests/layout/test_layout.c index 1dfb2a13627d3199406f7ed28772d075225d0aab..7673c67065cae13eb28149869d1e8a42d35ff93c 100644 --- a/tests/layout/test_layout.c +++ b/tests/layout/test_layout.c @@ -55,8 +55,8 @@ void test_slice_contiguous(void) //fprintf(stderr, "%d == %d\n", val, *(int *)ptr); assert( val == *(int *)ptr); } - free(a); - free(b); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); assert(aml_layout_dense_create(&a, (void *) memory, @@ -85,8 +85,8 @@ void test_slice_contiguous(void) assert( val == *(int *)ptr); } - free(a); - free(b); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); } void test_slice_strided(void) @@ -140,8 +140,8 @@ void test_slice_strided(void) stride[0] * (offsets_col[0] + new_stride_col[0] * k)] == *(int *)ptr); } - free(a); - free(b); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); assert(aml_layout_dense_create(&a, (void *) memory, @@ -163,8 +163,8 @@ void test_slice_strided(void) assert( memory[stride[2] * (offsets_col[2] + new_stride_col[2] * i)][stride[1] * (offsets_col[1] + new_stride_col[1] * j)][stride[0] * (offsets_col[0] + new_stride_col[0] * k)] == *(int *)ptr); } - free(a); - free(b); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); } @@ -218,9 +218,9 @@ void test_reshape_contiguous(void) assert(i == *(int *)c_ptr); } - free(a); - free(b); - free(c); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); + aml_layout_dense_destroy(&c); assert(aml_layout_dense_create(&a, (void *) memory, @@ -250,9 +250,9 @@ void test_reshape_contiguous(void) assert(i == *(int *)c_ptr); } - free(a); - free(b); - free(c); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); + aml_layout_dense_destroy(&c); } void test_reshape_discontiguous(void) @@ -315,9 +315,9 @@ void test_reshape_discontiguous(void) assert(i == *(int *)ptr); } - free(a); - free(b); - free(c); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); + aml_layout_dense_destroy(&c); assert(aml_layout_dense_create(&a, (void *) memory, @@ -353,9 +353,9 @@ void test_reshape_discontiguous(void) assert(i == *(int *)ptr); } - free(a); - free(b); - free(c); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); + aml_layout_dense_destroy(&c); } void test_reshape_strided(void) @@ -416,9 +416,9 @@ void test_reshape_strided(void) assert(i == *(int *)ptr); } - free(a); - free(b); - free(c); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); + aml_layout_dense_destroy(&c); assert(aml_layout_dense_create(&a, (void *) memory, @@ -452,9 +452,9 @@ void test_reshape_strided(void) assert(i == *(int *)ptr); } - free(a); - free(b); - free(c); + aml_layout_dense_destroy(&a); + aml_layout_dense_destroy(&b); + aml_layout_dense_destroy(&c); } void test_base(void) @@ -469,7 +469,7 @@ void test_base(void) size_t stride[5] = {1, 2, 1, 1, 1}; size_t dims_col[5] = {2, 3, 7, 11, 13}; - size_t dims_row[5] = {13, 11, 7, 3, 2}; + size_t dims_row[5] = {13, 11, 7, 3, 2}; size_t pitch_col[5] = {4, 8, 8, 12, 16}; size_t pitch_row[5] = {16, 12, 8, 8, 4}; @@ -477,9 +477,52 @@ void test_base(void) size_t stride_col[5] = {1, 2, 1, 1, 1}; size_t stride_row[5] = {1, 1, 1, 2, 1}; - for(size_t i = 0; i < 4*8*8*12*16; i++) + for(size_t i = 0; i < 4*8*8*12*16; i++) ((float*)(&memory[0][0][0][0][0]))[i] = (float)i; + /* test invalid input */ + assert(aml_layout_dense_create(NULL, (void *) memory, + AML_LAYOUT_ORDER_COLUMN_MAJOR, + sizeof(int), 5, dims_col, stride_col, + pitch_col) == -AML_EINVAL); + assert(aml_layout_dense_create(&a, NULL, + AML_LAYOUT_ORDER_COLUMN_MAJOR, + sizeof(int), 5, dims_col, stride_col, + pitch_col) == -AML_EINVAL); + /* missing: we don't test the tags/order value */ + assert(aml_layout_dense_create(&a, (void *) memory, + AML_LAYOUT_ORDER_COLUMN_MAJOR, + 0, 5, dims_col, stride_col, + pitch_col) == -AML_EINVAL); + assert(aml_layout_dense_create(&a, (void *) memory, + AML_LAYOUT_ORDER_COLUMN_MAJOR, + sizeof(int), 0, dims_col, stride_col, + pitch_col) == -AML_EINVAL); + assert(aml_layout_dense_create(&a, (void *) memory, + AML_LAYOUT_ORDER_COLUMN_MAJOR, + sizeof(int), 5, NULL, stride_col, + pitch_col) == -AML_EINVAL); + aml_layout_dense_destroy(NULL); + + /* test partial data */ + assert(aml_layout_dense_create(&a, + (void *) memory, + AML_LAYOUT_ORDER_COLUMN_MAJOR, + sizeof(int), + 5, + dims_col, + NULL, + pitch_col) == AML_SUCCESS); + aml_layout_dense_destroy(&a); + assert(aml_layout_dense_create(&a, + (void *) memory, + AML_LAYOUT_ORDER_COLUMN_MAJOR, + sizeof(int), + 5, + dims_col, + stride_col, + NULL) == AML_SUCCESS); + aml_layout_dense_destroy(&a); /* initialize column order layouts */ assert(aml_layout_dense_create(&a, @@ -533,16 +576,32 @@ void test_base(void) assert(res_addr == test_addr); assert(AML_LAYOUT_ORDER_COLUMN_MAJOR == aml_layout_order(a)); - free(a); + aml_layout_dense_destroy(&a); + + /* test partial data */ + assert(aml_layout_dense_create(&a, + (void *) memory, + AML_LAYOUT_ORDER_ROW_MAJOR, + sizeof(float), + 5, dims_row, + NULL, + pitch_row) == AML_SUCCESS); + aml_layout_dense_destroy(&a); + assert(aml_layout_dense_create(&a, (void *) memory, + AML_LAYOUT_ORDER_ROW_MAJOR, + sizeof(float), + 5, dims_row, + stride_row, + NULL) == AML_SUCCESS); + aml_layout_dense_destroy(&a); /* initialize row order layouts */ - aml_layout_dense_create(&a, - (void *)memory, - AML_LAYOUT_ORDER_ROW_MAJOR, - sizeof(float), - 5, dims_row, - stride_row, - pitch_row); + assert(aml_layout_dense_create(&a, (void *) memory, + AML_LAYOUT_ORDER_ROW_MAJOR, + sizeof(float), + 5, dims_row, + stride_row, + pitch_row) == AML_SUCCESS); adataptr = (struct aml_layout_dense *)a->data; bdataptr = (struct aml_layout_dense *)b->data; @@ -571,7 +630,7 @@ void test_base(void) assert(res_addr == test_addr); assert(AML_LAYOUT_ORDER_ROW_MAJOR == aml_layout_order(a)); - free(a); + aml_layout_dense_destroy(&a); } int main(int argc, char *argv[]) diff --git a/tests/utils/test_bitmap.c b/tests/utils/test_bitmap.c index fde289cbce727be5d8923438a0a9a8bb9c7ce68c..b917edfeb5d4b6e9e7cc65e6a8a784a701cdade5 100644 --- a/tests/utils/test_bitmap.c +++ b/tests/utils/test_bitmap.c @@ -11,108 +11,163 @@ #include "aml.h" #include -void test_bitmap_fill(){ - unsigned long i; - struct aml_bitmap b; - aml_bitmap_fill(&b); - for(i = 0; i < AML_BITMAP_MAX; i++) - assert(aml_bitmap_isset(&b, i)); - assert(aml_bitmap_nset(&b) == AML_BITMAP_MAX); -} +/* set of bits that are interesting to test. In increasing order by design, for + * the range tests. + * - first one + * - middle of a backing element + * - last one in the middle of the backing array + * - middle of a backing element + * - first one in the middle of the backing array + * - middle of a backing element + * - last one + */ +#define NTESTS 7 +#define TESTS_IDX {0, AML_BITMAP_NBITS + 16, \ + (2*AML_BITMAP_NBITS) - 1, (2*AML_BITMAP_NBITS) + 16, \ + 3*AML_BITMAP_NBITS, (3*AML_BITMAP_NBITS) + 16, AML_BITMAP_MAX - 1} +#define TESTS_OFF {0, 1, 1, 2, 3, 3, AML_BITMAP_SIZE - 1} -void test_bitmap_zero(){ - unsigned long i; - struct aml_bitmap b; - aml_bitmap_zero(&b); - for(i = 0; i < AML_BITMAP_MAX; i++) - assert(!aml_bitmap_isset(&b, i)); - assert(aml_bitmap_nset(&b) == 0); -} +int main(void) +{ + struct aml_bitmap *bitmap; + int idx[NTESTS] = TESTS_IDX; + int off[NTESTS] = TESTS_OFF; + + /* create/destroy should fail on NULL */ + assert(aml_bitmap_create(NULL) == -AML_EINVAL); + aml_bitmap_destroy(NULL); + + /* create should succeed with a pointer */ + assert(aml_bitmap_create(&bitmap) == AML_SUCCESS); + assert(bitmap != NULL); + + /* access the mask just to be sure */ + assert(bitmap->mask[0] == 0); + aml_bitmap_destroy(&bitmap); + assert(bitmap == NULL); -void test_bitmap_set(){ - unsigned long i,j; - struct aml_bitmap b; + /* keep a bitmap on for the rest of the tests */ + assert(aml_bitmap_create(&bitmap) == AML_SUCCESS); - aml_bitmap_zero(&b); - for(i = 0; i < AML_BITMAP_MAX; i++){ - aml_bitmap_set(&b, i); - assert(aml_bitmap_isset(&b, i)); + /* zero should work */ + assert(aml_bitmap_zero(NULL) == -AML_EINVAL); + memset(bitmap->mask, 255, AML_BITMAP_BYTES); + assert(aml_bitmap_zero(bitmap) == AML_SUCCESS); + for (size_t i = 0; i < AML_BITMAP_SIZE; i++) + assert(bitmap->mask[i] == 0); - for(j = 0; j < i; j++) - assert(!aml_bitmap_isset(&b, j)); - for(j = i+1; j < AML_BITMAP_MAX; j++) - assert(!aml_bitmap_isset(&b, j)); + /* iszero/isfull (1) */ + assert(aml_bitmap_iszero(NULL) == -AML_EINVAL); + assert(aml_bitmap_isfull(NULL) == -AML_EINVAL); + assert(aml_bitmap_iszero(bitmap)); + assert(!aml_bitmap_isfull(bitmap)); - assert(aml_bitmap_nset(&b) == 1); - aml_bitmap_clear(&b, i); - assert(!aml_bitmap_isset(&b, i)); + /* nset (1) */ + assert(aml_bitmap_nset(bitmap) == 0); + + /* fill should work */ + assert(aml_bitmap_fill(NULL) == -AML_EINVAL); + assert(aml_bitmap_fill(bitmap) == AML_SUCCESS); + for (size_t i = 0; i < AML_BITMAP_SIZE; i++) + assert(bitmap->mask[i] != 0); + assert(!aml_bitmap_iszero(bitmap)); + assert(aml_bitmap_isfull(bitmap)); + + /* nset (2) */ + assert(aml_bitmap_nset(bitmap) == AML_BITMAP_MAX); + + /* set / clear */ + aml_bitmap_zero(bitmap); + assert(aml_bitmap_set(NULL, 0) == -AML_EINVAL); + assert(aml_bitmap_set(NULL, AML_BITMAP_MAX) == -AML_EINVAL); + for (int i = 0; i < NTESTS; i++) { + aml_bitmap_zero(bitmap); + assert(aml_bitmap_set(bitmap, idx[i]) == AML_SUCCESS); + assert(bitmap->mask[off[i]] != 0); + /* nset (3) */ + assert(aml_bitmap_nset(bitmap) == 1); + /* clear that offset and check for zero */ + bitmap->mask[off[i]] = 0; + assert(aml_bitmap_iszero(bitmap)); } -} -void test_bitmap_clear(){ - unsigned long i,j; - struct aml_bitmap b; - aml_bitmap_fill(&b); - for(i = 0; i < AML_BITMAP_MAX; i++){ - aml_bitmap_clear(&b, i); - assert(!aml_bitmap_isset(&b, i)); - - for(j = 0; j < i; j++) - assert(aml_bitmap_isset(&b, j)); - for(j = i+1; j < AML_BITMAP_MAX; j++) - assert(aml_bitmap_isset(&b, j)); - - assert(aml_bitmap_nset(&b) == (AML_BITMAP_MAX-1)); - aml_bitmap_set(&b, i); - assert(aml_bitmap_isset(&b, i)); + /* same logic for clear */ + assert(aml_bitmap_clear(NULL, 0) == -AML_EINVAL); + assert(aml_bitmap_clear(NULL, AML_BITMAP_MAX) == -AML_EINVAL); + for (int i = 0; i < NTESTS; i++) { + aml_bitmap_fill(bitmap); + assert(aml_bitmap_clear(bitmap, idx[i]) == AML_SUCCESS); + assert(bitmap->mask[off[i]] != ~0UL); + /* nset (4) */ + assert(aml_bitmap_nset(bitmap) == AML_BITMAP_MAX - 1); + /* set that offset and check for full */ + bitmap->mask[off[i]] = ~0UL; + assert(aml_bitmap_isfull(bitmap)); } -} -void test_bitmap_set_range(){ - unsigned long i, ii, j; - struct aml_bitmap b; - aml_bitmap_zero(&b); - for(i = 0; i < AML_BITMAP_MAX; i++){ - for(ii = i+1; ii < AML_BITMAP_MAX; ii++){ - assert(aml_bitmap_set_range(&b, i, ii) == 0); - assert(aml_bitmap_nset(&b) == (1 + ii - i)); - for(j = 0; j < i; j++) - assert(!aml_bitmap_isset(&b, j)); - for(j = i; j <= ii; j++) - assert(aml_bitmap_isset(&b, j)); - for(j = ii+1; j < AML_BITMAP_MAX; j++) - assert(!aml_bitmap_isset(&b, j)); - aml_bitmap_zero(&b); - } + /* idem for isset */ + assert(aml_bitmap_isset(NULL, 0) == -AML_EINVAL); + assert(aml_bitmap_isset(bitmap, AML_BITMAP_MAX) == -AML_EINVAL); + aml_bitmap_zero(bitmap); + for (int i = 1; i < NTESTS; i++) { + aml_bitmap_set(bitmap, idx[i]); + assert(aml_bitmap_isset(bitmap, idx[i])); + assert(!aml_bitmap_isset(bitmap, idx[i-1])); + aml_bitmap_clear(bitmap, idx[i]); + assert(!aml_bitmap_isset(bitmap, idx[i])); + assert(!aml_bitmap_isset(bitmap, idx[i-1])); } -} -void test_bitmap_clear_range(){ - unsigned long i, ii, j; - struct aml_bitmap b; - aml_bitmap_fill(&b); - for(i = 0; i < AML_BITMAP_MAX; i++){ - for(ii = i+1; ii < AML_BITMAP_MAX; ii++){ - assert(aml_bitmap_clear_range(&b, i, ii) == 0); - assert(aml_bitmap_nset(&b) == (AML_BITMAP_MAX-ii+i-1)); - for(j = 0; j < i; j++) - assert(aml_bitmap_isset(&b, j)); - for(j = i; j <= ii; j++) - assert(!aml_bitmap_isset(&b, j)); - for(j = ii+1; j < AML_BITMAP_MAX; j++) - assert(aml_bitmap_isset(&b, j)); - aml_bitmap_fill(&b); + /* bad input for ranges (out-of-bounds, reverse indexes) */ + assert(aml_bitmap_set_range(NULL, 0, 1) == -AML_EINVAL); + assert(aml_bitmap_set_range(bitmap, 0, AML_BITMAP_MAX) == -AML_EINVAL); + assert(aml_bitmap_set_range(bitmap, AML_BITMAP_MAX, + AML_BITMAP_MAX+1) == -AML_EINVAL); + assert(aml_bitmap_set_range(bitmap, AML_BITMAP_MAX, 0) == -AML_EINVAL); + assert(aml_bitmap_set_range(bitmap, 1, 0) == -AML_EINVAL); + + for (int i = 0; i < NTESTS; i++) { + for (int j = i; j < NTESTS; j++) { + aml_bitmap_zero(bitmap); + assert(aml_bitmap_set_range(bitmap, idx[i], idx[j]) == + AML_SUCCESS); + for (int k = 0; k < idx[i]; k++) + assert(!aml_bitmap_isset(bitmap, k)); + for (int k = idx[i]; k <= idx[j]; k++) + assert(aml_bitmap_isset(bitmap, k)); + for (int k = idx[j]+1; k < AML_BITMAP_MAX; k++) + assert(!aml_bitmap_isset(bitmap, k)); + /* nset (5) */ + assert(aml_bitmap_nset(bitmap) == 1 + idx[j] - idx[i]); } } -} -int main(){ - test_bitmap_fill(); - test_bitmap_zero(); - test_bitmap_set(); - test_bitmap_clear(); - test_bitmap_set_range(); - test_bitmap_clear_range(); + /* same logic for clear */ + assert(aml_bitmap_clear_range(NULL, 0, 1) == -AML_EINVAL); + assert(aml_bitmap_clear_range(bitmap, 0, AML_BITMAP_MAX) == + -AML_EINVAL); + assert(aml_bitmap_clear_range(bitmap, AML_BITMAP_MAX, + AML_BITMAP_MAX+1) == -AML_EINVAL); + assert(aml_bitmap_clear_range(bitmap, AML_BITMAP_MAX, 0) == + -AML_EINVAL); + assert(aml_bitmap_clear_range(bitmap, 1, 0) == -AML_EINVAL); + + for (int i = 0; i < NTESTS; i++) { + for (int j = i; j < NTESTS; j++) { + aml_bitmap_fill(bitmap); + assert(aml_bitmap_clear_range(bitmap, idx[i], idx[j]) == + AML_SUCCESS); + for (int k = 0; k < idx[i]; k++) + assert(aml_bitmap_isset(bitmap, k)); + for (int k = idx[i]; k <= idx[j]; k++) + assert(!aml_bitmap_isset(bitmap, k)); + for (int k = idx[j]+1; k < AML_BITMAP_MAX; k++) + assert(aml_bitmap_isset(bitmap, k)); + assert(aml_bitmap_nset(bitmap) == + AML_BITMAP_MAX - idx[j] + idx[i] - 1); + } + } + aml_bitmap_destroy(&bitmap); return 0; }