-
Notifications
You must be signed in to change notification settings - Fork 309
allow to construct BytesMut with custom alignment #601
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,6 +142,65 @@ impl BytesMut { | |
pub fn with_capacity(capacity: usize) -> BytesMut { | ||
BytesMut::from_vec(Vec::with_capacity(capacity)) | ||
} | ||
|
||
/// Creates a new `BytesMut` with the specified capacity and alignment. | ||
/// | ||
/// The returned `BytesMut` will have alignment of `align` and be able to | ||
/// hold at least `capacity` bytes without reallocating. | ||
/// | ||
/// It is important to note that this function does not specify the length | ||
/// of the returned `BytesMut`, but only the capacity. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// use bytes::BytesMut; | ||
/// | ||
/// let bytes = BytesMut::with_capacity_aligned(65000, 4096); | ||
/// | ||
/// // `bytes` contains no data, even though there is capacity | ||
/// assert_eq!(bytes.len(), 0); | ||
/// // round up to match alignment | ||
/// assert_eq!(bytes.capacity(), 65536); | ||
/// ``` | ||
/// | ||
/// # Panics | ||
/// + If `align` is zero or not power of two by | ||
/// [Layout::from_size_align](std::alloc::Layout::from_size_align) | ||
/// + If `capacity` round up to `align` is excess `isize::MAX` by | ||
/// [Layout::from_size_align](std::alloc::Layout::from_size_align) | ||
/// + If out of memory by [GlobalAlloc::alloc](std::alloc::GlobalAlloc::alloc) | ||
#[inline] | ||
pub fn with_capacity_aligned(capacity: usize, align: usize) -> BytesMut { | ||
// if align isn't power of two it will fail in `std::alloc::Layout::from_size_align` | ||
let lower = align - 1; | ||
// round up to nearest number that aligned with `align`, | ||
// if itself aligned this does nothing | ||
let capacity = (capacity + lower) & !lower; | ||
// should be | ||
assert_eq!(capacity % align, 0); | ||
let layout = std::alloc::Layout::from_size_align(capacity, align).unwrap(); | ||
|
||
let vec = unsafe { | ||
// # Safety | ||
// + capacity and alignment has been checked above | ||
// + null ptr handled below | ||
let ptr = std::alloc::alloc(layout); | ||
if ptr.is_null() { | ||
// handle null ptr here because it might cause a problem at `BytesMut::from_vec` | ||
panic!("Not enough memory"); | ||
} | ||
// # Safety | ||
// + as long as `capacity % align == 0` it prevent `RawVec::drop` to cause `SIGSEGV` | ||
// because `RawVec::drop` will create new Layout during free, | ||
// `RawVec<u8>` will use `Layout::<u8>::array(capacity)` | ||
// to free instead of our alignment | ||
Vec::from_raw_parts(ptr, 0, capacity) | ||
Comment on lines
+193
to
+198
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The documentation for
Since the vector is using alignment 1, passing it a pointer of larger alignment is incorrect. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, I see errors in miri. |
||
}; | ||
// if `BytesMut::from_vec` is deprecated, please use ptr and capacity | ||
// to construct `BytesMut` instead | ||
BytesMut::from_vec(vec) | ||
} | ||
|
||
/// Creates a new `BytesMut` with default capacity. | ||
/// | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should call
alloc::alloc::handle_alloc_error
to handle OOM errors, since panicking may cause unexpected results in low-memory environments.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok thanks.