WIP: Make the isc_astack growable and start low
This commit is contained in:
+86
-28
@@ -19,65 +19,123 @@
|
||||
#include <isc/types.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
struct isc_astack {
|
||||
isc_mem_t *mctx;
|
||||
typedef struct nodes {
|
||||
size_t size;
|
||||
size_t pos;
|
||||
void **nodes;
|
||||
} nodes_t;
|
||||
|
||||
struct isc_astack {
|
||||
isc_mem_t *mctx;
|
||||
isc_mutex_t lock;
|
||||
uintptr_t nodes[];
|
||||
size_t min_size;
|
||||
size_t max_size;
|
||||
nodes_t cur;
|
||||
nodes_t old;
|
||||
};
|
||||
|
||||
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));
|
||||
static void
|
||||
nodes_new(isc_mem_t *mctx, nodes_t *cur, size_t size) {
|
||||
*cur = (nodes_t){ .size = size };
|
||||
|
||||
*stack = (isc_astack_t){
|
||||
.size = size,
|
||||
};
|
||||
if (size > 0) {
|
||||
cur->nodes = isc_mem_get(mctx, cur->size * sizeof(void *));
|
||||
memset(cur->nodes, 0, cur->size * sizeof(void *));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nodes_free(isc_mem_t *mctx, nodes_t *cur) {
|
||||
REQUIRE(cur->pos == 0);
|
||||
|
||||
if (cur->size > 0) {
|
||||
REQUIRE(cur->nodes != NULL);
|
||||
isc_mem_put(mctx, cur->nodes, cur->size * sizeof(void *));
|
||||
}
|
||||
|
||||
*cur = (nodes_t){ .size = 0 };
|
||||
}
|
||||
|
||||
#define IS_POWEROF2(bits) (bits && !(bits & (bits - 1)))
|
||||
|
||||
isc_astack_t *
|
||||
isc_astack_new(isc_mem_t *mctx, size_t min_size, size_t max_size) {
|
||||
isc_astack_t *stack = isc_mem_get(mctx, sizeof(isc_astack_t));
|
||||
|
||||
REQUIRE(IS_POWEROF2(min_size));
|
||||
REQUIRE(IS_POWEROF2(max_size));
|
||||
|
||||
*stack = (isc_astack_t){ .min_size = min_size, .max_size = max_size };
|
||||
isc_mem_attach(mctx, &stack->mctx);
|
||||
memset(stack->nodes, 0, size * sizeof(uintptr_t));
|
||||
isc_mutex_init(&stack->lock);
|
||||
|
||||
nodes_new(mctx, &stack->cur, stack->min_size);
|
||||
nodes_new(mctx, &stack->old, 0);
|
||||
|
||||
return (stack);
|
||||
}
|
||||
|
||||
bool
|
||||
isc_astack_trypush(isc_astack_t *stack, void *obj) {
|
||||
if (!isc_mutex_trylock(&stack->lock)) {
|
||||
if (stack->pos >= stack->size) {
|
||||
if (isc_mutex_trylock(&stack->lock) != ISC_R_SUCCESS) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (stack->cur.pos >= stack->cur.size) {
|
||||
if (stack->old.size > 0) {
|
||||
UNLOCK(&stack->lock);
|
||||
return (false);
|
||||
}
|
||||
stack->nodes[stack->pos++] = (uintptr_t)obj;
|
||||
UNLOCK(&stack->lock);
|
||||
return (true);
|
||||
} else {
|
||||
return (false);
|
||||
|
||||
if (stack->cur.size * 2 > stack->max_size) {
|
||||
UNLOCK(&stack->lock);
|
||||
return (false);
|
||||
}
|
||||
|
||||
stack->old = stack->cur;
|
||||
nodes_new(stack->mctx, &stack->cur, stack->old.size * 2);
|
||||
}
|
||||
|
||||
stack->cur.nodes[stack->cur.pos++] = obj;
|
||||
UNLOCK(&stack->lock);
|
||||
return (true);
|
||||
}
|
||||
|
||||
void *
|
||||
isc_astack_pop(isc_astack_t *stack) {
|
||||
LOCK(&stack->lock);
|
||||
uintptr_t rv;
|
||||
if (stack->pos == 0) {
|
||||
rv = 0;
|
||||
void *rv;
|
||||
|
||||
if (isc_mutex_trylock(&stack->lock) != ISC_R_SUCCESS) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (stack->old.size > 0) {
|
||||
REQUIRE(stack->old.pos > 0);
|
||||
|
||||
rv = stack->old.nodes[--stack->old.pos];
|
||||
|
||||
if (stack->old.pos == 0) {
|
||||
nodes_free(stack->mctx, &stack->old);
|
||||
}
|
||||
} else if (stack->cur.pos > 0) {
|
||||
rv = stack->cur.nodes[--stack->cur.pos];
|
||||
} else {
|
||||
rv = stack->nodes[--stack->pos];
|
||||
rv = NULL;
|
||||
}
|
||||
UNLOCK(&stack->lock);
|
||||
return ((void *)rv);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
void
|
||||
isc_astack_destroy(isc_astack_t *stack) {
|
||||
LOCK(&stack->lock);
|
||||
REQUIRE(stack->pos == 0);
|
||||
REQUIRE(stack->cur.pos == 0);
|
||||
REQUIRE(stack->old.size == 0);
|
||||
UNLOCK(&stack->lock);
|
||||
|
||||
nodes_free(stack->mctx, &stack->cur);
|
||||
|
||||
isc_mutex_destroy(&stack->lock);
|
||||
|
||||
isc_mem_putanddetach(&stack->mctx, stack,
|
||||
sizeof(struct isc_astack) +
|
||||
stack->size * sizeof(uintptr_t));
|
||||
isc_mem_putanddetach(&stack->mctx, stack, sizeof(struct isc_astack));
|
||||
}
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
#include <isc/types.h>
|
||||
|
||||
isc_astack_t *
|
||||
isc_astack_new(isc_mem_t *mctx, size_t size);
|
||||
isc_astack_new(isc_mem_t *mctx, size_t min_size, size_t max_size);
|
||||
/*%<
|
||||
* Allocate and initialize a new array stack of size 'size'.
|
||||
* Allocate and initialize a new bounded array stack. Initially, min_size
|
||||
* entries will be allocated, but would grow up to max_size entries.
|
||||
*/
|
||||
|
||||
void
|
||||
|
||||
+19
-10
@@ -48,8 +48,11 @@
|
||||
* How many isc_nmhandles and isc_nm_uvreqs will we be
|
||||
* caching for reuse in a socket.
|
||||
*/
|
||||
#define ISC_NM_HANDLES_STACK_SIZE 600
|
||||
#define ISC_NM_REQS_STACK_SIZE 600
|
||||
#define ISC_NM_HANDLES_MIN_STACK_SIZE 32
|
||||
#define ISC_NM_HANDLES_MAX_STACK_SIZE 1024
|
||||
|
||||
#define ISC_NM_REQS_MIN_STACK_SIZE 32
|
||||
#define ISC_NM_REQS_MAX_STACK_SIZE 1024
|
||||
|
||||
/*%
|
||||
* Shortcut index arrays to get access to statistics counters.
|
||||
@@ -1441,14 +1444,20 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
|
||||
|
||||
family = iface->type.sa.sa_family;
|
||||
|
||||
*sock = (isc_nmsocket_t){ .type = type,
|
||||
.iface = *iface,
|
||||
.fd = -1,
|
||||
.ah_size = 32,
|
||||
.inactivehandles = isc_astack_new(
|
||||
mgr->mctx, ISC_NM_HANDLES_STACK_SIZE),
|
||||
.inactivereqs = isc_astack_new(
|
||||
mgr->mctx, ISC_NM_REQS_STACK_SIZE) };
|
||||
*sock = (isc_nmsocket_t){
|
||||
.type = type,
|
||||
.iface = *iface,
|
||||
.fd = -1,
|
||||
.ah_size = 32,
|
||||
};
|
||||
|
||||
sock->inactivehandles = isc_astack_new(mgr->mctx,
|
||||
ISC_NM_HANDLES_MIN_STACK_SIZE,
|
||||
ISC_NM_HANDLES_MAX_STACK_SIZE);
|
||||
|
||||
sock->inactivereqs = isc_astack_new(mgr->mctx,
|
||||
ISC_NM_REQS_MIN_STACK_SIZE,
|
||||
ISC_NM_REQS_MAX_STACK_SIZE);
|
||||
|
||||
#if NETMGR_TRACE
|
||||
sock->backtrace_size = backtrace(sock->backtrace, TRACE_SIZE);
|
||||
|
||||
Reference in New Issue
Block a user