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

EventLock API #2

Closed
wants to merge 1 commit into from
Closed

Conversation

withoutboats
Copy link
Contributor

Built on top of #1, will rebase after that merges.

I didn't make this take ownership of the Event, because I think that would not be wanted. Users should not be holding the lock on the event for unduly long anyway; having the lock take a lifetime discourages storing the lock for longer than needed. If you feel otherwise, I can revise.

All of the synchronization occurs when the lock is taken in Event::lock; if there are no listeners to notify at that point, a lock is simply not taken (rather than holding the lock while performing unrelated operations and doing no-op notifications). I think that's the best performance, but maybe its surprising that the lock isn't always taken - I've documented that fact in the method's docs.

@withoutboats withoutboats force-pushed the event-lock branch 2 times, most recently from 5de5a4f to 004852c Compare May 19, 2020 18:27
This allows a user to issue multiple notifications during a single
hold of the lock, while interleaving other operations with those
notifications.
@withoutboats
Copy link
Contributor Author

rebased

@ghost
Copy link

ghost commented May 19, 2020

Thanks for the PR! Do you have an example use case for this?

If my thinking is right, this is useful when we want to emit a notification before knowing how many listeners to notify? And I guess we don't want to emit notifications after figuring out how many notifications to emit because that might cause spurious wakeups?

@withoutboats
Copy link
Contributor Author

In ringbahn, with Event::notify, I first wake all the completed task, then notify that many listeners that there is space on the queue for their submissions. This means that all completed tasks get woken before all tasks waiting to submit work. If the completed tasks perform IO, the waiting tasks get starved.

One option is to wake all waiting tasks before all completed tasks. This doesn't require any new API here, just some code to determine how much space there will be on the queue before processing completed tasks.

Another option is to wake one event listener, then one completed task - one in, one out. This sort of pattern, where the user interleaves other operations with notifications, is what this API enables.

@ghost
Copy link

ghost commented May 20, 2020

Another option is to wake one event listener, then one completed task - one in, one out. This sort of pattern, where the user interleaves other operations with notifications, is what this API enables.

notify(n) does not wake n additional tasks - it only makes sure that among all current listeners, n of them are notified. That means notify(1) quickly twice in a row is same as just a single notify(1).

Are you taking that into account when interleaving other operations with notifications?

@withoutboats
Copy link
Contributor Author

withoutboats commented May 20, 2020

Ah, you're right because of the change to check NOTIFIED if n is 1.

EDIT: but that isn't true with this lock API. each subsequent call will add up, so two calls to notify(1) on the lock would be equivalent to notify(2).

@ghost
Copy link

ghost commented May 20, 2020

I think notifications still don't add up because each notify(1) starts from the beginning of the linked list. There should be a new method, perhaps named notify_additional(1). It'd be wise to have a pointer to the first unnotified listener too, so that we avoid O(n^2) time complexity.

@withoutboats
Copy link
Contributor Author

Ah, got it. I'll close this for now. For my use case, anyway, it's probably better to wake all the waiting tasks with a single notify() call rather than interleaving operations like this.

notgull added a commit that referenced this pull request Feb 26, 2024
Signed-off-by: John Nunley <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant