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

aya: perf_buffer: call BytesMut::reserve() internally #243

Merged
merged 1 commit into from Apr 10, 2022

Conversation

alessandrod
Copy link
Collaborator

This changes PerfBuffer::read_events() to call BytesMut::reserve()
internally, and deprecates PerfBufferError::MoreSpaceNeeded.

This makes for a more ergonomic API, and allows for a more idiomatic
usage of BytesMut. For example consider:

let mut buffers = vec![BytesMut::with_capacity(N), ...];
loop {
    let events = oob_cpu_buf.read_events(&mut buffers).unwrap();
    for buf in &mut buffers[..events.read] {
        let sub: Bytes = buf.split_off(n).into();
        process_sub_buf(sub);
    }
    ...
}

This is a common way to process perf bufs, where a sub buffer is split
off from the original buffer and then processed. In the next iteration
of the loop when it's time to read again, two things can happen:

  • if processing of the sub buffer is complete and sub has been
    dropped, read_events() will call buf.reserve(sample_size) and hit a fast
    path in BytesMut that will just restore the original capacity of the
    buffer (assuming sample_size <= N).

  • if processing of the sub buffer hasn't ended (eg the buffer has been
    stored or is being processed in another thread),
    buf.reserve(sample_size) will actually allocate the new memory required
    to read the sample.

In other words, calling buf.reserve(sample_size) inside read_events()
simplifies doing zero-copy processing of buffers in many cases.

This changes PerfBuffer::read_events() to call BytesMut::reserve()
internally, and deprecates PerfBufferError::MoreSpaceNeeded.

This makes for a more ergonomic API, and allows for a more idiomatic
usage of BytesMut. For example consider:

    let mut buffers = vec![BytesMut::with_capacity(N), ...];
    loop {
        let events = oob_cpu_buf.read_events(&mut buffers).unwrap();
        for buf in &mut buffers[..events.read] {
            let sub: Bytes = buf.split_off(n).into();
            process_sub_buf(sub);
        }
        ...
    }

This is a common way to process perf bufs, where a sub buffer is split
off from the original buffer and then processed. In the next iteration
of the loop when it's time to read again, two things can happen:

- if processing of the sub buffer is complete and `sub` has been
dropped, read_events() will call buf.reserve(sample_size) and hit a fast
path in BytesMut that will just restore the original capacity of the
buffer (assuming sample_size <= N).

- if processing of the sub buffer hasn't ended (eg the buffer has been
stored or is being processed in another thread),
buf.reserve(sample_size) will actually allocate the new memory required
to read the sample.

In other words, calling buf.reserve(sample_size) inside read_events()
simplifies doing zero-copy processing of buffers in many cases.
@alessandrod alessandrod merged commit a1d4499 into aya-rs:main Apr 10, 2022
@dave-tucker dave-tucker added fix A PR that is a small change or fixes a bug aya This is about aya (userspace) labels Apr 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aya This is about aya (userspace) fix A PR that is a small change or fixes a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants