Skip to content

Commit

Permalink
Fix crash when obtaining stats for pipeline with single task system
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed May 12, 2023
1 parent 40051d3 commit efa2613
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 53 deletions.
54 changes: 28 additions & 26 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -29350,36 +29350,38 @@ bool ecs_pipeline_stats_get(
ecs_map_init_if(&s->system_stats, NULL);

/* Make sure vector is large enough to store all systems & sync points */
ecs_entity_t *systems = NULL;
if (pip_count) {
ecs_vec_init_if_t(&s->systems, ecs_entity_t);
ecs_vec_set_count_t(NULL, &s->systems, ecs_entity_t, pip_count);
systems = ecs_vec_first_t(&s->systems, ecs_entity_t);

/* Populate systems vector, keep track of sync points */
it = ecs_query_iter(stage, pq->query);

int32_t i, i_system = 0, ran_since_merge = 0;
while (ecs_query_next(&it)) {
if (flecs_id_record_get_table(pq->idr_inactive, it.table) != NULL) {
continue;
}
if (op) {
ecs_entity_t *systems = NULL;
if (pip_count) {
ecs_vec_init_if_t(&s->systems, ecs_entity_t);
ecs_vec_set_count_t(NULL, &s->systems, ecs_entity_t, pip_count);
systems = ecs_vec_first_t(&s->systems, ecs_entity_t);

/* Populate systems vector, keep track of sync points */
it = ecs_query_iter(stage, pq->query);

int32_t i, i_system = 0, ran_since_merge = 0;
while (ecs_query_next(&it)) {
if (flecs_id_record_get_table(pq->idr_inactive, it.table) != NULL) {
continue;
}

for (i = 0; i < it.count; i ++) {
systems[i_system ++] = it.entities[i];
ran_since_merge ++;
if (op != op_last && ran_since_merge == op->count) {
ran_since_merge = 0;
op++;
systems[i_system ++] = 0; /* 0 indicates a merge point */
for (i = 0; i < it.count; i ++) {
systems[i_system ++] = it.entities[i];
ran_since_merge ++;
if (op != op_last && ran_since_merge == op->count) {
ran_since_merge = 0;
op++;
systems[i_system ++] = 0; /* 0 indicates a merge point */
}
}
}
}

systems[i_system ++] = 0; /* Last merge */
ecs_assert(pip_count == i_system, ECS_INTERNAL_ERROR, NULL);
} else {
ecs_vec_fini_t(NULL, &s->systems, ecs_entity_t);
systems[i_system ++] = 0; /* Last merge */
ecs_assert(pip_count == i_system, ECS_INTERNAL_ERROR, NULL);
} else {
ecs_vec_fini_t(NULL, &s->systems, ecs_entity_t);
}
}

/* Separately populate system stats map from build query, which includes
Expand Down
54 changes: 28 additions & 26 deletions src/addons/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,36 +583,38 @@ bool ecs_pipeline_stats_get(
ecs_map_init_if(&s->system_stats, NULL);

/* Make sure vector is large enough to store all systems & sync points */
ecs_entity_t *systems = NULL;
if (pip_count) {
ecs_vec_init_if_t(&s->systems, ecs_entity_t);
ecs_vec_set_count_t(NULL, &s->systems, ecs_entity_t, pip_count);
systems = ecs_vec_first_t(&s->systems, ecs_entity_t);

/* Populate systems vector, keep track of sync points */
it = ecs_query_iter(stage, pq->query);

int32_t i, i_system = 0, ran_since_merge = 0;
while (ecs_query_next(&it)) {
if (flecs_id_record_get_table(pq->idr_inactive, it.table) != NULL) {
continue;
}
if (op) {
ecs_entity_t *systems = NULL;
if (pip_count) {
ecs_vec_init_if_t(&s->systems, ecs_entity_t);
ecs_vec_set_count_t(NULL, &s->systems, ecs_entity_t, pip_count);
systems = ecs_vec_first_t(&s->systems, ecs_entity_t);

/* Populate systems vector, keep track of sync points */
it = ecs_query_iter(stage, pq->query);

int32_t i, i_system = 0, ran_since_merge = 0;
while (ecs_query_next(&it)) {
if (flecs_id_record_get_table(pq->idr_inactive, it.table) != NULL) {
continue;
}

for (i = 0; i < it.count; i ++) {
systems[i_system ++] = it.entities[i];
ran_since_merge ++;
if (op != op_last && ran_since_merge == op->count) {
ran_since_merge = 0;
op++;
systems[i_system ++] = 0; /* 0 indicates a merge point */
for (i = 0; i < it.count; i ++) {
systems[i_system ++] = it.entities[i];
ran_since_merge ++;
if (op != op_last && ran_since_merge == op->count) {
ran_since_merge = 0;
op++;
systems[i_system ++] = 0; /* 0 indicates a merge point */
}
}
}
}

systems[i_system ++] = 0; /* Last merge */
ecs_assert(pip_count == i_system, ECS_INTERNAL_ERROR, NULL);
} else {
ecs_vec_fini_t(NULL, &s->systems, ecs_entity_t);
systems[i_system ++] = 0; /* Last merge */
ecs_assert(pip_count == i_system, ECS_INTERNAL_ERROR, NULL);
} else {
ecs_vec_fini_t(NULL, &s->systems, ecs_entity_t);
}
}

/* Separately populate system stats map from build query, which includes
Expand Down
1 change: 1 addition & 0 deletions test/addons/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,7 @@
"get_pipeline_stats_after_progress_2_systems",
"get_pipeline_stats_after_progress_2_systems_one_merge",
"get_entity_count",
"get_pipeline_stats_w_task_system",
"get_not_alive_entity_count"
]
}, {
Expand Down
18 changes: 18 additions & 0 deletions test/addons/src/Stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,24 @@ void Stats_get_pipeline_stats_after_progress_2_systems_one_merge() {
ecs_fini(world);
}

void Stats_get_pipeline_stats_w_task_system() {
ecs_world_t *world = ecs_init();

ECS_SYSTEM(world, FooSys, EcsOnUpdate, 0);

ecs_entity_t pipeline = ecs_get_pipeline(world);
test_assert(pipeline != 0);

ecs_pipeline_stats_t stats = {0};
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
test_assert(ecs_map_count(&stats.system_stats) != 0); /* Inactive systems */
test_int(ecs_vec_count(&stats.systems), 0);

ecs_pipeline_stats_fini(&stats);

ecs_fini(world);
}

void Stats_get_entity_count() {
ecs_world_t *world = ecs_init();

Expand Down
7 changes: 6 additions & 1 deletion test/addons/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,7 @@ void Stats_get_pipeline_stats_after_progress_1_inactive_system(void);
void Stats_get_pipeline_stats_after_progress_2_systems(void);
void Stats_get_pipeline_stats_after_progress_2_systems_one_merge(void);
void Stats_get_entity_count(void);
void Stats_get_pipeline_stats_w_task_system(void);
void Stats_get_not_alive_entity_count(void);

// Testsuite 'Run'
Expand Down Expand Up @@ -5915,6 +5916,10 @@ bake_test_case Stats_testcases[] = {
"get_entity_count",
Stats_get_entity_count
},
{
"get_pipeline_stats_w_task_system",
Stats_get_pipeline_stats_w_task_system
},
{
"get_not_alive_entity_count",
Stats_get_not_alive_entity_count
Expand Down Expand Up @@ -6776,7 +6781,7 @@ static bake_test_suite suites[] = {
"Stats",
NULL,
NULL,
10,
11,
Stats_testcases
},
{
Expand Down

0 comments on commit efa2613

Please sign in to comment.