aboutsummaryrefslogtreecommitdiffstats
path: root/vmemalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'vmemalloc.c')
-rw-r--r--vmemalloc.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/vmemalloc.c b/vmemalloc.c
index d725374..72e65d2 100644
--- a/vmemalloc.c
+++ b/vmemalloc.c
@@ -8,8 +8,8 @@ struct memalloc_state {
size_t alignment;
size_t elem_size;
size_t size_prod;
- char zero_init;
- char if_zero;
+ signed char zero_init;
+ signed char if_zero;
char round_up_size;
char have_size;
char cache_align;
@@ -18,14 +18,16 @@ struct memalloc_state {
};
static int
-vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va_list ap)
+vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va_list ap, size_t *ap_advance_out)
{
+ *ap_advance_out = 0;
if (state->have_size++)
goto inval;
state->elem_size = arg;
if (n) {
while (--n) {
arg = va_arg(ap, size_t);
+ ++*ap_advance_out;
if (!state->elem_size)
continue;
if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(arg, state->elem_size, &state->elem_size, SIZE_MAX)) {
@@ -38,6 +40,7 @@ vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va
goto inval;
for (;;) {
arg = va_arg(ap, size_t);
+ ++*ap_advance_out;
if (!arg)
break;
if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(arg, state->elem_size, &state->elem_size, SIZE_MAX)) {
@@ -46,7 +49,6 @@ vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va
}
}
}
-
return 0;
inval:
errno = EINVAL;
@@ -58,8 +60,8 @@ vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list ap)
{
enum libsimple_memalloc_option opt;
long int page_size;
- va_list *subapp;
- size_t arg;
+ va_list *subap, ap_copy;
+ size_t arg, ap_advance;
for (;;) {
opt = va_arg(ap, enum libsimple_memalloc_option);
@@ -129,27 +131,31 @@ vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list ap)
case LIBSIMPLE_MEMALLOC_PRODUCT_SIZE:
arg = va_arg(ap, size_t);
- if (vmemalloc_parse_size_prod(state, n, arg, ap))
+ va_copy(ap_copy, ap);
+ if (vmemalloc_parse_size_prod(state, n, arg, ap_copy, &ap_advance))
return -1;
+ va_end(ap_copy);
+ while (ap_advance--)
+ (void) va_arg(ap, size_t);
break;
case LIBSIMPLE_MEMALLOC_VA_PRODUCT_SIZE:
- subapp = va_arg(ap, va_list *);
- arg = va_arg(*subapp, size_t);
- if (vmemalloc_parse_size_prod(state, n, arg, *subapp))
+ subap = va_arg(ap, va_list *);
+ arg = va_arg(*subap, size_t);
+ if (vmemalloc_parse_size_prod(state, n, arg, *subap, &ap_advance))
return -1;
break;
case LIBSIMPLE_MEMALLOC_1_VA_PRODUCT_SIZE:
arg = va_arg(ap, size_t);
- subapp = va_arg(ap, va_list *);
- if (vmemalloc_parse_size_prod(state, n, arg, *subapp))
+ subap = va_arg(ap, va_list *);
+ if (vmemalloc_parse_size_prod(state, n, arg, *subap, &ap_advance))
return -1;
break;
case LIBSIMPLE_MEMALLOC_VA_LIST:
- subapp = va_arg(ap, va_list *);
- if (vmemalloc_parse_args(state, n, *subapp))
+ subap = va_arg(ap, va_list *);
+ if (vmemalloc_parse_args(state, n, *subap))
return -1;
break;