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

Revert "Optimize poll loop slightly" #225

Closed

Conversation

richarddd
Copy link
Contributor

This reverts commit ad76225.

Fixes #224

@DelSkayn
Copy link
Owner

DelSkayn commented Oct 6, 2023

Good catch! I didn't think about new futures being added while polling, however, won't the reverted code have the same problem as the current?

I believe the iterator returned by iter_mut will also be invalidated if a value is pushed into the vector, as they consist of just two pointers pointing to the memory of the vector.

The ultimate problem is that we have aliasing mutable references which will always be unsound.

I think the only proper solution is to implement the schedular with a linked list.

@richarddd
Copy link
Contributor Author

Good catch! I didn't think about new futures being added while polling, however, won't the reverted code have the same problem as the current?

Nope, because we are not mutating the array from inside the iterator. We are simply collecting indexes.

I believe the iterator returned by iter_mut will also be invalidated if a value is pushed into the vector, as they consist of just two pointers pointing to the memory of the vector.

The ultimate problem is that we have aliasing mutable references which will always be unsound.

I think the only proper solution is to implement the schedular with a linked list.

A double linked list might be an alternative but i suspect pointer following might have slight performance implications for lots of spawns.

@DelSkayn
Copy link
Owner

DelSkayn commented Oct 6, 2023

Nope, because we are not mutating the array from inside the iterator. We are simply collecting indexes.

I disagree, the for loop holds onto a iterator to the futures vector which is just a pointer to the memory of the vector. Then inside the for loop poll gets called which can push a new value into the futures vec. If that happens the futures vec memory might need to be reallocated, which can cause the memory which the iterator pointer is pointing to, to become invalid resulting, again, in a segfault.

We could possibly change to using indexes in the array, but I believe, because we are supposed to have exclusive access to the futures vec the compiler could decide to still optimize the array index away to again using pointers.

A double linked list might be an alternative but i suspect pointer following might have slight performance implications for lots of spawns.

If it is done right the schedular wouldn't even have to follow pointers that often. I have been thinking about implementing the schedular with two linked lists such that whenever a future calls wake on the waker, that waker moves the future into the should be polled list from the sleeping list. That way the shedular knows which futures to poll again, avoiding the possible quadratic complexity the schedular currently has.

@richarddd
Copy link
Contributor Author

Nope, because we are not mutating the array from inside the iterator. We are simply collecting indexes.

I disagree, the for loop holds onto a iterator to the futures vector which is just a pointer to the memory of the vector. Then inside the for loop poll gets called which can push a new value into the futures vec. If that happens the futures vec memory might need to be reallocated, which can cause the memory which the iterator pointer is pointing to, to become invalid resulting, again, in a segfault.

We could possibly change to using indexes in the array, but I believe, because we are supposed to have exclusive access to the futures vec the compiler could decide to still optimize the array index away to again using pointers.

A double linked list might be an alternative but i suspect pointer following might have slight performance implications for lots of spawns.

If it is done right the schedular wouldn't even have to follow pointers that often. I have been thinking about implementing the schedular with two linked lists such that whenever a future calls wake on the waker, that waker moves the future into the should be polled list from the sleeping list. That way the shedular knows which futures to poll again, avoiding the possible quadratic complexity the schedular currently has.

You are absolutely right, my bad. I think using two linked lists is a fantastic idea 👌

@richarddd
Copy link
Contributor Author

Closing in favor of #228

@richarddd richarddd closed this Oct 11, 2023
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.

Crash due to memory leak & undefined behaviour in spawn poller when spawning nested tasks
2 participants