Compare commits

...

1 Commits

Author SHA1 Message Date
Ondřej Surý
ad884f926b WIP: Make the isc_astack growable and start low 2021-12-09 13:23:09 +01:00
3 changed files with 107 additions and 39 deletions

View File

@@ -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));
}

View File

@@ -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

View File

@@ -47,8 +47,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.
@@ -1460,13 +1463,19 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
REQUIRE(sock != NULL);
REQUIRE(mgr != NULL);
*sock = (isc_nmsocket_t){ .type = type,
.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,
.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 (iface != NULL) {
family = iface->type.sa.sa_family;