microsoft/openvmm

Public

mirrored fromhttps://github.com/microsoft/openvmmAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
044a1588c83070552bc8d547fc011779c82b1892

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

vm/hv1/vtl_array/src/lib.rs

229lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Container data structures indexable by [`Vtl`].
5
6#![no_std]
7#![forbid(unsafe_code)]
8#![warn(missing_docs)]
9
10use bitvec::array::BitArray;
11use core::ops::Deref;
12use core::ops::DerefMut;
13use core::ops::Index;
14use core::ops::IndexMut;
15use hvdef::Vtl;
16use inspect::Inspect;
17
18// TODO: Enforce N <= 3 on the type when stable
19/// An array indexable by [`Vtl`].
20#[derive(Debug, Clone)]
21pub struct VtlArray<T, const N: usize> {
22 data: [T; N],
23}
24
25impl<T, const N: usize> VtlArray<T, N> {
26 /// Creates an array of type T, where each element is `value`.
27 pub const fn new(value: T) -> Self
28 where
29 T: Copy,
30 {
31 assert!(N > 0 && N <= 3);
32 Self { data: [value; N] }
33 }
34
35 /// Creates an array of type T, where each element is
36 /// the returned value from `f` using that element’s index.
37 pub fn from_fn<F>(mut f: F) -> Self
38 where
39 F: FnMut(Vtl) -> T,
40 {
41 assert!(N > 0 && N <= 3);
42 Self {
43 data: core::array::from_fn(|i| f(Vtl::try_from(i as u8).unwrap())),
44 }
45 }
46
47 /// Maps over the vtl array using the raw underlying array.
48 pub fn map<U, F>(self, f: F) -> VtlArray<U, N>
49 where
50 F: FnMut(T) -> U,
51 {
52 VtlArray {
53 data: self.data.map(f),
54 }
55 }
56
57 /// Borrows each element and returns an array of references with the same
58 /// size as self.
59 pub fn each_ref(&self) -> VtlArray<&T, N> {
60 VtlArray {
61 data: self.data.each_ref(),
62 }
63 }
64
65 /// Borrows each element mutably and returns an array of mutable references
66 /// with the same size as self.
67 pub fn each_mut(&mut self) -> VtlArray<&mut T, N> {
68 VtlArray {
69 data: self.data.each_mut(),
70 }
71 }
72
73 /// Returns the raw underlying array.
74 pub fn into_inner(self) -> [T; N] {
75 self.data
76 }
77}
78
79impl<T> From<[T; 1]> for VtlArray<T, 1> {
80 fn from(a: [T; 1]) -> Self {
81 Self { data: a }
82 }
83}
84
85impl<T> From<[T; 2]> for VtlArray<T, 2> {
86 fn from(a: [T; 2]) -> Self {
87 Self { data: a }
88 }
89}
90
91impl<T> From<[T; 3]> for VtlArray<T, 3> {
92 fn from(a: [T; 3]) -> Self {
93 Self { data: a }
94 }
95}
96
97impl<T, const N: usize> Inspect for VtlArray<T, N>
98where
99 T: Inspect,
100{
101 fn inspect(&self, req: inspect::Request<'_>) {
102 inspect::iter_by_index(&self.data).inspect(req)
103 }
104}
105
106impl<T, V: Into<Vtl>, const N: usize> Index<V> for VtlArray<T, N> {
107 type Output = T;
108
109 fn index(&self, index: V) -> &Self::Output {
110 &self.data[index.into() as usize]
111 }
112}
113
114impl<T, V: Into<Vtl>, const N: usize> IndexMut<V> for VtlArray<T, N> {
115 fn index_mut(&mut self, index: V) -> &mut Self::Output {
116 &mut self.data[index.into() as usize]
117 }
118}
119
120impl<T, const N: usize> Deref for VtlArray<T, N> {
121 type Target = [T; N];
122
123 fn deref(&self) -> &Self::Target {
124 &self.data
125 }
126}
127
128impl<T, const N: usize> DerefMut for VtlArray<T, N> {
129 fn deref_mut(&mut self) -> &mut Self::Target {
130 &mut self.data
131 }
132}
133
134/// A set of [`Vtl`]s.
135#[derive(Copy, Clone)]
136pub struct VtlSet {
137 bits: BitArray<u16>,
138}
139
140impl VtlSet {
141 /// Creates a new empty set.
142 pub fn new() -> Self {
143 Self {
144 bits: BitArray::new(0),
145 }
146 }
147
148 /// Adds a [`Vtl`] to the set.
149 pub fn set(&mut self, vtl: Vtl) {
150 self.bits.set(vtl as usize, true);
151 }
152
153 /// Removes a [`Vtl`] from the set.
154 pub fn clear(&mut self, vtl: Vtl) {
155 self.bits.set(vtl as usize, false);
156 }
157
158 /// Returns true if any [`Vtl`] in the set is higher than `vtl`.
159 pub fn is_higher_vtl_set_than(&self, vtl: Vtl) -> bool {
160 self.highest_set() > Some(vtl)
161 }
162
163 /// Returns the highest set [`Vtl`] in the set, if any.
164 pub fn highest_set(&self) -> Option<Vtl> {
165 Some(Vtl::try_from(self.bits.last_one()? as u8).unwrap())
166 }
167
168 /// Returns true if the given [`Vtl`] is set.
169 pub fn is_set<V: Into<Vtl>>(&self, vtl: V) -> bool {
170 self.bits[vtl.into() as usize]
171 }
172
173 /// Returns true if the given [`Vtl`] is not set.
174 pub fn is_clear<V: Into<Vtl>>(&self, vtl: V) -> bool {
175 !self.is_set(vtl)
176 }
177
178 /// Returns an iterator over the set [`Vtl`]s, in order from highest to lowest.
179 pub fn iter_highest_first(&self) -> impl Iterator<Item = Vtl> + '_ {
180 self.bits
181 .iter_ones()
182 .rev()
183 .map(|i| Vtl::try_from(i as u8).unwrap())
184 }
185}
186
187impl Inspect for VtlSet {
188 fn inspect(&self, req: inspect::Request<'_>) {
189 inspect::iter_by_index(self.bits.iter().map(|v| *v)).inspect(req)
190 }
191}
192
193impl From<u16> for VtlSet {
194 fn from(bits: u16) -> Self {
195 VtlSet {
196 bits: BitArray::new(bits),
197 }
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use super::VtlSet;
204 use hvdef::Vtl;
205
206 #[test]
207 fn test_vtlset() {
208 let mut set = VtlSet::new();
209 assert_eq!(set.highest_set(), None);
210 set.set(Vtl::Vtl0);
211 assert_eq!(set.highest_set(), Some(Vtl::Vtl0));
212 set.set(Vtl::Vtl2);
213 assert_eq!(set.highest_set(), Some(Vtl::Vtl2));
214
215 {
216 let mut iter = set.iter_highest_first();
217 assert_eq!(iter.next(), Some(Vtl::Vtl2));
218 assert_eq!(iter.next(), Some(Vtl::Vtl0));
219 assert_eq!(iter.next(), None);
220 }
221
222 assert!(!set.is_higher_vtl_set_than(Vtl::Vtl2));
223 assert!(set.is_higher_vtl_set_than(Vtl::Vtl1));
224 assert!(set.is_higher_vtl_set_than(Vtl::Vtl0));
225
226 set.clear(Vtl::Vtl2);
227 assert!(!set.is_higher_vtl_set_than(Vtl::Vtl0));
228 }
229}
230