diff options
author | Gurchetan Singh <gurchetansingh@chromium.org> | 2018-10-31 17:31:46 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-11 00:34:36 +0000 |
commit | bf433ea9f6b5f3717b23700b50f996edd527e17d (patch) | |
tree | 7853dbffb71a0f76e00e60ac9685b09a4d3906db /data_model | |
parent | 65b98f1ccc2ce1d52c12f75a224a259fd399e555 (diff) | |
download | crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.gz crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.bz2 crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.lz crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.xz crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.zst crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.zip |
crosvm: move vec_with_array_field to data_model
Move it to the newly created flexible array file. BUG=chromium:892806 TEST=compiles Change-Id: I6c423a885cec17e376b0da87a4adbd17c71ff6f0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1325510 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org> Tested-by: Gurchetan Singh <gurchetansingh@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'data_model')
-rw-r--r-- | data_model/src/flexible_array.rs | 39 | ||||
-rw-r--r-- | data_model/src/lib.rs | 3 |
2 files changed, 42 insertions, 0 deletions
diff --git a/data_model/src/flexible_array.rs b/data_model/src/flexible_array.rs new file mode 100644 index 0000000..35ac15a --- /dev/null +++ b/data_model/src/flexible_array.rs @@ -0,0 +1,39 @@ +// Copyright 2019 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +//! A wrapper for structures that contain flexible arrays. + +use std::mem::size_of; + +// Returns a `Vec<T>` with a size in bytes at least as large as `size_in_bytes`. +fn vec_with_size_in_bytes<T: Default>(size_in_bytes: usize) -> Vec<T> { + let rounded_size = (size_in_bytes + size_of::<T>() - 1) / size_of::<T>(); + let mut v = Vec::with_capacity(rounded_size); + for _ in 0..rounded_size { + v.push(T::default()) + } + v +} + +/// The kernel API has many structs that resemble the following `Foo` structure: +/// +/// ```ignore +/// #[repr(C)] +/// struct Foo { +/// some_data: u32, +/// entries: __IncompleteArrayField<__u32>, +/// } +/// ``` +/// +/// In order to allocate such a structure, `size_of::<Foo>()` would be too small because it would +/// not include any space for `entries`. To make the allocation large enough while still being +/// aligned for `Foo`, a `Vec<Foo>` is created. Only the first element of `Vec<Foo>` would actually +/// be used as a `Foo`. The remaining memory in the `Vec<Foo>` is for `entries`, which must be +/// contiguous with `Foo`. This function is used to make the `Vec<Foo>` with enough space for +/// `count` entries. +pub fn vec_with_array_field<T: Default, F>(count: usize) -> Vec<T> { + let element_space = count * size_of::<F>(); + let vec_size_bytes = size_of::<T>() + element_space; + vec_with_size_in_bytes(vec_size_bytes) +} diff --git a/data_model/src/lib.rs b/data_model/src/lib.rs index dcca108..3f75377 100644 --- a/data_model/src/lib.rs +++ b/data_model/src/lib.rs @@ -180,3 +180,6 @@ pub use crate::endian::*; pub mod volatile_memory; pub use crate::volatile_memory::*; + +mod flexible_array; +pub use flexible_array::vec_with_array_field; |