Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2016-05-16 16:57:19 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-05-16 16:57:19 +0300
commit575d7a9666e12ef6608af92d0bf2a9c590afc816 (patch)
tree51b21ae410f66754a13d6d9ad9822d2926b7aef7
parent75a96f832518e33bc032d137ab6f6334676f024c (diff)
BLI_task: make foreach loop index hleper lockfree, take II.
New code is actually much, much better than first version, using 'fetch_and_add' atomic op here allows us to get rid of the loop etc. The broken CAS issue remains on windows, to be investigated...
-rw-r--r--source/blender/blenlib/intern/task.c21
1 files changed, 7 insertions, 14 deletions
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index 247f1af846e..f1bffd0e669 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -776,23 +776,18 @@ typedef struct ParallelRangeState {
int iter;
int chunk_size;
- SpinLock lock;
} ParallelRangeState;
BLI_INLINE bool parallel_range_next_iter_get(
ParallelRangeState * __restrict state,
int * __restrict iter, int * __restrict count)
{
- bool result = false;
- BLI_spin_lock(&state->lock);
- if (state->iter < state->stop) {
- *count = min_ii(state->chunk_size, state->stop - state->iter);
- *iter = state->iter;
- state->iter += *count;
- result = true;
- }
- BLI_spin_unlock(&state->lock);
- return result;
+ uint32_t previter = atomic_fetch_and_add_uint32((uint32_t *)(&state->iter), state->chunk_size);
+
+ *iter = (int)previter;
+ *count = max_ii(0, min_ii(state->chunk_size, state->stop - previter));
+
+ return (previter < state->stop);
}
static void parallel_range_func(
@@ -897,7 +892,6 @@ static void task_parallel_range_ex(
*/
num_tasks = num_threads * 2;
- BLI_spin_init(&state.lock);
state.start = start;
state.stop = stop;
state.userdata = userdata;
@@ -914,6 +908,7 @@ static void task_parallel_range_ex(
}
num_tasks = min_ii(num_tasks, (stop - start) / state.chunk_size);
+ atomic_fetch_and_add_uint32((uint32_t *)(&state.iter), 0);
for (i = 0; i < num_tasks; i++) {
BLI_task_pool_push(task_pool,
@@ -924,8 +919,6 @@ static void task_parallel_range_ex(
BLI_task_pool_work_and_wait(task_pool);
BLI_task_pool_free(task_pool);
-
- BLI_spin_end(&state.lock);
}
/**