Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vector clock to epoll ready lists #3932

Merged
merged 4 commits into from
Oct 2, 2024
Merged

Add vector clock to epoll ready lists #3932

merged 4 commits into from
Oct 2, 2024

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Oct 2, 2024

Replaces #3928

Fixes #3911

This test demonstrates the need to synchronize the clock
of the thread waking up from an epoll_wait from the thread
that issued the epoll awake event.
A couple of instructions were left over from an earlier rebase
it would seem. They don't impact the logic but the ready_list type
is about to change in the next commit.

Rather than modify one of these lines in the commit that changes
ready_list, only to have these lines removed later on, remove them now.
They don't impact the tests results.
This adds a VClock to the epoll implementation's ready_list
and has this VClock synced from the thread that updates
an event in the ready_list and then has the VClocks of any
threads being made runnable again, out of the calls to
epoll_wait, synced from it.
A simplification that doesn't impact the epoll implementation's logic.

It is not necessary to clone the ready_list before reading its
`is_empty` state.

This avoids the clone step but more importantly avoids the invisible
drop step of the clone.
@oli-obk
Copy link
Contributor Author

oli-obk commented Oct 2, 2024

@bors r+

@bors
Copy link
Contributor

bors commented Oct 2, 2024

📌 Commit d7695a0 has been approved by oli-obk

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Oct 2, 2024

⌛ Testing commit d7695a0 with merge 483eb7d...

@bors
Copy link
Contributor

bors commented Oct 2, 2024

☀️ Test successful - checks-actions
Approved by: oli-obk
Pushing 483eb7d to master...

@bors bors merged commit 483eb7d into master Oct 2, 2024
8 checks passed
@bors bors deleted the epoll-with-vector-clock branch October 2, 2024 21:00
#[derive(Debug, Default)]
struct ReadyList {
mapping: RefCell<BTreeMap<(FdId, i32), EpollEventInstance>>,
clock: RefCell<VClock>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we say in the issue that we wanted a clock per event?

That would avoid accidentally synchronizing with events we didn't even receive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RalfJung Do you feel this synch is too broad?

/// Callback function after epoll_wait unblocks
fn blocking_epoll_callback<'tcx>(
    epfd_value: i32,
    weak_epfd: WeakFileDescriptionRef,
    dest: &MPlaceTy<'tcx>,
    events: &MPlaceTy<'tcx>,
    ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx> {
    let Some(epfd) = weak_epfd.upgrade() else {
        throw_unsup_format!("epoll FD {epfd_value} got closed while blocking.")
    };

    let epoll_file_description = epfd
        .downcast::<Epoll>()
        .ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_wait`"))?;

    let ready_list = epoll_file_description.get_ready_list();

    // Synchronize waking thread from the epoll ready list.
    ecx.acquire_clock(&ready_list.clock.borrow());

    let mut ready_list = ready_list.mapping.borrow_mut();
    let mut num_of_events: i32 = 0;
    let mut array_iter = ecx.project_array_fields(events)?;

    while let Some(des) = array_iter.next(ecx)? {
        if let Some(epoll_event_instance) = ready_list_next(ecx, &mut ready_list) {
            ecx.write_int_fields_named(
                &[
                    ("events", epoll_event_instance.events.into()),
                    ("u64", epoll_event_instance.data.into()),
                ],
                &des.1,
            )?;
            num_of_events = num_of_events.strict_add(1);
        } else {
            break;
        }
    }
    ecx.write_int(num_of_events, dest)?;
    interp_ok(())
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what you are currently doing, right? Yes I think this syncs too much: #3944

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Epoll deadlock on tokio's test
4 participants