rnatm

Load and structure data describing an atmosphere
git clone git://git.meso-star.fr/rnatm.git
Log | Files | Refs | README | LICENSE

commit 67ded6763e5e2bc346b68c8d65956a6332a9078e
parent c4ae42af3f8fdf65a2d9c92b672540826018bf10
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 23 Aug 2022 11:58:52 +0200

Allow a partition to be fetched by several threads

Diffstat:
Msrc/rnatm_voxel_partition.c | 30++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/rnatm_voxel_partition.c b/src/rnatm_voxel_partition.c @@ -42,6 +42,12 @@ struct partition { size_t id; /* Unique identifier of the partition */ struct tile* tile; /* Set of voxels */ struct pool* pool; + + /* Number of references on the partition. When the partition is commited, its + * reference count is set to the width of the voxel. Once fetched, a + * reference is given to the caller that it releases by calling + * partition_free */ + ATOMIC ref; }; struct pool { @@ -64,7 +70,7 @@ struct pool { struct cond* cond_fetch; struct cond* cond_tile; - size_t next_part_id; /* Indentifier of the next partition */ + size_t next_part_id; /* Identifier of the next partition */ size_t partition_definition; /* #voxels along the 3 axis */ size_t partition_nvoxels; /* Overall number of voxels in a partition */ size_t voxel_width; /* Number of items per voxel data */ @@ -244,6 +250,9 @@ partition_free(struct partition* partition) pool = partition->pool; + if(ATOMIC_DECR(&partition->ref) != 0) + return; /* The partition is still referenced */ + mutex_lock(pool->mutex); list_move_tail(&partition->node, &pool->parts_free); /* Free the partition */ if(partition->tile) { /* Free the reserved tile */ @@ -285,6 +294,9 @@ partition_commit(struct partition* partition) pool = partition->pool; + /* Setup the number of partition references */ + partition->ref = (ATOMIC)partition->pool->voxel_width; + /* Committed partitions are sorted in ascending order of their id. We are * therefore looking for the partition whose id is less than the id of the * partition to be committed in order to add the latter in the right place */ @@ -296,8 +308,12 @@ partition_commit(struct partition* partition) list_add(node, &partition->node); mutex_unlock(pool->mutex); - /* Notify a thread waiting for a valid partition that we just registered one */ - cond_signal(pool->cond_fetch); + /* Notify the threads waiting for a valid partition that we just registered + * one. Note that a partition can register several items when voxel_width > 1 + * and therefore several threads can wait for the same partition. + * Consequently, we broadcast the signal to all threads that are blocked on + * fetch condition */ + cond_broadcast(pool->cond_fetch); } size_t @@ -500,7 +516,7 @@ pool_fetch_partition(struct pool* pool, const size_t ipartition) mutex_lock(pool->mutex); while(!pool->error) { - /* Finds the partition that matches the submitted id */ + /* Search for the partition that matches the submitted id */ LIST_FOR_EACH(node, &pool->parts_commit) { struct partition* partition = CONTAINER_OF(node, struct partition, node); @@ -520,8 +536,10 @@ pool_fetch_partition(struct pool* pool, const size_t ipartition) cond_wait(pool->cond_fetch, pool->mutex); } else { - /* Remove the found partition from the list of committed partition */ - list_del(&found_partition->node); + /* Do not remove the found partition from the list of committed + * partitions since the same partition can be fetched several times when + * the width of the voxels is greater than 1 */ + /* list_del(&found_partition->node); */ break; } }