star-sp

Random number generators and distributions
git clone git://git.meso-star.fr/star-sp.git
Log | Files | Refs | README | LICENSE

commit 141afbdba0620909fa209665f520419bf2859815
parent e9916421a494772b1e5ec0746fcc950bbfa5b78c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  2 Mar 2022 12:16:05 +0100

Adjust the mutual exclusions in the RNG proxy

When a new RNG pool is required by a bucket, we no longer lock the proxy
for the whole process, that is to compute the next pool state for all buckets
(writing) and then to fetch the pool corresponding to the bucket
(reading). The "write" process is always executed entirely under a
mutual exclusion. However, the "read" step can be performed locally on
the bucket if its cache is disabled. In this situation, we unlock
the mutual exclusion in order to avoid unnecessary blocks.

Diffstat:
Msrc/ssp_rng_proxy.c | 28++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/src/ssp_rng_proxy.c b/src/ssp_rng_proxy.c @@ -227,10 +227,16 @@ rng_state_cache_is_empty(struct rng_state_cache* cache) } static res_T -rng_state_cache_read(struct rng_state_cache* cache, struct ssp_rng* rng) +rng_state_cache_read + (struct rng_state_cache* cache, + struct ssp_rng* rng, + struct mutex* mutex) /* Proxy mutex */ { res_T res = RES_OK; - ASSERT(cache && rng && !rng_state_cache_is_empty(cache)); + ASSERT(cache && rng && mutex); + + mutex_lock(mutex); + ASSERT(!rng_state_cache_is_empty(cache)); if(!cache->no_rstream && cache->no_wstream @@ -247,7 +253,10 @@ rng_state_cache_read(struct rng_state_cache* cache, struct ssp_rng* rng) if(!cache->no_rstream) { fseek(cache->stream, cache->read, SEEK_SET); res = ssp_rng_read(rng, cache->stream); - if(res != RES_OK) goto error; + if(res != RES_OK) { + mutex_unlock(mutex); + goto error; + } cache->read = ftell(cache->stream); /* The fp reaches the end of the cached data */ @@ -258,8 +267,13 @@ rng_state_cache_read(struct rng_state_cache* cache, struct ssp_rng* rng) /* Remove one cached states */ cache->nstates -= 1; + mutex_unlock(mutex); + /* Generate the next RNG state and load the cached one */ } else { + /* All is done locally to the RNG. We can thus unlock the proxy mutex */ + mutex_unlock(mutex); + /* Copy the cached RNG state */ res = darray_char_copy(&cache->state_scratch, &cache->state); if(res != RES_OK) goto error; @@ -493,6 +507,7 @@ rng_proxy_next_ran_pool ASSERT(bucket_name <= sa_size(proxy->per_bucket_sequence_id)); mutex_lock(proxy->mutex); + if(rng_state_cache_is_empty(proxy->states + bucket_name)) { size_t ibucket; /* Register a new state for *all* buckets */ @@ -507,17 +522,18 @@ rng_proxy_next_ran_pool /* Increment the sequence id of the main RNG */ proxy->main_sequence_id += 1; } + mutex_unlock(proxy->mutex); /* Read the RNG pool state of `bucket_name' */ res = rng_state_cache_read - (proxy->states + bucket_name, proxy->pools[bucket_name]); + (proxy->states + bucket_name, + proxy->pools[bucket_name], + proxy->mutex); if(res != RES_OK) FATAL("RNG proxy: cannot read from state cache\n"); /* Update the sequence of the bucket RNG */ proxy->per_bucket_sequence_id[bucket_name] += 1; - mutex_unlock(proxy->mutex); - return proxy->pools[bucket_name]; }