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:
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_assert.h12
-rw-r--r--source/blender/blenlib/BLI_memarena.h2
-rw-r--r--source/blender/blenlib/BLI_task.h7
-rw-r--r--source/blender/blenlib/intern/BLI_assert.c5
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c53
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c2
-rw-r--r--source/blender/blenlib/intern/expr_pylike_eval.c2
-rw-r--r--source/blender/blenlib/intern/math_color.c2
-rw-r--r--source/blender/blenlib/intern/path_util.c2
-rw-r--r--source/blender/blenlib/intern/system.c2
-rw-r--r--source/blender/blenlib/intern/task_iterator.c29
-rw-r--r--source/blender/blenlib/intern/task_range.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_delaunay_2d_test.cc8
13 files changed, 107 insertions, 21 deletions
diff --git a/source/blender/blenlib/BLI_assert.h b/source/blender/blenlib/BLI_assert.h
index 685f526b4ad..6019f0f3566 100644
--- a/source/blender/blenlib/BLI_assert.h
+++ b/source/blender/blenlib/BLI_assert.h
@@ -31,6 +31,7 @@ extern "C" {
/* Utility functions. */
void _BLI_assert_print_pos(const char *file, const int line, const char *function, const char *id);
+void _BLI_assert_print_extra(const char *str);
void _BLI_assert_print_backtrace(void);
void _BLI_assert_abort(void);
void _BLI_assert_unreachable_print(const char *file, const int line, const char *function);
@@ -61,8 +62,17 @@ void _BLI_assert_unreachable_print(const char *file, const int line, const char
_BLI_ASSERT_ABORT(), \
NULL)) : \
NULL)
+/** A version of #BLI_assert() to pass an additional message to be printed on failure. */
+# define BLI_assert_msg(a, msg) \
+ (void)((!(a)) ? ((_BLI_assert_print_backtrace(), \
+ _BLI_ASSERT_PRINT_POS(a), \
+ _BLI_assert_print_extra(msg), \
+ _BLI_ASSERT_ABORT(), \
+ NULL)) : \
+ NULL)
#else
# define BLI_assert(a) ((void)0)
+# define BLI_assert_msg(a, msg) ((void)0)
#endif
#if defined(__cplusplus)
@@ -96,7 +106,7 @@ void _BLI_assert_unreachable_print(const char *file, const int line, const char
#define BLI_assert_unreachable() \
{ \
_BLI_assert_unreachable_print(__FILE__, __LINE__, __func__); \
- BLI_assert(!"This line of code is marked to be unreachable."); \
+ BLI_assert_msg(0, "This line of code is marked to be unreachable."); \
} \
((void)0)
diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h
index d7798f12fcc..b2e05b00735 100644
--- a/source/blender/blenlib/BLI_memarena.h
+++ b/source/blender/blenlib/BLI_memarena.h
@@ -50,6 +50,8 @@ void *BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESU
void *BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2);
+void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src) ATTR_NONNULL(1, 2);
+
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1);
#ifdef __cplusplus
diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h
index dbe8ec3dcc0..418db14e2f3 100644
--- a/source/blender/blenlib/BLI_task.h
+++ b/source/blender/blenlib/BLI_task.h
@@ -129,6 +129,9 @@ typedef struct TaskParallelTLS {
typedef void (*TaskParallelRangeFunc)(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls);
+
+typedef void (*TaskParallelInitFunc)(const void *__restrict userdata, void *__restrict chunk);
+
typedef void (*TaskParallelReduceFunc)(const void *__restrict userdata,
void *__restrict chunk_join,
void *__restrict chunk);
@@ -151,6 +154,10 @@ typedef struct TaskParallelSettings {
/* Function called from calling thread once whole range have been
* processed.
*/
+ /* Function called to initialize user data chunk,
+ * typically to allocate data, freed by `func_free`.
+ */
+ TaskParallelInitFunc func_init;
/* Function called to join user data chunk into another, to reduce
* the result to the original userdata_chunk memory.
* The reduce functions should have no side effects, so that they
diff --git a/source/blender/blenlib/intern/BLI_assert.c b/source/blender/blenlib/intern/BLI_assert.c
index 887f583242f..cebc6f8957f 100644
--- a/source/blender/blenlib/intern/BLI_assert.c
+++ b/source/blender/blenlib/intern/BLI_assert.c
@@ -31,6 +31,11 @@ void _BLI_assert_print_pos(const char *file, const int line, const char *functio
fprintf(stderr, "BLI_assert failed: %s:%d, %s(), at \'%s\'\n", file, line, function, id);
}
+void _BLI_assert_print_extra(const char *str)
+{
+ fprintf(stderr, " %s\n", str);
+}
+
void _BLI_assert_unreachable_print(const char *file, const int line, const char *function)
{
fprintf(stderr, "Code marked as unreachable has been executed. Please report this as a bug.\n");
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index fc381c22315..0ab27a5adad 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -45,6 +45,7 @@
# define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) UNUSED_VARS(pool, rzB, is_zeroed)
# define VALGRIND_DESTROY_MEMPOOL(pool) UNUSED_VARS(pool)
# define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) UNUSED_VARS(pool, addr, size)
+# define VALGRIND_MOVE_MEMPOOL(pool_a, pool_b) UNUSED_VARS(pool_a, pool_b)
#endif
struct MemBuf {
@@ -179,6 +180,58 @@ void *BLI_memarena_calloc(MemArena *ma, size_t size)
}
/**
+ * Transfer ownership of allocated blocks from `ma_src` into `ma_dst`,
+ * cleaning the contents of `ma_src`.
+ *
+ * \note Useful for multi-threaded tasks that need a thread-local #MemArena
+ * that is kept after the multi-threaded operation is completed.
+ *
+ * \note Avoid accumulating memory pools where possible
+ * as any unused memory in `ma_src` is wasted every merge.
+ */
+void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src)
+{
+ /* Memory arenas must be compatible. */
+ BLI_assert(ma_dst != ma_src);
+ BLI_assert(ma_dst->align == ma_src->align);
+ BLI_assert(ma_dst->use_calloc == ma_src->use_calloc);
+ BLI_assert(ma_dst->bufsize == ma_src->bufsize);
+
+ if (ma_src->bufs == NULL) {
+ return;
+ }
+
+ if (UNLIKELY(ma_dst->bufs == NULL)) {
+ BLI_assert(ma_dst->curbuf == NULL);
+ ma_dst->bufs = ma_src->bufs;
+ ma_dst->curbuf = ma_src->curbuf;
+ ma_dst->cursize = ma_src->cursize;
+ }
+ else {
+ /* Keep the 'ma_dst->curbuf' for simplicity.
+ * Insert buffers after the first. */
+ if (ma_dst->bufs->next != NULL) {
+ /* Loop over `ma_src` instead of `ma_dst` since it's likely the destination is larger
+ * when used for accumulating from multiple sources. */
+ struct MemBuf *mb_src = ma_src->bufs;
+ mb_src = ma_src->bufs;
+ while (mb_src && mb_src->next) {
+ mb_src = mb_src->next;
+ }
+ mb_src->next = ma_dst->bufs->next;
+ }
+ ma_dst->bufs->next = ma_src->bufs;
+ }
+
+ ma_src->bufs = NULL;
+ ma_src->curbuf = NULL;
+ ma_src->cursize = 0;
+
+ VALGRIND_MOVE_MEMPOOL(ma_src, ma_dst);
+ VALGRIND_CREATE_MEMPOOL(ma_src, 0, false);
+}
+
+/**
* Clear for reuse, avoids re-allocation when an arena may
* otherwise be free'd and recreated.
*/
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 934c1e44dc3..523bb300247 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -522,7 +522,7 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
}
}
if (!found) {
- BLI_assert(!"Attempt to free data which is not in pool.\n");
+ BLI_assert_msg(0, "Attempt to free data which is not in pool.\n");
}
}
diff --git a/source/blender/blenlib/intern/expr_pylike_eval.c b/source/blender/blenlib/intern/expr_pylike_eval.c
index a5d4130cb20..4d1ba190c14 100644
--- a/source/blender/blenlib/intern/expr_pylike_eval.c
+++ b/source/blender/blenlib/intern/expr_pylike_eval.c
@@ -569,7 +569,7 @@ static int opcode_arg_count(eOpCode code)
case OPCODE_FUNC3:
return 3;
default:
- BLI_assert(!"unexpected opcode");
+ BLI_assert_msg(0, "unexpected opcode");
return -1;
}
}
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 263c508c07c..da97e697f2f 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -153,7 +153,7 @@ void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr,
cr = (0.5f * sr) - (0.41869f * sg) - (0.08131f * sb) + 128.0f;
break;
default:
- BLI_assert(!"invalid colorspace");
+ BLI_assert_msg(0, "invalid colorspace");
break;
}
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 8969dd4f6b5..4d0dc43ed1e 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1275,7 +1275,7 @@ void BLI_setenv(const char *env, const char *val)
{
/* free windows */
-#if (defined(WIN32) || defined(WIN64))
+#if (defined(_WIN32) || defined(_WIN64))
uputenv(env, val);
#else
diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c
index 87330cf4899..66d0b44cfb3 100644
--- a/source/blender/blenlib/intern/system.c
+++ b/source/blender/blenlib/intern/system.c
@@ -184,7 +184,7 @@ size_t BLI_system_memory_max_in_megabytes(void)
/* Maximum addressable bytes on this platform.
*
* NOTE: Due to the shift arithmetic this is a half of the memory. */
- const size_t limit_bytes_half = (((size_t)1) << ((sizeof(size_t[8])) - 1));
+ const size_t limit_bytes_half = (((size_t)1) << (sizeof(size_t[8]) - 1));
/* Convert it to megabytes and return. */
return (limit_bytes_half >> 20) * 2;
}
diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c
index 0ff408ddb0a..06087869685 100644
--- a/source/blender/blenlib/intern/task_iterator.c
+++ b/source/blender/blenlib/intern/task_iterator.c
@@ -186,6 +186,9 @@ static void task_parallel_iterator_no_threads(const TaskParallelSettings *settin
if (use_userdata_chunk) {
userdata_chunk_local = MALLOCA(userdata_chunk_size);
memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
+ if (settings->func_init != NULL) {
+ settings->func_init(state->userdata, userdata_chunk_local);
+ }
}
/* Also marking it as non-threaded for the iterator callback. */
@@ -247,6 +250,9 @@ static void task_parallel_iterator_do(const TaskParallelSettings *settings,
if (use_userdata_chunk) {
userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i);
memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
+ if (settings->func_init != NULL) {
+ settings->func_init(state->userdata, userdata_chunk_local);
+ }
}
/* Use this pool's pre-allocated tasks. */
BLI_task_pool_push(task_pool, parallel_iterator_func, userdata_chunk_local, false, NULL);
@@ -403,11 +409,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
TaskParallelMempoolFunc func,
const TaskParallelSettings *settings)
{
- TaskPool *task_pool;
- ParallelMempoolState state;
- int i, num_threads, num_tasks;
-
- if (BLI_mempool_len(mempool) == 0) {
+ if (UNLIKELY(BLI_mempool_len(mempool) == 0)) {
return;
}
@@ -422,6 +424,9 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
if (use_userdata_chunk) {
userdata_chunk_local = MALLOCA(userdata_chunk_size);
memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
+ if (settings->func_init != NULL) {
+ settings->func_init(userdata, userdata_chunk_local);
+ }
tls.userdata_chunk = userdata_chunk_local;
}
@@ -442,14 +447,15 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
return;
}
- task_pool = BLI_task_pool_create(&state, TASK_PRIORITY_HIGH);
- num_threads = BLI_task_scheduler_num_threads();
+ ParallelMempoolState state;
+ TaskPool *task_pool = BLI_task_pool_create(&state, TASK_PRIORITY_HIGH);
+ const int num_threads = BLI_task_scheduler_num_threads();
/* The idea here is to prevent creating task for each of the loop iterations
* and instead have tasks which are evenly distributed across CPU cores and
* pull next item to be crunched using the threaded-aware BLI_mempool_iter.
*/
- num_tasks = num_threads + 2;
+ const int num_tasks = num_threads + 2;
state.userdata = userdata;
state.func = func;
@@ -461,10 +467,13 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
ParallelMempoolTaskData *mempool_iterator_data = mempool_iter_threadsafe_create(
mempool, (size_t)num_tasks);
- for (i = 0; i < num_tasks; i++) {
+ for (int i = 0; i < num_tasks; i++) {
if (use_userdata_chunk) {
userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i);
memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
+ if (settings->func_init != NULL) {
+ settings->func_init(userdata, userdata_chunk_local);
+ }
}
mempool_iterator_data[i].tls.userdata_chunk = userdata_chunk_local;
@@ -477,7 +486,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
if (use_userdata_chunk) {
if ((settings->func_free != NULL) || (settings->func_reduce != NULL)) {
- for (i = 0; i < num_tasks; i++) {
+ for (int i = 0; i < num_tasks; i++) {
if (settings->func_reduce) {
settings->func_reduce(
userdata, userdata_chunk, mempool_iterator_data[i].tls.userdata_chunk);
diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc
index 871d04c1f35..8407be2cb2b 100644
--- a/source/blender/blenlib/intern/task_range.cc
+++ b/source/blender/blenlib/intern/task_range.cc
@@ -156,7 +156,7 @@ int BLI_task_parallel_thread_id(const TaskParallelTLS *UNUSED(tls))
if (thread_id == -1) {
thread_id = atomic_fetch_and_add_int32(&tbb_thread_id_counter, 1);
if (thread_id >= BLENDER_MAX_THREADS) {
- BLI_assert(!"Maximum number of threads exceeded for sculpting");
+ BLI_assert_msg(0, "Maximum number of threads exceeded for sculpting");
thread_id = thread_id % BLENDER_MAX_THREADS;
}
}
diff --git a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
index 59c4be6d952..08a3818e18f 100644
--- a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
@@ -353,27 +353,27 @@ void graph_draw(const std::string &label,
const vec2<T> &uco = verts[e.first];
const vec2<T> &vco = verts[e.second];
int strokew = thin_line;
- f << "<line fill=\"none\" stroke=\"black\" stroke-width=\"" << strokew << "\" x1=\""
+ f << R"(<line fill="none" stroke="black" stroke-width=")" << strokew << "\" x1=\""
<< SX(uco[0]) << "\" y1=\"" << SY(uco[1]) << "\" x2=\"" << SX(vco[0]) << "\" y2=\""
<< SY(vco[1]) << "\">\n";
f << " <title>[" << e.first << "][" << e.second << "]</title>\n";
f << "</line>\n";
if (draw_edge_labels) {
f << "<text x=\"" << SX(0.5 * (uco[0] + vco[0])) << "\" y=\"" << SY(0.5 * (uco[1] + vco[1]))
- << "\" font-size=\"small\">";
+ << R"(" font-size="small">)";
f << "[" << e.first << "][" << e.second << "]</text>\n";
}
}
int i = 0;
for (const vec2<T> &vco : verts) {
- f << "<circle fill=\"black\" cx=\"" << SX(vco[0]) << "\" cy=\"" << SY(vco[1]) << "\" r=\""
+ f << R"(<circle fill="black" cx=")" << SX(vco[0]) << "\" cy=\"" << SY(vco[1]) << "\" r=\""
<< vert_radius << "\">\n";
f << " <title>[" << i << "]" << vco << "</title>\n";
f << "</circle>\n";
if (draw_vert_labels) {
f << "<text x=\"" << SX(vco[0]) + vert_radius << "\" y=\"" << SY(vco[1]) - vert_radius
- << "\" font-size=\"small\">[" << i << "]</text>\n";
+ << R"(" font-size="small">[)" << i << "]</text>\n";
}
++i;
}