commit c8781620c50e9d00d34a49e408a2bd2585ba1fb3
parent b1f3a65edfd06cceed50a8cc68cf8b6356c58ceb
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 20 Oct 2023 15:35:38 +0200
Fix voxelization deadlock
Partitions that do not overlap the atmosphere grid were not released as
expected, resulting in a deadlock when there were no empty partitions
left for voxelization threads.
Diffstat:
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/rnatm_voxel_partition.c b/src/rnatm_voxel_partition.c
@@ -122,6 +122,7 @@ partition_init
partition->id = SIZE_MAX;
partition->tile = NULL;
partition->pool = pool;
+ partition->ref = 0;
}
static void
@@ -251,11 +252,17 @@ partition_free(struct partition* partition)
pool = partition->pool;
- if(ATOMIC_DECR(&partition->ref) != 0)
+ /* The partition reference counter can be zero before being decremented: it is
+ * initialized to the voxel width once the partition has been commited. So, if
+ * the partition is released before any commit (for example, when it doesn't
+ * overlap the atmosphere grid), it can be negative after it has been
+ * decremented */
+ 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 */
+ partition->ref = 0; /* Reset to 0 rather than letting a negative value */
if(partition->tile) { /* Free the reserved tile */
list_move_tail(&partition->tile->node, &pool->tiles_free);
partition->tile = NULL;