Flecs-Rust icon indicating copy to clipboard operation
Flecs-Rust copied to clipboard

Using get in a multithreaded system leads to an abort

Open TestingPlant opened this issue 8 months ago • 1 comments

Code:

fn main() {
    use flecs_ecs::prelude::*;

    #[derive(Component, Copy, Clone, Debug)]
    struct Foo {
        a: u64,
    }

    #[derive(Component, Copy, Clone, Debug)]
    struct Bar {
        a: u64,
    }

    let world = World::new();

    for _ in 0..4 {
        world.entity().set(Foo { a: 5 }).set(Bar { a: 1 });
    }

    let system = system!("a", world, &Foo)
        .multi_threaded()
        .each_iter(|it, index, foo| {
            let entity = it.entity(index).unwrap();
            entity.get::<&Bar>(|_| {});
        });

    let mut app = world.app();
    app.set_threads(4);
    app.run();
}

This code seems to trigger one of two different assertions when ran:

fatal: flecs.c: 55035: assert: !ecs_is_deferred(world) cannot call progress while world is deferred (INVALID_OPERATION)
Stack trace
#0  __pthread_kill_implementation (threadid=281474842230816, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#1  0x0000fffff7e5f244 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2  0x0000fffff7e1a67c in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x0000fffff7e07130 in __GI_abort () at ./stdlib/abort.c:79
#4  0x0000aaaaaabba8d0 in flecs_workers_progress (world=0xaaaaaacd7b10, pq=0xaaaaaadb95f0, delta_time=0.0169759355) at src/flecs.c:55035
#5  0x0000aaaaaabb7f9c in ecs_progress (world=0xaaaaaacd7b10, user_delta_time=0) at src/flecs.c:54617
#6  0x0000aaaaaab5c680 in flecs_default_frame_action (world=0xaaaaaacd7b10, desc=0xaaaaaacd6948 <ecs_app_desc>) at src/flecs.c:21559
#7  0x0000aaaaaab5c82c in ecs_app_run_frame (world=0xaaaaaacd7b10, desc=0xaaaaaacd6948 <ecs_app_desc>) at src/flecs.c:21641
#8  0x0000aaaaaab5c620 in flecs_default_run_action (world=0xaaaaaacd7b10, desc=0xaaaaaacd6948 <ecs_app_desc>) at src/flecs.c:21538
#9  0x0000aaaaaab5c7d4 in ecs_app_run (world=0xaaaaaacd7b10, desc=0xfffffffff098) at src/flecs.c:21634
#10 0x0000aaaaaaad4c14 in flecs_ecs::addons::app::App::run (self=0xfffffffff098) at src/addons/app.rs:139
#11 0x0000aaaaaaab58e4 in flecs_repro::main () at src/main.rs:29
fatal: flecs.c: 10671: assert: stage->defer > 0 INTERNAL_ERROR
Stack trace
#0  __pthread_kill_implementation (threadid=281474842230816, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#1  0x0000fffff7e5f244 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2  0x0000fffff7e1a67c in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x0000fffff7e07130 in __GI_abort () at ./stdlib/abort.c:79
#4  0x0000aaaaaab3b2cc in flecs_defer_end (world=0xaaaaaacd7b10, stage=0xaaaaaacdf250) at src/flecs.c:10671
#5  0x0000aaaaaab508b8 in flecs_stage_merge (world=0xaaaaaacd7b10) at src/flecs.c:17319
#6  0x0000aaaaaab53664 in ecs_readonly_end (world=0xaaaaaacd7b10) at src/flecs.c:18063
#7  0x0000aaaaaabb7aa8 in flecs_run_pipeline (world=0xaaaaaacd7b10, pq=0xaaaaaadb95f0, delta_time=0.0169658158) at src/flecs.c:54525
#8  0x0000aaaaaabba944 in flecs_workers_progress (world=0xaaaaaacd7b10, pq=0xaaaaaadb95f0, delta_time=0.0169658158) at src/flecs.c:55044
#9  0x0000aaaaaabb7f9c in ecs_progress (world=0xaaaaaacd7b10, user_delta_time=0) at src/flecs.c:54617
#10 0x0000aaaaaab5c680 in flecs_default_frame_action (world=0xaaaaaacd7b10, desc=0xaaaaaacd6948 <ecs_app_desc>) at src/flecs.c:21559
#11 0x0000aaaaaab5c82c in ecs_app_run_frame (world=0xaaaaaacd7b10, desc=0xaaaaaacd6948 <ecs_app_desc>) at src/flecs.c:21641
#12 0x0000aaaaaab5c620 in flecs_default_run_action (world=0xaaaaaacd7b10, desc=0xaaaaaacd6948 <ecs_app_desc>) at src/flecs.c:21538
#13 0x0000aaaaaab5c7d4 in ecs_app_run (world=0xaaaaaacd7b10, desc=0xfffffffff098) at src/flecs.c:21634
#14 0x0000aaaaaaad4c14 in flecs_ecs::addons::app::App::run (self=0xfffffffff098) at src/addons/app.rs:139
#15 0x0000aaaaaaab58e4 in flecs_repro::main () at src/main.rs:29

I am on aarch64-unknown-linux-gnu and testing on the latest flecs_ecs commit (9c7e8939a784b110c442f4f061fe46dc10fbb3cf).

TestingPlant avatar May 20 '25 04:05 TestingPlant

Adding an entity in a multithreaded system seems to abort also:

fn main() {
    use flecs_ecs::prelude::*;
 
    #[derive(Component, Copy, Clone, Debug)]
    struct Foo {
        a: u64,
    }
 
    let world = World::new();
 
    world.entity().set(Foo { a: 5 });
 
    let system = system!("a", world, &Foo)
        .multi_threaded()
        .each_iter(move |it, index, foo| {
            let world = it.world();
            world.entity().set(Foo { a: 5 });
        });
 
    let mut app = world.app();
    app.set_threads(4);
    app.run();
}
fatal: flecs.c: 8763: assert: ecs_is_alive(world, entity) INVALID_PARAMETER
Stack trace
#0  __pthread_kill_implementation (threadid=281474842230816, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#1  0x0000fffff7e5f244 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2  0x0000fffff7e1a67c in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x0000fffff7e07130 in __GI_abort () at ./stdlib/abort.c:79
#4  0x0000aaaaaab31cb4 in ecs_ensure_modified_id (world=0xaaaaaacdb250, entity=577, id=33) at src/flecs.c:8763
#5  0x0000aaaaaaab1388 in flecs_ecs::core::utility::functions::set_helper<flecs_repro::main::Foo> (world=0xaaaaaacdb250, entity=577, value=..., id=33)
    at /home/remote-dev/.cargo/git/checkouts/flecs-rust-182003fcd2303c9b/9c7e893/flecs_ecs/src/core/utility/functions.rs:297
#6  0x0000aaaaaaab23e0 in flecs_ecs::core::entity_view::entity_view_const::EntityView::set<flecs_repro::main::Foo> (self=..., component=...)
    at /home/remote-dev/.cargo/git/checkouts/flecs-rust-182003fcd2303c9b/9c7e893/flecs_ecs/src/core/entity_view/entity_view_mut.rs:399
#7  0x0000aaaaaaaaec8c in flecs_repro::main::{closure#0} (it=..., index=0, foo=0xaaaaaaf5b7e0) at src/main.rs:17
#8  0x0000aaaaaaab0828 in flecs_ecs::core::utility::traits::private::internal_SystemAPI::execute_each_iter<flecs_ecs::addons::system::system_builder::SystemBuilder<&flecs_repro::main::Foo>, (), &flecs_repro::main::Foo, flecs_repro::main::{closure_env#0}> (iter=0xffffffffe038)
    at /home/remote-dev/.cargo/git/checkouts/flecs-rust-182003fcd2303c9b/9c7e893/flecs_ecs/src/core/utility/traits/mod.rs:216
#9  0x0000aaaaaabe008c in flecs_run_intern (world=0xaaaaaacd3b10, stage=0xaaaaaacdb250, system=576, system_data=0xaaaaaaf74a90, stage_index=0,
    stage_count=4, delta_time=0.0166666675, param=0x0) at src/flecs.c:65398
#10 0x0000aaaaaabb5e0c in flecs_run_pipeline_ops (world=0xaaaaaacd3b10, stage=0xaaaaaacdb250, stage_index=0, stage_count=4, delta_time=0.0166666675)
    at src/flecs.c:54432
#11 0x0000aaaaaabb63d0 in flecs_run_pipeline (world=0xaaaaaacd3b10, pq=0xaaaaaadb55f0, delta_time=0.0166666675) at src/flecs.c:54501
#12 0x0000aaaaaabb9354 in flecs_workers_progress (world=0xaaaaaacd3b10, pq=0xaaaaaadb55f0, delta_time=0.0166666675) at src/flecs.c:55044
#13 0x0000aaaaaabb69ac in ecs_progress (world=0xaaaaaacd3b10, user_delta_time=0) at src/flecs.c:54617
#14 0x0000aaaaaab5b098 in flecs_default_frame_action (world=0xaaaaaacd3b10, desc=0xaaaaaacd2940 <ecs_app_desc>) at src/flecs.c:21559
#15 0x0000aaaaaab5b244 in ecs_app_run_frame (world=0xaaaaaacd3b10, desc=0xaaaaaacd2940 <ecs_app_desc>) at src/flecs.c:21641
#16 0x0000aaaaaab5b038 in flecs_default_run_action (world=0xaaaaaacd3b10, desc=0xaaaaaacd2940 <ecs_app_desc>) at src/flecs.c:21538
#17 0x0000aaaaaab5b1ec in ecs_app_run (world=0xaaaaaacd3b10, desc=0xfffffffff098) at src/flecs.c:21634
#18 0x0000aaaaaaad2808 in flecs_ecs::addons::app::App::run (self=0xfffffffff098) at src/addons/app.rs:139
#19 0x0000aaaaaaab3554 in flecs_repro::main () at src/main.rs:22

TestingPlant avatar May 20 '25 12:05 TestingPlant

fatal: flecs.c: 55035: assert: !ecs_is_deferred(world) cannot call progress while world is deferred (INVALID_OPERATION)
fatal: flecs.c: 10671: assert: stage->defer > 0 INTERNAL_ERROR

Both of these stack traces strongly suggest that there is another thread that is mutating the Flecs world. While the world is progressing, other threads should not be reading or writing to it. Only the multithreaded systems are allowed to read/write.

fatal: flecs.c: 8763: assert: ecs_is_alive(world, entity) INVALID_PARAMETER

You cannot create entities from multithreaded systems. Try making the system single threaded.

SanderMertens avatar Jul 01 '25 21:07 SanderMertens