Commit 0b950290 authored by Geoff Simmons's avatar Geoff Simmons

Simplify caching of thread-specific bitmaps for random_bool().

parent 6af8f7ed
Pipeline #236 skipped
......@@ -90,21 +90,24 @@ struct filedata {
size_t len;
};
struct rnd_bitmap {
uint64_t bits;
uint8_t nbits;
};
struct rnd_bool {
unsigned magic;
#define VMOD_GCRYPT_RND_BOOL_MAGIC 0x7d0a3e42
uint64_t bits;
uint8_t nbits;
struct rnd_bitmap bitmap[2];
};
VSLIST_HEAD(filedata_head, filedata);
static const char *gcrypt_version = NULL;
static int secmem_enabled = 1;
static pthread_once_t strong_bool_once = PTHREAD_ONCE_INIT,
nonce_bool_once = PTHREAD_ONCE_INIT;
static pthread_key_t strong_boolk, nonce_boolk;
static int strong_boolk_inited = 0, nonce_boolk_inited = 0;
static pthread_once_t rnd_bool_once = PTHREAD_ONCE_INIT;
static pthread_key_t rnd_boolk;
static int rnd_boolk_inited = 0;
static void
errmsg(VRT_CTX, const char *fmt, ...)
......@@ -832,73 +835,43 @@ rnd_bool_fini(void *p)
}
/*
* Initialize the pthread key for both quality levels via pthread_once,
* only if random_bool() is called for that quality level at all.
* Initialize the pthread key for the cached bitmaps via pthread_once,
* only if random_bool() is called at all.
*/
static void
nonce_bool_init(void)
{
AZ(nonce_boolk_inited);
errno = 0;
if (pthread_key_create(&nonce_boolk, rnd_bool_fini) != 0) {
assert(errno == EAGAIN);
return;
}
nonce_boolk_inited = 1;
}
static void
strong_bool_init(void)
rnd_bool_init(void)
{
AZ(strong_boolk_inited);
AZ(rnd_boolk_inited);
errno = 0;
if (pthread_key_create(&strong_boolk, rnd_bool_fini) != 0) {
if (pthread_key_create(&rnd_boolk, rnd_bool_fini) != 0) {
assert(errno == EAGAIN);
return;
}
strong_boolk_inited = 1;
rnd_boolk_inited = 1;
}
VCL_BOOL
vmod_random_bool(VRT_CTX, VCL_ENUM qualitys)
{
VCL_BOOL r;
pthread_once_t *rnd_bool_once;
void (*rnd_bool_init)(void);
pthread_key_t *rnd_boolk;
int *rnd_boolk_inited;
void *p;
struct rnd_bool *rb;
int map = 0;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(qualitys);
assert(qualitys[0] != 'V');
switch(qualitys[0]) {
case 'N':
rnd_bool_once = &nonce_bool_once;
rnd_bool_init = nonce_bool_init;
rnd_boolk = &nonce_boolk;
rnd_boolk_inited = &nonce_boolk_inited;
break;
case 'S':
rnd_bool_once = &strong_bool_once;
rnd_bool_init = strong_bool_init;
rnd_boolk = &strong_boolk;
rnd_boolk_inited = &strong_boolk_inited;
break;
default:
WRONG("Invalid quality ENUM");
}
AZ(pthread_once(rnd_bool_once, rnd_bool_init));
if (! *rnd_boolk_inited) {
if (qualitys[0] == 'S')
map = 1;
AZ(pthread_once(&rnd_bool_once, rnd_bool_init));
if (! rnd_boolk_inited) {
VERR(ctx, "pthread key allocation exhausted "
"(PTHREAD_KEYS_MAX=%d) in gcrypt.random_bool(), discard "
"old VCL instances or restart Varnish", PTHREAD_KEYS_MAX);
return 0;
}
p = pthread_getspecific(*rnd_boolk);
p = pthread_getspecific(rnd_boolk);
if (p == NULL) {
ALLOC_OBJ(rb, VMOD_GCRYPT_RND_BOOL_MAGIC);
if (rb == NULL) {
......@@ -906,20 +879,19 @@ vmod_random_bool(VRT_CTX, VCL_ENUM qualitys)
"for random_bool()");
return 0;
}
AZ(rb->bits);
AZ(rb->nbits);
AZ(pthread_setspecific(*rnd_boolk, rb));
AZ(pthread_setspecific(rnd_boolk, rb));
}
else
CAST_OBJ(rb, p, VMOD_GCRYPT_RND_BOOL_MAGIC);
if (rb->nbits == 0) {
get_rnd(qualitys, &rb->bits, sizeof(rb->bits));
rb->nbits = sizeof(rb->bits) * 8;
if (rb->bitmap[map].nbits == 0) {
get_rnd(qualitys, &rb->bitmap[map].bits,
sizeof(rb->bitmap[map].bits));
rb->bitmap[map].nbits = sizeof(rb->bitmap[map].bits) * 8;
}
r = rb->bits & 0x01;
rb->bits >>= 1;
rb->nbits -= 1;
r = rb->bitmap[map].bits & 0x01;
rb->bitmap[map].bits >>= 1;
rb->bitmap[map].nbits -= 1;
return r;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment