1385 lines
33 KiB
C
1385 lines
33 KiB
C
#include <addons.h>
|
|
|
|
static ECS_COMPONENT_DECLARE(Position);
|
|
static ECS_DECLARE(Tag);
|
|
|
|
void MultiTaskThread_setup(void) {
|
|
ecs_log_set_level(-3);
|
|
}
|
|
|
|
void MultiTaskThread_Progress(ecs_iter_t *it) {
|
|
Position *pos = ecs_field(it, Position, 1);
|
|
int row;
|
|
for (row = 0; row < it->count; row ++) {
|
|
Position *p = &pos[row];
|
|
p->x ++;
|
|
}
|
|
}
|
|
|
|
static
|
|
ecs_world_t* init_world(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
|
|
ECS_SYSTEM(world, MultiTaskThread_Progress, EcsOnUpdate, Position);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = MultiTaskThread_Progress,
|
|
.multi_threaded = true
|
|
});
|
|
|
|
return world;
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_10_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 10, THREADS = 2;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_2_thread_1_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 1, THREADS = 2;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_2_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 2, THREADS = 2;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_5_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 5, THREADS = 2;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_3_thread_10_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 10, THREADS = 3;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_3_thread_1_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 1, THREADS = 3;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_3_thread_2_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 2, THREADS = 3;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_3_thread_5_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 5, THREADS = 3;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_4_thread_10_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 10, THREADS = 4;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_4_thread_1_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 1, THREADS = 4;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_4_thread_2_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 2, THREADS = 4;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_4_thread_5_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 5, THREADS = 4;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_5_thread_10_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 10, THREADS = 5;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_5_thread_1_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 1, THREADS = 5;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_5_thread_2_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 2, THREADS = 5;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_5_thread_5_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 5, THREADS = 5;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_6_thread_10_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 10, THREADS = 6;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_6_thread_1_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 1, THREADS = 6;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
|
|
void MultiTaskThread_6_thread_2_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 2, THREADS = 6;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_6_thread_5_entity(void) {
|
|
ecs_world_t *world = init_world();
|
|
|
|
int i, ENTITIES = 5, THREADS = 6;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_1_entity_instanced(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
|
|
ecs_entity_t s = ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = ecs_entity(world, {.add = {ecs_dependson(EcsOnUpdate)}}),
|
|
.callback = MultiTaskThread_Progress,
|
|
.query.filter = {
|
|
.expr = "Position",
|
|
.instanced = true
|
|
},
|
|
.multi_threaded = true
|
|
});
|
|
test_assert(s != 0);
|
|
|
|
int i, ENTITIES = 1, THREADS = 2;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_5_entity_instanced(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
|
|
ecs_entity_t s = ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = ecs_entity(world, {.add = {ecs_dependson(EcsOnUpdate)}}),
|
|
.callback = MultiTaskThread_Progress,
|
|
.query.filter = {
|
|
.expr = "Position",
|
|
.instanced = true
|
|
},
|
|
.multi_threaded = true
|
|
});
|
|
test_assert(s != 0);
|
|
|
|
int i, ENTITIES = 5, THREADS = 2;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_10_entity_instanced(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
|
|
ecs_entity_t s = ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = ecs_entity(world, {.add = {ecs_dependson(EcsOnUpdate)}}),
|
|
.callback = MultiTaskThread_Progress,
|
|
.query.filter = {
|
|
.expr = "Position",
|
|
.instanced = true
|
|
},
|
|
.multi_threaded = true
|
|
});
|
|
test_assert(s != 0);
|
|
|
|
int i, ENTITIES = 10, THREADS = 2;
|
|
ecs_entity_t *handles = ecs_os_alloca(sizeof(ecs_entity_t) * ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
handles[i] = ecs_new(world, Position);
|
|
ecs_set(world, handles[i], Position, {0});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 1);
|
|
}
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
test_int(ecs_get(world, handles[i], Position)->x, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
typedef struct Param {
|
|
ecs_entity_t entity;
|
|
int count;
|
|
} Param;
|
|
|
|
static
|
|
void TestSubset(ecs_iter_t *it) {
|
|
Param *param = it->param;
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
test_assert(param->entity != it->entities[i]);
|
|
param->count ++;
|
|
}
|
|
}
|
|
|
|
static
|
|
void TestAll(ecs_iter_t *it) {
|
|
Position *p = ecs_field(it, Position, 1);
|
|
|
|
ecs_entity_t TestSubset = ecs_field_id(it, 2);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
Param param = {.entity = it->entities[i], 0};
|
|
ecs_run_w_filter(it->world, TestSubset, 1, it->frame_offset + i + 1, 0, ¶m);
|
|
p[i].x += param.count;
|
|
}
|
|
}
|
|
|
|
static
|
|
void test_combs_100_entity(int THREADS) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
|
|
ECS_SYSTEM(world, TestSubset, 0, Position);
|
|
ECS_SYSTEM(world, TestAll, EcsOnUpdate, Position, TestSubset());
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = TestAll,
|
|
.multi_threaded = true
|
|
});
|
|
|
|
int i, ENTITIES = 100;
|
|
|
|
const ecs_entity_t *ids = ecs_bulk_new(world, Position, ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
ecs_set(world, ids[i], Position, {1, 2});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
const Position *p = ecs_get(world, ids[i], Position);
|
|
test_int(p->x, ENTITIES - i);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_test_combs_100_entity_w_next_worker(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
|
|
ECS_SYSTEM(world, TestSubset, 0, Position);
|
|
|
|
ecs_query_t *q = ecs_query_new(world, "Position, TestSubset()");
|
|
|
|
int i, ENTITIES = 100;
|
|
|
|
const ecs_entity_t *ids = ecs_bulk_new(world, Position, ENTITIES);
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
ecs_set(world, ids[i], Position, {1, 2});
|
|
}
|
|
|
|
ecs_iter_t it = ecs_query_iter(world, q);
|
|
ecs_iter_t wit = ecs_worker_iter(&it, 0, 2);
|
|
while (ecs_worker_next(&wit)) {
|
|
TestAll(&wit);
|
|
}
|
|
|
|
it = ecs_query_iter(world, q);
|
|
wit = ecs_worker_iter(&it, 1, 2);
|
|
while (ecs_worker_next(&wit)) {
|
|
TestAll(&wit);
|
|
}
|
|
|
|
for (i = 0; i < ENTITIES; i ++) {
|
|
const Position *p = ecs_get(world, ids[i], Position);
|
|
test_int(p->x, ENTITIES - i);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_test_combs_100_entity(void) {
|
|
test_combs_100_entity(2);
|
|
}
|
|
|
|
void MultiTaskThread_3_thread_test_combs_100_entity(void) {
|
|
test_combs_100_entity(3);
|
|
}
|
|
|
|
void MultiTaskThread_4_thread_test_combs_100_entity(void) {
|
|
test_combs_100_entity(4);
|
|
}
|
|
|
|
void MultiTaskThread_5_thread_test_combs_100_entity(void) {
|
|
test_combs_100_entity(5);
|
|
}
|
|
|
|
void MultiTaskThread_6_thread_test_combs_100_entity(void) {
|
|
test_combs_100_entity(6);
|
|
}
|
|
|
|
static
|
|
void test_combs_100_entity_2_types(int THREADS) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Type, Position, Velocity);
|
|
|
|
ECS_SYSTEM(world, TestSubset, 0, Position);
|
|
ECS_SYSTEM(world, TestAll, EcsOnUpdate, Position, TestSubset());
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = TestAll,
|
|
.multi_threaded = true
|
|
});
|
|
|
|
int i, ENTITIES = 100;
|
|
|
|
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, ENTITIES / 2);
|
|
ecs_entity_t ids_1[50];
|
|
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * ENTITIES / 2);
|
|
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, ENTITIES / 2);
|
|
|
|
for (i = 0; i < ENTITIES / 2; i ++) {
|
|
ecs_set(world, ids_1[i], Position, {1, 2});
|
|
ecs_set(world, ids_2[i], Position, {1, 2});
|
|
}
|
|
|
|
ecs_set_task_threads(world, THREADS);
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES / 2; i ++) {
|
|
const Position *p = ecs_get(world, ids_1[i], Position);
|
|
test_int(p->x, ENTITIES - i);
|
|
|
|
p = ecs_get(world, ids_2[i], Position);
|
|
test_int(p->x, ENTITIES - (i + ENTITIES / 2));
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_2_thread_test_combs_100_entity_2_types(void) {
|
|
test_combs_100_entity_2_types(2);
|
|
}
|
|
|
|
void MultiTaskThread_3_thread_test_combs_100_entity_2_types(void) {
|
|
test_combs_100_entity_2_types(3);
|
|
}
|
|
|
|
void MultiTaskThread_4_thread_test_combs_100_entity_2_types(void) {
|
|
test_combs_100_entity_2_types(4);
|
|
}
|
|
|
|
void MultiTaskThread_5_thread_test_combs_100_entity_2_types(void) {
|
|
test_combs_100_entity_2_types(5);
|
|
}
|
|
|
|
void MultiTaskThread_6_thread_test_combs_100_entity_2_types(void) {
|
|
test_combs_100_entity_2_types(6);
|
|
}
|
|
|
|
void MultiTaskThread_change_thread_count(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Type, Position, Velocity);
|
|
|
|
ECS_SYSTEM(world, TestSubset, 0, Position);
|
|
ECS_SYSTEM(world, TestAll, EcsOnUpdate, Position, TestSubset());
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = TestAll,
|
|
.multi_threaded = true
|
|
});
|
|
|
|
int i, ENTITIES = 100;
|
|
|
|
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, ENTITIES / 2);
|
|
ecs_entity_t ids_1[50];
|
|
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * ENTITIES / 2);
|
|
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, ENTITIES / 2);
|
|
|
|
for (i = 0; i < ENTITIES / 2; i ++) {
|
|
ecs_set(world, ids_1[i], Position, {1, 2});
|
|
ecs_set(world, ids_2[i], Position, {1, 2});
|
|
}
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES / 2; i ++) {
|
|
Position *p = ecs_get_mut(world, ids_1[i], Position);
|
|
test_int(p->x, ENTITIES - i);
|
|
p->x = 1;
|
|
|
|
p = ecs_get_mut(world, ids_2[i], Position);
|
|
test_int(p->x, ENTITIES - (i + ENTITIES / 2));
|
|
p->x = 1;
|
|
}
|
|
|
|
ecs_set_task_threads(world, 3);
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
for (i = 0; i < ENTITIES / 2; i ++) {
|
|
const Position *p = ecs_get(world, ids_1[i], Position);
|
|
test_int(p->x, ENTITIES - i);
|
|
|
|
p = ecs_get(world, ids_2[i], Position);
|
|
test_int(p->x, ENTITIES - (i + ENTITIES / 2));
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void QuitSystem(ecs_iter_t *it) {
|
|
ecs_quit(it->world);
|
|
}
|
|
|
|
void MultiTaskThread_multithread_quit(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
|
|
ECS_SYSTEM(world, QuitSystem, EcsOnUpdate, Position);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = QuitSystem,
|
|
.multi_threaded = true
|
|
});
|
|
|
|
ecs_bulk_new(world, Position, 100);
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
test_assert( ecs_progress(world, 0) == 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static bool has_ran = false;
|
|
|
|
static
|
|
void MtTask(ecs_iter_t *it) {
|
|
has_ran = true;
|
|
}
|
|
|
|
void MultiTaskThread_schedule_w_tasks(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_SYSTEM(world, MtTask, EcsOnUpdate, 0);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = MtTask,
|
|
.multi_threaded = true
|
|
});
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
test_assert( ecs_progress(world, 0) != 0);
|
|
|
|
test_assert( has_ran == true);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void ReactiveDummySystem(ecs_iter_t * it) {
|
|
has_ran = true;
|
|
}
|
|
|
|
static
|
|
void PeriodicDummySystem(ecs_iter_t * it) {
|
|
ecs_id_t ecs_id(Position) = ecs_field_id(it, 1);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i++ ) {
|
|
ecs_set(it->world, it->entities[i], Position, {0});
|
|
}
|
|
}
|
|
|
|
void MultiTaskThread_reactive_system(void) {
|
|
ecs_world_t * world = ecs_init();
|
|
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
ECS_SYSTEM(world, PeriodicDummySystem, EcsOnUpdate, Position);
|
|
ECS_OBSERVER(world, ReactiveDummySystem, EcsOnSet, Position);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = PeriodicDummySystem,
|
|
.multi_threaded = true
|
|
});
|
|
|
|
ecs_bulk_new(world, Position, 2);
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
test_assert(has_ran == false);
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
test_assert(has_ran == true);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_fini_after_set_threads(void) {
|
|
ecs_world_t * world = ecs_init();
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
ecs_fini(world);
|
|
|
|
// Make sure code doesn't crash
|
|
test_assert(true);
|
|
}
|
|
|
|
static
|
|
void SingleThreadedSystem(ecs_iter_t * it) {
|
|
Position *p = ecs_field(it, Position, 1);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i++ ) {
|
|
p[i].x ++;
|
|
p[i].y ++;
|
|
}
|
|
}
|
|
|
|
void MultiTaskThread_2_threads_single_threaded_system(void) {
|
|
ecs_world_t * world = ecs_init();
|
|
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
ECS_SYSTEM(world, SingleThreadedSystem, EcsOnUpdate, Position);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = SingleThreadedSystem,
|
|
.multi_threaded = false
|
|
});
|
|
|
|
ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20});
|
|
ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30});
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 11);
|
|
test_int(p->y, 21);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 21);
|
|
test_int(p->y, 31);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static int create_query_invoked = 0;
|
|
|
|
static
|
|
void CreateQuery(ecs_iter_t *it) {
|
|
ecs_query_new(it->world, "0");
|
|
create_query_invoked ++;
|
|
}
|
|
|
|
void MultiTaskThread_no_staging_w_multithread(void) {
|
|
for (int i = 0; i < 10; i ++) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_set_task_threads(world, 32);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.callback = CreateQuery,
|
|
.no_readonly = true,
|
|
.entity = ecs_entity(world, {.add = {ecs_dependson(EcsOnUpdate)}})
|
|
});
|
|
|
|
create_query_invoked = 0;
|
|
ecs_progress(world, 0);
|
|
test_int(create_query_invoked, 1);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
test_assert(true);
|
|
}
|
|
|
|
void MultiTaskThread_multithread_w_monitor_addon(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
ECS_IMPORT(world, FlecsMonitor);
|
|
ecs_set_task_threads(world, 4);
|
|
ecs_progress(world, 0);
|
|
ecs_fini(world);
|
|
|
|
/* Make sure monitor could be run in multithreaded mode */
|
|
test_assert(true);
|
|
}
|
|
|
|
static int system_ctx = 0;
|
|
|
|
static
|
|
void System_w_ctx(ecs_iter_t *it) {
|
|
test_assert(it->ctx == &system_ctx);
|
|
test_assert(it->system != 0);
|
|
test_assert(it->delta_time != 0);
|
|
system_ctx ++;
|
|
}
|
|
|
|
static
|
|
void System_run_w_ctx(ecs_iter_t *it) {
|
|
System_w_ctx(it);
|
|
ecs_iter_fini(it);
|
|
}
|
|
|
|
static
|
|
void System_w_binding_ctx(ecs_iter_t *it) {
|
|
test_assert(it->binding_ctx == &system_ctx);
|
|
test_assert(it->system != 0);
|
|
test_assert(it->delta_time != 0);
|
|
system_ctx ++;
|
|
}
|
|
|
|
static
|
|
void System_run_w_binding_ctx(ecs_iter_t *it) {
|
|
System_w_binding_ctx(it);
|
|
ecs_iter_fini(it);
|
|
}
|
|
|
|
void MultiTaskThread_get_ctx(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = ecs_entity(world, { .add = { ecs_dependson(EcsOnUpdate) } }),
|
|
.callback = System_w_ctx,
|
|
.multi_threaded = true,
|
|
.ctx = &system_ctx
|
|
});
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
test_assert(system_ctx != 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_get_binding_ctx(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = ecs_entity(world, { .add = { ecs_dependson(EcsOnUpdate) } }),
|
|
.callback = System_w_binding_ctx,
|
|
.multi_threaded = true,
|
|
.binding_ctx = &system_ctx
|
|
});
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
test_assert(system_ctx != 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_get_ctx_w_run(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = ecs_entity(world, { .add = { ecs_dependson(EcsOnUpdate) } }),
|
|
.run = System_run_w_ctx,
|
|
.multi_threaded = true,
|
|
.ctx = &system_ctx
|
|
});
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
test_assert(system_ctx != 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_get_binding_ctx_w_run(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_set_task_threads(world, 2);
|
|
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = ecs_entity(world, { .add = { ecs_dependson(EcsOnUpdate) } }),
|
|
.run = System_run_w_binding_ctx,
|
|
.multi_threaded = true,
|
|
.binding_ctx = &system_ctx
|
|
});
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
test_assert(system_ctx != 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_sys(ecs_iter_t *it) { }
|
|
|
|
void MultiTaskThread_sys_bulk_init(ecs_iter_t *it) {
|
|
ecs_bulk_init(it->world, &(ecs_bulk_desc_t){
|
|
.count = 10,
|
|
.ids = {Tag}
|
|
});
|
|
}
|
|
|
|
void MultiTaskThread_bulk_new_in_no_readonly_w_multithread(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_TAG_DEFINE(world, Tag);
|
|
|
|
ecs_system(world, {
|
|
.entity = ecs_entity(world, { .add = { ecs_dependson(EcsOnUpdate) }}),
|
|
.no_readonly = true,
|
|
.callback = MultiTaskThread_sys_bulk_init
|
|
});
|
|
|
|
ecs_system(world, {
|
|
.entity = ecs_entity(world, { .add = { ecs_dependson(EcsOnUpdate) }}),
|
|
.multi_threaded = true,
|
|
.callback = MultiTaskThread_sys
|
|
});
|
|
|
|
ecs_set_task_threads(world, 80);
|
|
|
|
for (int i = 0; i < 100; i ++) {
|
|
ecs_progress(world, 0);
|
|
}
|
|
|
|
test_int(ecs_count(world, Tag), 100 * 10);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_sys_bulk_init_2(ecs_iter_t *it) {
|
|
ecs_bulk_init(it->world, &(ecs_bulk_desc_t){
|
|
.count = 1,
|
|
.ids = {ecs_id(Position)}
|
|
});
|
|
|
|
ecs_iter_t qit = ecs_query_iter(it->world, it->ctx);
|
|
ecs_iter_fini(&qit);
|
|
}
|
|
|
|
void MultiTaskThread_bulk_new_in_no_readonly_w_multithread_2(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT_DEFINE(world, Position);
|
|
|
|
ecs_set_task_threads(world, 64);
|
|
|
|
ecs_system(world, {
|
|
.entity = ecs_entity(world, {
|
|
.add = { ecs_dependson(EcsOnUpdate) }
|
|
}),
|
|
.query.filter.terms = {{ ecs_id(Position) }},
|
|
.callback = MultiTaskThread_sys
|
|
});
|
|
|
|
ecs_query_t *q = ecs_query(world, {
|
|
.filter.terms = {{ ecs_id(Position) }}
|
|
});
|
|
|
|
ecs_system(world, {
|
|
.entity = ecs_entity(world, {
|
|
.add = { ecs_dependson(EcsOnUpdate) }
|
|
}),
|
|
.callback = MultiTaskThread_sys_bulk_init_2,
|
|
.no_readonly = true,
|
|
.ctx = q
|
|
});
|
|
|
|
ecs_system(world, {
|
|
.entity = ecs_entity(world, {
|
|
.add = { ecs_dependson(EcsOnUpdate) }
|
|
}),
|
|
.callback = MultiTaskThread_sys
|
|
});
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
test_int(ecs_count(world, Position), 1);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static ecs_os_thread_id_t main_thread;
|
|
static int invoked_count = 0;
|
|
static int invoked_main_count = 0;
|
|
|
|
static void dummy(ecs_iter_t *it) {
|
|
int stage_id = ecs_get_stage_id(it->world);
|
|
|
|
if (stage_id == 0) {
|
|
test_assert(main_thread == ecs_os_thread_self());
|
|
ecs_os_ainc(&invoked_main_count);
|
|
} else {
|
|
test_assert(main_thread != ecs_os_thread_self());
|
|
}
|
|
|
|
ecs_os_ainc(&invoked_count);
|
|
}
|
|
|
|
void MultiTaskThread_run_first_worker_on_main(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_system(world, {
|
|
.entity = ecs_entity(world, { .add = { ecs_dependson(EcsOnUpdate) }}),
|
|
.multi_threaded = true,
|
|
.callback = dummy
|
|
});
|
|
|
|
ecs_set_task_threads(world, 3);
|
|
|
|
main_thread = ecs_os_thread_self();
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
test_int(invoked_count, 3);
|
|
test_int(invoked_main_count, 1);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void MultiTaskThread_run_single_thread_on_main(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_system(world, {
|
|
.entity = ecs_entity(world, { .add = { ecs_dependson(EcsOnUpdate) }}),
|
|
.multi_threaded = false,
|
|
.callback = dummy
|
|
});
|
|
|
|
ecs_set_task_threads(world, 3);
|
|
|
|
main_thread = ecs_os_thread_self();
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
test_int(invoked_count, 1);
|
|
test_int(invoked_main_count, 1);
|
|
|
|
ecs_fini(world);
|
|
}
|