From a8c814cb2fa61e47af7e6e6571376e1cdec0d722 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Tue, 5 Nov 2019 13:50:43 -0800 Subject: [PATCH] implement fixed-size array stack data structure --- lib/isc/Makefile.in | 4 +- lib/isc/astack.c | 80 +++++++++++++++++++++++++ lib/isc/include/isc/Makefile.in | 2 +- lib/isc/include/isc/astack.h | 44 ++++++++++++++ lib/isc/include/isc/types.h | 1 + lib/isc/win32/libisc.def.in | 4 ++ lib/isc/win32/libisc.vcxproj.filters.in | 6 ++ lib/isc/win32/libisc.vcxproj.in | 2 + util/copyrights | 2 + 9 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 lib/isc/astack.c create mode 100644 lib/isc/include/isc/astack.h diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in index d30031faeb..1f0066a60d 100644 --- a/lib/isc/Makefile.in +++ b/lib/isc/Makefile.in @@ -46,7 +46,7 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/errno.@O@ \ # Alphabetically OBJS = pk11.@O@ pk11_result.@O@ \ - aes.@O@ app.@O@ assertions.@O@ \ + aes.@O@ app.@O@ assertions.@O@ astack.@O@ \ backtrace.@O@ base32.@O@ base64.@O@ \ bind9.@O@ buffer.@O@ bufferlist.@O@ \ commandline.@O@ counter.@O@ crc64.@O@ error.@O@ entropy.@O@ \ @@ -66,7 +66,7 @@ SYMTBLOBJS = backtrace-emptytbl.@O@ # Alphabetically SRCS = pk11.c pk11_result.c \ - aes.c app.c assertions.c \ + aes.c app.c assertions.c astack.c \ backtrace.c base32.c base64.c bind9.c \ buffer.c bufferlist.c commandline.c counter.c crc64.c \ entropy.c error.c event.c hash.c ht.c heap.c \ diff --git a/lib/isc/astack.c b/lib/isc/astack.c new file mode 100644 index 0000000000..05d94365d4 --- /dev/null +++ b/lib/isc/astack.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +struct isc_astack { + isc_mem_t *mctx; + size_t size; + size_t pos; + isc_mutex_t lock; + uintptr_t nodes[]; +}; + +isc_astack_t * +isc_astack_new(isc_mem_t *mctx, size_t size) { + isc_astack_t *stack = + isc_mem_get(mctx, + sizeof(isc_astack_t) + size * sizeof(uintptr_t)); + + stack->mctx = NULL; + isc_mem_attach(mctx, &stack->mctx); + stack->size = size; + stack->pos = 0; + memset(stack->nodes, 0, size * sizeof(uintptr_t)); + isc_mutex_init(&stack->lock); + return (stack); +} + +bool +isc_astack_trypush(isc_astack_t *stack, void *obj) { + if (isc_mutex_trylock(&stack->lock) == false) { + if (stack->pos >= stack->size) { + isc_mutex_unlock(&stack->lock); + return (false); + } + stack->nodes[stack->pos++] = (uintptr_t) obj; + isc_mutex_unlock(&stack->lock); + return (true); + } else { + return (false); + } +} + +void * +isc_astack_pop(isc_astack_t *stack) { + isc_mutex_lock(&stack->lock); + uintptr_t rv; + if (stack->pos == 0) { + rv = 0; + } else { + rv = stack->nodes[--stack->pos]; + } + isc_mutex_unlock(&stack->lock); + return ((void*) rv); +} + +void +isc_astack_destroy(isc_astack_t *stack) { + REQUIRE(stack->pos == 0); + + isc_mem_putanddetach(&stack->mctx, stack, + sizeof(struct isc_astack) + + stack->size * sizeof(uintptr_t)); +} diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in index 9b93fbe1f6..620c8c308d 100644 --- a/lib/isc/include/isc/Makefile.in +++ b/lib/isc/include/isc/Makefile.in @@ -18,7 +18,7 @@ VERSION=@BIND9_VERSION@ # machine generated. The latter are handled specially in the # install target below. # -HEADERS = aes.h app.h assertions.h atomic.h backtrace.h \ +HEADERS = aes.h app.h assertions.h astack.h atomic.h backtrace.h \ base32.h base64.h bind9.h buffer.h bufferlist.h \ commandline.h counter.h crc64.h deprecated.h \ endian.h errno.h error.h event.h eventclass.h \ diff --git a/lib/isc/include/isc/astack.h b/lib/isc/include/isc/astack.h new file mode 100644 index 0000000000..e0ea66ca2b --- /dev/null +++ b/lib/isc/include/isc/astack.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#include +#include +#include + +isc_astack_t * +isc_astack_new(isc_mem_t *mctx, size_t size); +/*%< + * Allocate and initialize a new array stack of size 'size'. + */ + +void +isc_astack_destroy(isc_astack_t *stack); +/*%< + * Free an array stack 'stack'. + * + * Requires: + * \li 'stack' is empty. + */ + +bool +isc_astack_trypush(isc_astack_t *stack, void *obj); +/*%< + * Try to push 'obj' onto array stack 'astack'. On failure, either + * because the stack size limit has been reached or because another + * thread has already changed the stack pointer, return 'false'. + */ + +void * +isc_astack_pop(isc_astack_t *stack); +/*%< + * Pop an object off of array stack 'stack'. If the stack is empty, + * return NULL. + */ diff --git a/lib/isc/include/isc/types.h b/lib/isc/include/isc/types.h index 6520d23711..0c11eadc62 100644 --- a/lib/isc/include/isc/types.h +++ b/lib/isc/include/isc/types.h @@ -31,6 +31,7 @@ */ #define ISC_LIST(type) struct { type *head, *tail; } +typedef struct isc_astack isc_astack_t; /*%< Array-based fast stack */ typedef struct isc_appctx isc_appctx_t; /*%< Application context */ typedef struct isc_backtrace_symmap isc_backtrace_symmap_t; /*%< Symbol Table Entry */ typedef struct isc_buffer isc_buffer_t; /*%< Buffer */ diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 89a46daa1a..6df89c29ff 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -24,6 +24,10 @@ isc_app_start isc_app_unblock isc_appctx_create isc_appctx_destroy +isc_astack_destroy +isc_astack_new +isc_astack_pop +isc_astack_trypush isc__buffer_activeregion isc__buffer_add isc__buffer_availableregion diff --git a/lib/isc/win32/libisc.vcxproj.filters.in b/lib/isc/win32/libisc.vcxproj.filters.in index 36bfa47258..188f0dbdb4 100644 --- a/lib/isc/win32/libisc.vcxproj.filters.in +++ b/lib/isc/win32/libisc.vcxproj.filters.in @@ -35,6 +35,9 @@ Library Header Files + + Library Header Files + Library Header Files @@ -452,6 +455,9 @@ Library Source Files + + Library Source Files + Library Source Files diff --git a/lib/isc/win32/libisc.vcxproj.in b/lib/isc/win32/libisc.vcxproj.in index 552443fd50..eed5338b85 100644 --- a/lib/isc/win32/libisc.vcxproj.in +++ b/lib/isc/win32/libisc.vcxproj.in @@ -288,6 +288,7 @@ copy InstallFiles ..\Build\Release\ + @@ -405,6 +406,7 @@ copy InstallFiles ..\Build\Release\ + diff --git a/util/copyrights b/util/copyrights index 7f6dd8774c..b2be20d76f 100644 --- a/util/copyrights +++ b/util/copyrights @@ -2129,6 +2129,7 @@ ./lib/isc/api X 1999,2000,2001,2006,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019 ./lib/isc/app.c C 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2013,2014,2015,2016,2017,2018,2019 ./lib/isc/assertions.c C 1997,1998,1999,2000,2001,2004,2005,2007,2008,2009,2015,2016,2018,2019 +./lib/isc/astack.c C 2019 ./lib/isc/backtrace-emptytbl.c C 2009,2016,2018,2019 ./lib/isc/backtrace.c C 2009,2013,2014,2015,2016,2018,2019 ./lib/isc/base32.c C 2008,2009,2013,2014,2015,2016,2018,2019 @@ -2156,6 +2157,7 @@ ./lib/isc/include/isc/aes.h C 2014,2016,2018,2019 ./lib/isc/include/isc/app.h C 1999,2000,2001,2004,2005,2006,2007,2009,2013,2014,2015,2016,2018,2019 ./lib/isc/include/isc/assertions.h C 1997,1998,1999,2000,2001,2004,2005,2006,2007,2008,2009,2016,2017,2018,2019 +./lib/isc/include/isc/astack.h C 2019 ./lib/isc/include/isc/atomic.h C 2018,2019 ./lib/isc/include/isc/backtrace.h C 2009,2016,2018,2019 ./lib/isc/include/isc/base32.h C 2008,2014,2016,2018,2019