1#![doc = "Energy model netlink interface to notify its changes.\n"]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &str = "dev-energymodel";
17pub const PROTONAME_CSTR: &CStr = c"dev-energymodel";
18#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
19#[derive(Debug, Clone, Copy)]
20pub enum PerfStateFlags {
21 #[doc = "The performance state is inefficient. There is in this perf-domain,\nanother performance state with a higher frequency but a lower or equal\npower cost.\n"]
22 PerfStateInefficient = 1 << 0,
23}
24impl PerfStateFlags {
25 pub fn from_value(value: u64) -> Option<Self> {
26 Some(match value {
27 n if n == 1 << 0 => Self::PerfStateInefficient,
28 _ => return None,
29 })
30 }
31}
32#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
33#[derive(Debug, Clone, Copy)]
34pub enum PerfDomainFlags {
35 #[doc = "The power values are in micro-Watts or some other scale.\n"]
36 PerfDomainMicrowatts = 1 << 0,
37 #[doc = "Skip inefficient states when estimating energy consumption.\n"]
38 PerfDomainSkipInefficiencies = 1 << 1,
39 #[doc = "The power values are artificial and might be created by platform missing\nreal power information.\n"]
40 PerfDomainArtificial = 1 << 2,
41}
42impl PerfDomainFlags {
43 pub fn from_value(value: u64) -> Option<Self> {
44 Some(match value {
45 n if n == 1 << 0 => Self::PerfDomainMicrowatts,
46 n if n == 1 << 1 => Self::PerfDomainSkipInefficiencies,
47 n if n == 1 << 2 => Self::PerfDomainArtificial,
48 _ => return None,
49 })
50 }
51}
52#[derive(Clone)]
53pub enum PerfDomain<'a> {
54 Pad(&'a [u8]),
55 #[doc = "A unique ID number for each performance domain.\n"]
56 PerfDomainId(u32),
57 #[doc = "Bitmask of performance domain flags.\n\nAssociated type: [`PerfDomainFlags`] (enum)"]
58 Flags(u64),
59 #[doc = "CPUs that belong to this performance domain.\n\nAttribute may repeat multiple times (treat it as array)"]
60 Cpus(u64),
61}
62impl<'a> IterablePerfDomain<'a> {
63 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
64 let mut iter = self.clone();
65 iter.pos = 0;
66 for attr in iter {
67 if let Ok(PerfDomain::Pad(val)) = attr {
68 return Ok(val);
69 }
70 }
71 Err(ErrorContext::new_missing(
72 "PerfDomain",
73 "Pad",
74 self.orig_loc,
75 self.buf.as_ptr() as usize,
76 ))
77 }
78 #[doc = "A unique ID number for each performance domain.\n"]
79 pub fn get_perf_domain_id(&self) -> Result<u32, ErrorContext> {
80 let mut iter = self.clone();
81 iter.pos = 0;
82 for attr in iter {
83 if let Ok(PerfDomain::PerfDomainId(val)) = attr {
84 return Ok(val);
85 }
86 }
87 Err(ErrorContext::new_missing(
88 "PerfDomain",
89 "PerfDomainId",
90 self.orig_loc,
91 self.buf.as_ptr() as usize,
92 ))
93 }
94 #[doc = "Bitmask of performance domain flags.\n\nAssociated type: [`PerfDomainFlags`] (enum)"]
95 pub fn get_flags(&self) -> Result<u64, ErrorContext> {
96 let mut iter = self.clone();
97 iter.pos = 0;
98 for attr in iter {
99 if let Ok(PerfDomain::Flags(val)) = attr {
100 return Ok(val);
101 }
102 }
103 Err(ErrorContext::new_missing(
104 "PerfDomain",
105 "Flags",
106 self.orig_loc,
107 self.buf.as_ptr() as usize,
108 ))
109 }
110 #[doc = "CPUs that belong to this performance domain.\n\nAttribute may repeat multiple times (treat it as array)"]
111 pub fn get_cpus(&self) -> MultiAttrIterable<Self, PerfDomain<'a>, u64> {
112 MultiAttrIterable::new(self.clone(), |variant| {
113 if let PerfDomain::Cpus(val) = variant {
114 Some(val)
115 } else {
116 None
117 }
118 })
119 }
120}
121impl PerfDomain<'_> {
122 pub fn new<'a>(buf: &'a [u8]) -> IterablePerfDomain<'a> {
123 IterablePerfDomain::with_loc(buf, buf.as_ptr() as usize)
124 }
125 fn attr_from_type(r#type: u16) -> Option<&'static str> {
126 let res = match r#type {
127 1u16 => "Pad",
128 2u16 => "PerfDomainId",
129 3u16 => "Flags",
130 4u16 => "Cpus",
131 _ => return None,
132 };
133 Some(res)
134 }
135}
136#[derive(Clone, Copy, Default)]
137pub struct IterablePerfDomain<'a> {
138 buf: &'a [u8],
139 pos: usize,
140 orig_loc: usize,
141}
142impl<'a> IterablePerfDomain<'a> {
143 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
144 Self {
145 buf,
146 pos: 0,
147 orig_loc,
148 }
149 }
150 pub fn get_buf(&self) -> &'a [u8] {
151 self.buf
152 }
153}
154impl<'a> Iterator for IterablePerfDomain<'a> {
155 type Item = Result<PerfDomain<'a>, ErrorContext>;
156 fn next(&mut self) -> Option<Self::Item> {
157 let mut pos;
158 let mut r#type;
159 loop {
160 pos = self.pos;
161 r#type = None;
162 if self.buf.len() == self.pos {
163 return None;
164 }
165 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
166 self.pos = self.buf.len();
167 break;
168 };
169 r#type = Some(header.r#type);
170 let res = match header.r#type {
171 1u16 => PerfDomain::Pad({
172 let res = Some(next);
173 let Some(val) = res else { break };
174 val
175 }),
176 2u16 => PerfDomain::PerfDomainId({
177 let res = parse_u32(next);
178 let Some(val) = res else { break };
179 val
180 }),
181 3u16 => PerfDomain::Flags({
182 let res = parse_u64(next);
183 let Some(val) = res else { break };
184 val
185 }),
186 4u16 => PerfDomain::Cpus({
187 let res = parse_u64(next);
188 let Some(val) = res else { break };
189 val
190 }),
191 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
192 n => continue,
193 };
194 return Some(Ok(res));
195 }
196 Some(Err(ErrorContext::new(
197 "PerfDomain",
198 r#type.and_then(|t| PerfDomain::attr_from_type(t)),
199 self.orig_loc,
200 self.buf.as_ptr().wrapping_add(pos) as usize,
201 )))
202 }
203}
204impl<'a> std::fmt::Debug for IterablePerfDomain<'_> {
205 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
206 let mut fmt = f.debug_struct("PerfDomain");
207 for attr in self.clone() {
208 let attr = match attr {
209 Ok(a) => a,
210 Err(err) => {
211 fmt.finish()?;
212 f.write_str("Err(")?;
213 err.fmt(f)?;
214 return f.write_str(")");
215 }
216 };
217 match attr {
218 PerfDomain::Pad(val) => fmt.field("Pad", &val),
219 PerfDomain::PerfDomainId(val) => fmt.field("PerfDomainId", &val),
220 PerfDomain::Flags(val) => fmt.field(
221 "Flags",
222 &FormatFlags(val.into(), PerfDomainFlags::from_value),
223 ),
224 PerfDomain::Cpus(val) => fmt.field("Cpus", &val),
225 };
226 }
227 fmt.finish()
228 }
229}
230impl IterablePerfDomain<'_> {
231 pub fn lookup_attr(
232 &self,
233 offset: usize,
234 missing_type: Option<u16>,
235 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
236 let mut stack = Vec::new();
237 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
238 if missing_type.is_some() && cur == offset {
239 stack.push(("PerfDomain", offset));
240 return (
241 stack,
242 missing_type.and_then(|t| PerfDomain::attr_from_type(t)),
243 );
244 }
245 if cur > offset || cur + self.buf.len() < offset {
246 return (stack, None);
247 }
248 let mut attrs = self.clone();
249 let mut last_off = cur + attrs.pos;
250 while let Some(attr) = attrs.next() {
251 let Ok(attr) = attr else { break };
252 match attr {
253 PerfDomain::Pad(val) => {
254 if last_off == offset {
255 stack.push(("Pad", last_off));
256 break;
257 }
258 }
259 PerfDomain::PerfDomainId(val) => {
260 if last_off == offset {
261 stack.push(("PerfDomainId", last_off));
262 break;
263 }
264 }
265 PerfDomain::Flags(val) => {
266 if last_off == offset {
267 stack.push(("Flags", last_off));
268 break;
269 }
270 }
271 PerfDomain::Cpus(val) => {
272 if last_off == offset {
273 stack.push(("Cpus", last_off));
274 break;
275 }
276 }
277 _ => {}
278 };
279 last_off = cur + attrs.pos;
280 }
281 if !stack.is_empty() {
282 stack.push(("PerfDomain", cur));
283 }
284 (stack, None)
285 }
286}
287#[derive(Clone)]
288pub enum PerfTable<'a> {
289 #[doc = "A unique ID number for each performance domain.\n"]
290 PerfDomainId(u32),
291 #[doc = "Attribute may repeat multiple times (treat it as array)"]
292 PerfState(IterablePerfState<'a>),
293}
294impl<'a> IterablePerfTable<'a> {
295 #[doc = "A unique ID number for each performance domain.\n"]
296 pub fn get_perf_domain_id(&self) -> Result<u32, ErrorContext> {
297 let mut iter = self.clone();
298 iter.pos = 0;
299 for attr in iter {
300 if let Ok(PerfTable::PerfDomainId(val)) = attr {
301 return Ok(val);
302 }
303 }
304 Err(ErrorContext::new_missing(
305 "PerfTable",
306 "PerfDomainId",
307 self.orig_loc,
308 self.buf.as_ptr() as usize,
309 ))
310 }
311 #[doc = "Attribute may repeat multiple times (treat it as array)"]
312 pub fn get_perf_state(&self) -> MultiAttrIterable<Self, PerfTable<'a>, IterablePerfState<'a>> {
313 MultiAttrIterable::new(self.clone(), |variant| {
314 if let PerfTable::PerfState(val) = variant {
315 Some(val)
316 } else {
317 None
318 }
319 })
320 }
321}
322impl PerfTable<'_> {
323 pub fn new<'a>(buf: &'a [u8]) -> IterablePerfTable<'a> {
324 IterablePerfTable::with_loc(buf, buf.as_ptr() as usize)
325 }
326 fn attr_from_type(r#type: u16) -> Option<&'static str> {
327 let res = match r#type {
328 1u16 => "PerfDomainId",
329 2u16 => "PerfState",
330 _ => return None,
331 };
332 Some(res)
333 }
334}
335#[derive(Clone, Copy, Default)]
336pub struct IterablePerfTable<'a> {
337 buf: &'a [u8],
338 pos: usize,
339 orig_loc: usize,
340}
341impl<'a> IterablePerfTable<'a> {
342 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
343 Self {
344 buf,
345 pos: 0,
346 orig_loc,
347 }
348 }
349 pub fn get_buf(&self) -> &'a [u8] {
350 self.buf
351 }
352}
353impl<'a> Iterator for IterablePerfTable<'a> {
354 type Item = Result<PerfTable<'a>, ErrorContext>;
355 fn next(&mut self) -> Option<Self::Item> {
356 let mut pos;
357 let mut r#type;
358 loop {
359 pos = self.pos;
360 r#type = None;
361 if self.buf.len() == self.pos {
362 return None;
363 }
364 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
365 self.pos = self.buf.len();
366 break;
367 };
368 r#type = Some(header.r#type);
369 let res = match header.r#type {
370 1u16 => PerfTable::PerfDomainId({
371 let res = parse_u32(next);
372 let Some(val) = res else { break };
373 val
374 }),
375 2u16 => PerfTable::PerfState({
376 let res = Some(IterablePerfState::with_loc(next, self.orig_loc));
377 let Some(val) = res else { break };
378 val
379 }),
380 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
381 n => continue,
382 };
383 return Some(Ok(res));
384 }
385 Some(Err(ErrorContext::new(
386 "PerfTable",
387 r#type.and_then(|t| PerfTable::attr_from_type(t)),
388 self.orig_loc,
389 self.buf.as_ptr().wrapping_add(pos) as usize,
390 )))
391 }
392}
393impl<'a> std::fmt::Debug for IterablePerfTable<'_> {
394 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
395 let mut fmt = f.debug_struct("PerfTable");
396 for attr in self.clone() {
397 let attr = match attr {
398 Ok(a) => a,
399 Err(err) => {
400 fmt.finish()?;
401 f.write_str("Err(")?;
402 err.fmt(f)?;
403 return f.write_str(")");
404 }
405 };
406 match attr {
407 PerfTable::PerfDomainId(val) => fmt.field("PerfDomainId", &val),
408 PerfTable::PerfState(val) => fmt.field("PerfState", &val),
409 };
410 }
411 fmt.finish()
412 }
413}
414impl IterablePerfTable<'_> {
415 pub fn lookup_attr(
416 &self,
417 offset: usize,
418 missing_type: Option<u16>,
419 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
420 let mut stack = Vec::new();
421 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
422 if missing_type.is_some() && cur == offset {
423 stack.push(("PerfTable", offset));
424 return (
425 stack,
426 missing_type.and_then(|t| PerfTable::attr_from_type(t)),
427 );
428 }
429 if cur > offset || cur + self.buf.len() < offset {
430 return (stack, None);
431 }
432 let mut attrs = self.clone();
433 let mut last_off = cur + attrs.pos;
434 let mut missing = None;
435 while let Some(attr) = attrs.next() {
436 let Ok(attr) = attr else { break };
437 match attr {
438 PerfTable::PerfDomainId(val) => {
439 if last_off == offset {
440 stack.push(("PerfDomainId", last_off));
441 break;
442 }
443 }
444 PerfTable::PerfState(val) => {
445 (stack, missing) = val.lookup_attr(offset, missing_type);
446 if !stack.is_empty() {
447 break;
448 }
449 }
450 _ => {}
451 };
452 last_off = cur + attrs.pos;
453 }
454 if !stack.is_empty() {
455 stack.push(("PerfTable", cur));
456 }
457 (stack, missing)
458 }
459}
460#[derive(Clone)]
461pub enum PerfState<'a> {
462 Pad(&'a [u8]),
463 #[doc = "CPU performance (capacity) at a given frequency.\n"]
464 Performance(u64),
465 #[doc = "The frequency in KHz, for consistency with CPUFreq.\n"]
466 Frequency(u64),
467 #[doc = "The power consumed at this level (by 1 CPU or by a registered device).\nIt can be a total power: static and dynamic.\n"]
468 Power(u64),
469 #[doc = "The cost coefficient associated with this level, used during energy\ncalculation. Equal to: power \\* max_frequency / frequency.\n"]
470 Cost(u64),
471 #[doc = "Bitmask of performance state flags.\n\nAssociated type: [`PerfStateFlags`] (enum)"]
472 Flags(u64),
473}
474impl<'a> IterablePerfState<'a> {
475 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
476 let mut iter = self.clone();
477 iter.pos = 0;
478 for attr in iter {
479 if let Ok(PerfState::Pad(val)) = attr {
480 return Ok(val);
481 }
482 }
483 Err(ErrorContext::new_missing(
484 "PerfState",
485 "Pad",
486 self.orig_loc,
487 self.buf.as_ptr() as usize,
488 ))
489 }
490 #[doc = "CPU performance (capacity) at a given frequency.\n"]
491 pub fn get_performance(&self) -> Result<u64, ErrorContext> {
492 let mut iter = self.clone();
493 iter.pos = 0;
494 for attr in iter {
495 if let Ok(PerfState::Performance(val)) = attr {
496 return Ok(val);
497 }
498 }
499 Err(ErrorContext::new_missing(
500 "PerfState",
501 "Performance",
502 self.orig_loc,
503 self.buf.as_ptr() as usize,
504 ))
505 }
506 #[doc = "The frequency in KHz, for consistency with CPUFreq.\n"]
507 pub fn get_frequency(&self) -> Result<u64, ErrorContext> {
508 let mut iter = self.clone();
509 iter.pos = 0;
510 for attr in iter {
511 if let Ok(PerfState::Frequency(val)) = attr {
512 return Ok(val);
513 }
514 }
515 Err(ErrorContext::new_missing(
516 "PerfState",
517 "Frequency",
518 self.orig_loc,
519 self.buf.as_ptr() as usize,
520 ))
521 }
522 #[doc = "The power consumed at this level (by 1 CPU or by a registered device).\nIt can be a total power: static and dynamic.\n"]
523 pub fn get_power(&self) -> Result<u64, ErrorContext> {
524 let mut iter = self.clone();
525 iter.pos = 0;
526 for attr in iter {
527 if let Ok(PerfState::Power(val)) = attr {
528 return Ok(val);
529 }
530 }
531 Err(ErrorContext::new_missing(
532 "PerfState",
533 "Power",
534 self.orig_loc,
535 self.buf.as_ptr() as usize,
536 ))
537 }
538 #[doc = "The cost coefficient associated with this level, used during energy\ncalculation. Equal to: power \\* max_frequency / frequency.\n"]
539 pub fn get_cost(&self) -> Result<u64, ErrorContext> {
540 let mut iter = self.clone();
541 iter.pos = 0;
542 for attr in iter {
543 if let Ok(PerfState::Cost(val)) = attr {
544 return Ok(val);
545 }
546 }
547 Err(ErrorContext::new_missing(
548 "PerfState",
549 "Cost",
550 self.orig_loc,
551 self.buf.as_ptr() as usize,
552 ))
553 }
554 #[doc = "Bitmask of performance state flags.\n\nAssociated type: [`PerfStateFlags`] (enum)"]
555 pub fn get_flags(&self) -> Result<u64, ErrorContext> {
556 let mut iter = self.clone();
557 iter.pos = 0;
558 for attr in iter {
559 if let Ok(PerfState::Flags(val)) = attr {
560 return Ok(val);
561 }
562 }
563 Err(ErrorContext::new_missing(
564 "PerfState",
565 "Flags",
566 self.orig_loc,
567 self.buf.as_ptr() as usize,
568 ))
569 }
570}
571impl PerfState<'_> {
572 pub fn new<'a>(buf: &'a [u8]) -> IterablePerfState<'a> {
573 IterablePerfState::with_loc(buf, buf.as_ptr() as usize)
574 }
575 fn attr_from_type(r#type: u16) -> Option<&'static str> {
576 let res = match r#type {
577 1u16 => "Pad",
578 2u16 => "Performance",
579 3u16 => "Frequency",
580 4u16 => "Power",
581 5u16 => "Cost",
582 6u16 => "Flags",
583 _ => return None,
584 };
585 Some(res)
586 }
587}
588#[derive(Clone, Copy, Default)]
589pub struct IterablePerfState<'a> {
590 buf: &'a [u8],
591 pos: usize,
592 orig_loc: usize,
593}
594impl<'a> IterablePerfState<'a> {
595 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
596 Self {
597 buf,
598 pos: 0,
599 orig_loc,
600 }
601 }
602 pub fn get_buf(&self) -> &'a [u8] {
603 self.buf
604 }
605}
606impl<'a> Iterator for IterablePerfState<'a> {
607 type Item = Result<PerfState<'a>, ErrorContext>;
608 fn next(&mut self) -> Option<Self::Item> {
609 let mut pos;
610 let mut r#type;
611 loop {
612 pos = self.pos;
613 r#type = None;
614 if self.buf.len() == self.pos {
615 return None;
616 }
617 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
618 self.pos = self.buf.len();
619 break;
620 };
621 r#type = Some(header.r#type);
622 let res = match header.r#type {
623 1u16 => PerfState::Pad({
624 let res = Some(next);
625 let Some(val) = res else { break };
626 val
627 }),
628 2u16 => PerfState::Performance({
629 let res = parse_u64(next);
630 let Some(val) = res else { break };
631 val
632 }),
633 3u16 => PerfState::Frequency({
634 let res = parse_u64(next);
635 let Some(val) = res else { break };
636 val
637 }),
638 4u16 => PerfState::Power({
639 let res = parse_u64(next);
640 let Some(val) = res else { break };
641 val
642 }),
643 5u16 => PerfState::Cost({
644 let res = parse_u64(next);
645 let Some(val) = res else { break };
646 val
647 }),
648 6u16 => PerfState::Flags({
649 let res = parse_u64(next);
650 let Some(val) = res else { break };
651 val
652 }),
653 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
654 n => continue,
655 };
656 return Some(Ok(res));
657 }
658 Some(Err(ErrorContext::new(
659 "PerfState",
660 r#type.and_then(|t| PerfState::attr_from_type(t)),
661 self.orig_loc,
662 self.buf.as_ptr().wrapping_add(pos) as usize,
663 )))
664 }
665}
666impl<'a> std::fmt::Debug for IterablePerfState<'_> {
667 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
668 let mut fmt = f.debug_struct("PerfState");
669 for attr in self.clone() {
670 let attr = match attr {
671 Ok(a) => a,
672 Err(err) => {
673 fmt.finish()?;
674 f.write_str("Err(")?;
675 err.fmt(f)?;
676 return f.write_str(")");
677 }
678 };
679 match attr {
680 PerfState::Pad(val) => fmt.field("Pad", &val),
681 PerfState::Performance(val) => fmt.field("Performance", &val),
682 PerfState::Frequency(val) => fmt.field("Frequency", &val),
683 PerfState::Power(val) => fmt.field("Power", &val),
684 PerfState::Cost(val) => fmt.field("Cost", &val),
685 PerfState::Flags(val) => fmt.field(
686 "Flags",
687 &FormatFlags(val.into(), PerfStateFlags::from_value),
688 ),
689 };
690 }
691 fmt.finish()
692 }
693}
694impl IterablePerfState<'_> {
695 pub fn lookup_attr(
696 &self,
697 offset: usize,
698 missing_type: Option<u16>,
699 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
700 let mut stack = Vec::new();
701 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
702 if missing_type.is_some() && cur == offset {
703 stack.push(("PerfState", offset));
704 return (
705 stack,
706 missing_type.and_then(|t| PerfState::attr_from_type(t)),
707 );
708 }
709 if cur > offset || cur + self.buf.len() < offset {
710 return (stack, None);
711 }
712 let mut attrs = self.clone();
713 let mut last_off = cur + attrs.pos;
714 while let Some(attr) = attrs.next() {
715 let Ok(attr) = attr else { break };
716 match attr {
717 PerfState::Pad(val) => {
718 if last_off == offset {
719 stack.push(("Pad", last_off));
720 break;
721 }
722 }
723 PerfState::Performance(val) => {
724 if last_off == offset {
725 stack.push(("Performance", last_off));
726 break;
727 }
728 }
729 PerfState::Frequency(val) => {
730 if last_off == offset {
731 stack.push(("Frequency", last_off));
732 break;
733 }
734 }
735 PerfState::Power(val) => {
736 if last_off == offset {
737 stack.push(("Power", last_off));
738 break;
739 }
740 }
741 PerfState::Cost(val) => {
742 if last_off == offset {
743 stack.push(("Cost", last_off));
744 break;
745 }
746 }
747 PerfState::Flags(val) => {
748 if last_off == offset {
749 stack.push(("Flags", last_off));
750 break;
751 }
752 }
753 _ => {}
754 };
755 last_off = cur + attrs.pos;
756 }
757 if !stack.is_empty() {
758 stack.push(("PerfState", cur));
759 }
760 (stack, None)
761 }
762}
763pub struct PushPerfDomain<Prev: Pusher> {
764 pub(crate) prev: Option<Prev>,
765 pub(crate) header_offset: Option<usize>,
766}
767impl<Prev: Pusher> Pusher for PushPerfDomain<Prev> {
768 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
769 self.prev.as_mut().unwrap().as_vec_mut()
770 }
771 fn as_vec(&self) -> &Vec<u8> {
772 self.prev.as_ref().unwrap().as_vec()
773 }
774}
775impl<Prev: Pusher> PushPerfDomain<Prev> {
776 pub fn new(prev: Prev) -> Self {
777 Self {
778 prev: Some(prev),
779 header_offset: None,
780 }
781 }
782 pub fn end_nested(mut self) -> Prev {
783 let mut prev = self.prev.take().unwrap();
784 if let Some(header_offset) = &self.header_offset {
785 finalize_nested_header(prev.as_vec_mut(), *header_offset);
786 }
787 prev
788 }
789 pub fn push_pad(mut self, value: &[u8]) -> Self {
790 push_header(self.as_vec_mut(), 1u16, value.len() as u16);
791 self.as_vec_mut().extend(value);
792 self
793 }
794 #[doc = "A unique ID number for each performance domain.\n"]
795 pub fn push_perf_domain_id(mut self, value: u32) -> Self {
796 push_header(self.as_vec_mut(), 2u16, 4 as u16);
797 self.as_vec_mut().extend(value.to_ne_bytes());
798 self
799 }
800 #[doc = "Bitmask of performance domain flags.\n\nAssociated type: [`PerfDomainFlags`] (enum)"]
801 pub fn push_flags(mut self, value: u64) -> Self {
802 push_header(self.as_vec_mut(), 3u16, 8 as u16);
803 self.as_vec_mut().extend(value.to_ne_bytes());
804 self
805 }
806 #[doc = "CPUs that belong to this performance domain.\n\nAttribute may repeat multiple times (treat it as array)"]
807 pub fn push_cpus(mut self, value: u64) -> Self {
808 push_header(self.as_vec_mut(), 4u16, 8 as u16);
809 self.as_vec_mut().extend(value.to_ne_bytes());
810 self
811 }
812}
813impl<Prev: Pusher> Drop for PushPerfDomain<Prev> {
814 fn drop(&mut self) {
815 if let Some(prev) = &mut self.prev {
816 if let Some(header_offset) = &self.header_offset {
817 finalize_nested_header(prev.as_vec_mut(), *header_offset);
818 }
819 }
820 }
821}
822pub struct PushPerfTable<Prev: Pusher> {
823 pub(crate) prev: Option<Prev>,
824 pub(crate) header_offset: Option<usize>,
825}
826impl<Prev: Pusher> Pusher for PushPerfTable<Prev> {
827 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
828 self.prev.as_mut().unwrap().as_vec_mut()
829 }
830 fn as_vec(&self) -> &Vec<u8> {
831 self.prev.as_ref().unwrap().as_vec()
832 }
833}
834impl<Prev: Pusher> PushPerfTable<Prev> {
835 pub fn new(prev: Prev) -> Self {
836 Self {
837 prev: Some(prev),
838 header_offset: None,
839 }
840 }
841 pub fn end_nested(mut self) -> Prev {
842 let mut prev = self.prev.take().unwrap();
843 if let Some(header_offset) = &self.header_offset {
844 finalize_nested_header(prev.as_vec_mut(), *header_offset);
845 }
846 prev
847 }
848 #[doc = "A unique ID number for each performance domain.\n"]
849 pub fn push_perf_domain_id(mut self, value: u32) -> Self {
850 push_header(self.as_vec_mut(), 1u16, 4 as u16);
851 self.as_vec_mut().extend(value.to_ne_bytes());
852 self
853 }
854 #[doc = "Attribute may repeat multiple times (treat it as array)"]
855 pub fn nested_perf_state(mut self) -> PushPerfState<Self> {
856 let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
857 PushPerfState {
858 prev: Some(self),
859 header_offset: Some(header_offset),
860 }
861 }
862}
863impl<Prev: Pusher> Drop for PushPerfTable<Prev> {
864 fn drop(&mut self) {
865 if let Some(prev) = &mut self.prev {
866 if let Some(header_offset) = &self.header_offset {
867 finalize_nested_header(prev.as_vec_mut(), *header_offset);
868 }
869 }
870 }
871}
872pub struct PushPerfState<Prev: Pusher> {
873 pub(crate) prev: Option<Prev>,
874 pub(crate) header_offset: Option<usize>,
875}
876impl<Prev: Pusher> Pusher for PushPerfState<Prev> {
877 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
878 self.prev.as_mut().unwrap().as_vec_mut()
879 }
880 fn as_vec(&self) -> &Vec<u8> {
881 self.prev.as_ref().unwrap().as_vec()
882 }
883}
884impl<Prev: Pusher> PushPerfState<Prev> {
885 pub fn new(prev: Prev) -> Self {
886 Self {
887 prev: Some(prev),
888 header_offset: None,
889 }
890 }
891 pub fn end_nested(mut self) -> Prev {
892 let mut prev = self.prev.take().unwrap();
893 if let Some(header_offset) = &self.header_offset {
894 finalize_nested_header(prev.as_vec_mut(), *header_offset);
895 }
896 prev
897 }
898 pub fn push_pad(mut self, value: &[u8]) -> Self {
899 push_header(self.as_vec_mut(), 1u16, value.len() as u16);
900 self.as_vec_mut().extend(value);
901 self
902 }
903 #[doc = "CPU performance (capacity) at a given frequency.\n"]
904 pub fn push_performance(mut self, value: u64) -> Self {
905 push_header(self.as_vec_mut(), 2u16, 8 as u16);
906 self.as_vec_mut().extend(value.to_ne_bytes());
907 self
908 }
909 #[doc = "The frequency in KHz, for consistency with CPUFreq.\n"]
910 pub fn push_frequency(mut self, value: u64) -> Self {
911 push_header(self.as_vec_mut(), 3u16, 8 as u16);
912 self.as_vec_mut().extend(value.to_ne_bytes());
913 self
914 }
915 #[doc = "The power consumed at this level (by 1 CPU or by a registered device).\nIt can be a total power: static and dynamic.\n"]
916 pub fn push_power(mut self, value: u64) -> Self {
917 push_header(self.as_vec_mut(), 4u16, 8 as u16);
918 self.as_vec_mut().extend(value.to_ne_bytes());
919 self
920 }
921 #[doc = "The cost coefficient associated with this level, used during energy\ncalculation. Equal to: power \\* max_frequency / frequency.\n"]
922 pub fn push_cost(mut self, value: u64) -> Self {
923 push_header(self.as_vec_mut(), 5u16, 8 as u16);
924 self.as_vec_mut().extend(value.to_ne_bytes());
925 self
926 }
927 #[doc = "Bitmask of performance state flags.\n\nAssociated type: [`PerfStateFlags`] (enum)"]
928 pub fn push_flags(mut self, value: u64) -> Self {
929 push_header(self.as_vec_mut(), 6u16, 8 as u16);
930 self.as_vec_mut().extend(value.to_ne_bytes());
931 self
932 }
933}
934impl<Prev: Pusher> Drop for PushPerfState<Prev> {
935 fn drop(&mut self) {
936 if let Some(prev) = &mut self.prev {
937 if let Some(header_offset) = &self.header_offset {
938 finalize_nested_header(prev.as_vec_mut(), *header_offset);
939 }
940 }
941 }
942}
943#[doc = "Notify attributes:\n- [`.get_perf_domain_id()`](IterablePerfTable::get_perf_domain_id)\n- [`.get_perf_state()`](IterablePerfTable::get_perf_state)\n"]
944#[derive(Debug)]
945pub struct OpPerfDomainCreatedNotif;
946impl OpPerfDomainCreatedNotif {
947 pub const CMD: u8 = 3u8;
948 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterablePerfTable<'a> {
949 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
950 IterablePerfTable::with_loc(attrs, buf.as_ptr() as usize)
951 }
952}
953#[doc = "Notify attributes:\n- [`.get_perf_domain_id()`](IterablePerfTable::get_perf_domain_id)\n- [`.get_perf_state()`](IterablePerfTable::get_perf_state)\n"]
954#[derive(Debug)]
955pub struct OpPerfDomainUpdatedNotif;
956impl OpPerfDomainUpdatedNotif {
957 pub const CMD: u8 = 4u8;
958 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterablePerfTable<'a> {
959 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
960 IterablePerfTable::with_loc(attrs, buf.as_ptr() as usize)
961 }
962}
963#[doc = "Notify attributes:\n- [`.get_perf_domain_id()`](IterablePerfTable::get_perf_domain_id)\n"]
964#[derive(Debug)]
965pub struct OpPerfDomainDeletedNotif;
966impl OpPerfDomainDeletedNotif {
967 pub const CMD: u8 = 5u8;
968 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterablePerfTable<'a> {
969 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
970 IterablePerfTable::with_loc(attrs, buf.as_ptr() as usize)
971 }
972}
973pub struct NotifGroup;
974impl NotifGroup {
975 #[doc = "Notifications:\n- [`OpPerfDomainCreatedNotif`]\n- [`OpPerfDomainUpdatedNotif`]\n- [`OpPerfDomainDeletedNotif`]\n"]
976 pub const EVENT: &str = "event";
977 #[doc = "Notifications:\n- [`OpPerfDomainCreatedNotif`]\n- [`OpPerfDomainUpdatedNotif`]\n- [`OpPerfDomainDeletedNotif`]\n"]
978 pub const EVENT_CSTR: &CStr = c"event";
979}
980#[doc = "Get the list of information for all performance domains.\n\nReply attributes:\n- [.get_perf_domain_id()](IterablePerfDomain::get_perf_domain_id)\n- [.get_flags()](IterablePerfDomain::get_flags)\n- [.get_cpus()](IterablePerfDomain::get_cpus)\n\n"]
981#[derive(Debug)]
982pub struct OpGetPerfDomainsDump<'r> {
983 request: Request<'r>,
984}
985impl<'r> OpGetPerfDomainsDump<'r> {
986 pub fn new(mut request: Request<'r>) -> Self {
987 Self::write_header(request.buf_mut());
988 Self {
989 request: request.set_dump(),
990 }
991 }
992 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushPerfDomain<&'buf mut Vec<u8>> {
993 Self::write_header(buf);
994 PushPerfDomain::new(buf)
995 }
996 pub fn encode(&mut self) -> PushPerfDomain<&mut Vec<u8>> {
997 PushPerfDomain::new(self.request.buf_mut())
998 }
999 pub fn into_encoder(self) -> PushPerfDomain<RequestBuf<'r>> {
1000 PushPerfDomain::new(self.request.buf)
1001 }
1002 pub fn decode_request<'a>(buf: &'a [u8]) -> IterablePerfDomain<'a> {
1003 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1004 IterablePerfDomain::with_loc(attrs, buf.as_ptr() as usize)
1005 }
1006 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1007 let mut header = BuiltinNfgenmsg::new();
1008 header.cmd = 1u8;
1009 header.version = 1u8;
1010 prev.as_vec_mut().extend(header.as_slice());
1011 }
1012}
1013impl NetlinkRequest for OpGetPerfDomainsDump<'_> {
1014 fn protocol(&self) -> Protocol {
1015 Protocol::Generic("dev-energymodel".as_bytes())
1016 }
1017 fn flags(&self) -> u16 {
1018 self.request.flags
1019 }
1020 fn payload(&self) -> &[u8] {
1021 self.request.buf()
1022 }
1023 type ReplyType<'buf> = IterablePerfDomain<'buf>;
1024 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1025 Self::decode_request(buf)
1026 }
1027 fn lookup(
1028 buf: &[u8],
1029 offset: usize,
1030 missing_type: Option<u16>,
1031 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1032 Self::decode_request(buf).lookup_attr(offset, missing_type)
1033 }
1034}
1035#[doc = "Get the list of information for all performance domains.\n\nRequest attributes:\n- [.push_perf_domain_id()](PushPerfDomain::push_perf_domain_id)\n\nReply attributes:\n- [.get_perf_domain_id()](IterablePerfDomain::get_perf_domain_id)\n- [.get_flags()](IterablePerfDomain::get_flags)\n- [.get_cpus()](IterablePerfDomain::get_cpus)\n\n"]
1036#[derive(Debug)]
1037pub struct OpGetPerfDomainsDo<'r> {
1038 request: Request<'r>,
1039}
1040impl<'r> OpGetPerfDomainsDo<'r> {
1041 pub fn new(mut request: Request<'r>) -> Self {
1042 Self::write_header(request.buf_mut());
1043 Self { request: request }
1044 }
1045 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushPerfDomain<&'buf mut Vec<u8>> {
1046 Self::write_header(buf);
1047 PushPerfDomain::new(buf)
1048 }
1049 pub fn encode(&mut self) -> PushPerfDomain<&mut Vec<u8>> {
1050 PushPerfDomain::new(self.request.buf_mut())
1051 }
1052 pub fn into_encoder(self) -> PushPerfDomain<RequestBuf<'r>> {
1053 PushPerfDomain::new(self.request.buf)
1054 }
1055 pub fn decode_request<'a>(buf: &'a [u8]) -> IterablePerfDomain<'a> {
1056 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1057 IterablePerfDomain::with_loc(attrs, buf.as_ptr() as usize)
1058 }
1059 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1060 let mut header = BuiltinNfgenmsg::new();
1061 header.cmd = 1u8;
1062 header.version = 1u8;
1063 prev.as_vec_mut().extend(header.as_slice());
1064 }
1065}
1066impl NetlinkRequest for OpGetPerfDomainsDo<'_> {
1067 fn protocol(&self) -> Protocol {
1068 Protocol::Generic("dev-energymodel".as_bytes())
1069 }
1070 fn flags(&self) -> u16 {
1071 self.request.flags
1072 }
1073 fn payload(&self) -> &[u8] {
1074 self.request.buf()
1075 }
1076 type ReplyType<'buf> = IterablePerfDomain<'buf>;
1077 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1078 Self::decode_request(buf)
1079 }
1080 fn lookup(
1081 buf: &[u8],
1082 offset: usize,
1083 missing_type: Option<u16>,
1084 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1085 Self::decode_request(buf).lookup_attr(offset, missing_type)
1086 }
1087}
1088#[doc = "Get the energy model table of a performance domain.\n\nRequest attributes:\n- [.push_perf_domain_id()](PushPerfTable::push_perf_domain_id)\n\nReply attributes:\n- [.get_perf_domain_id()](IterablePerfTable::get_perf_domain_id)\n- [.get_perf_state()](IterablePerfTable::get_perf_state)\n\n"]
1089#[derive(Debug)]
1090pub struct OpGetPerfTableDo<'r> {
1091 request: Request<'r>,
1092}
1093impl<'r> OpGetPerfTableDo<'r> {
1094 pub fn new(mut request: Request<'r>) -> Self {
1095 Self::write_header(request.buf_mut());
1096 Self { request: request }
1097 }
1098 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushPerfTable<&'buf mut Vec<u8>> {
1099 Self::write_header(buf);
1100 PushPerfTable::new(buf)
1101 }
1102 pub fn encode(&mut self) -> PushPerfTable<&mut Vec<u8>> {
1103 PushPerfTable::new(self.request.buf_mut())
1104 }
1105 pub fn into_encoder(self) -> PushPerfTable<RequestBuf<'r>> {
1106 PushPerfTable::new(self.request.buf)
1107 }
1108 pub fn decode_request<'a>(buf: &'a [u8]) -> IterablePerfTable<'a> {
1109 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1110 IterablePerfTable::with_loc(attrs, buf.as_ptr() as usize)
1111 }
1112 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1113 let mut header = BuiltinNfgenmsg::new();
1114 header.cmd = 2u8;
1115 header.version = 1u8;
1116 prev.as_vec_mut().extend(header.as_slice());
1117 }
1118}
1119impl NetlinkRequest for OpGetPerfTableDo<'_> {
1120 fn protocol(&self) -> Protocol {
1121 Protocol::Generic("dev-energymodel".as_bytes())
1122 }
1123 fn flags(&self) -> u16 {
1124 self.request.flags
1125 }
1126 fn payload(&self) -> &[u8] {
1127 self.request.buf()
1128 }
1129 type ReplyType<'buf> = IterablePerfTable<'buf>;
1130 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1131 Self::decode_request(buf)
1132 }
1133 fn lookup(
1134 buf: &[u8],
1135 offset: usize,
1136 missing_type: Option<u16>,
1137 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1138 Self::decode_request(buf).lookup_attr(offset, missing_type)
1139 }
1140}
1141use crate::traits::LookupFn;
1142use crate::utils::RequestBuf;
1143#[derive(Debug)]
1144pub struct Request<'buf> {
1145 buf: RequestBuf<'buf>,
1146 flags: u16,
1147 writeback: Option<&'buf mut Option<RequestInfo>>,
1148}
1149#[allow(unused)]
1150#[derive(Debug, Clone)]
1151pub struct RequestInfo {
1152 protocol: Protocol,
1153 flags: u16,
1154 name: &'static str,
1155 lookup: LookupFn,
1156}
1157impl Request<'static> {
1158 pub fn new() -> Self {
1159 Self::new_from_buf(Vec::new())
1160 }
1161 pub fn new_from_buf(buf: Vec<u8>) -> Self {
1162 Self {
1163 flags: 0,
1164 buf: RequestBuf::Own(buf),
1165 writeback: None,
1166 }
1167 }
1168 pub fn into_buf(self) -> Vec<u8> {
1169 match self.buf {
1170 RequestBuf::Own(buf) => buf,
1171 _ => unreachable!(),
1172 }
1173 }
1174}
1175impl<'buf> Request<'buf> {
1176 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
1177 buf.clear();
1178 Self::new_extend(buf)
1179 }
1180 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
1181 Self {
1182 flags: 0,
1183 buf: RequestBuf::Ref(buf),
1184 writeback: None,
1185 }
1186 }
1187 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
1188 let Some(writeback) = &mut self.writeback else {
1189 return;
1190 };
1191 **writeback = Some(RequestInfo {
1192 protocol,
1193 flags: self.flags,
1194 name,
1195 lookup,
1196 })
1197 }
1198 pub fn buf(&self) -> &Vec<u8> {
1199 self.buf.buf()
1200 }
1201 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1202 self.buf.buf_mut()
1203 }
1204 #[doc = "Set `NLM_F_CREATE` flag"]
1205 pub fn set_create(mut self) -> Self {
1206 self.flags |= consts::NLM_F_CREATE as u16;
1207 self
1208 }
1209 #[doc = "Set `NLM_F_EXCL` flag"]
1210 pub fn set_excl(mut self) -> Self {
1211 self.flags |= consts::NLM_F_EXCL as u16;
1212 self
1213 }
1214 #[doc = "Set `NLM_F_REPLACE` flag"]
1215 pub fn set_replace(mut self) -> Self {
1216 self.flags |= consts::NLM_F_REPLACE as u16;
1217 self
1218 }
1219 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
1220 pub fn set_change(self) -> Self {
1221 self.set_create().set_replace()
1222 }
1223 #[doc = "Set `NLM_F_APPEND` flag"]
1224 pub fn set_append(mut self) -> Self {
1225 self.flags |= consts::NLM_F_APPEND as u16;
1226 self
1227 }
1228 #[doc = "Set `self.flags |= flags`"]
1229 pub fn set_flags(mut self, flags: u16) -> Self {
1230 self.flags |= flags;
1231 self
1232 }
1233 #[doc = "Set `self.flags ^= self.flags & flags`"]
1234 pub fn unset_flags(mut self, flags: u16) -> Self {
1235 self.flags ^= self.flags & flags;
1236 self
1237 }
1238 #[doc = "Set `NLM_F_DUMP` flag"]
1239 fn set_dump(mut self) -> Self {
1240 self.flags |= consts::NLM_F_DUMP as u16;
1241 self
1242 }
1243 #[doc = "Get the list of information for all performance domains.\n\nReply attributes:\n- [.get_perf_domain_id()](IterablePerfDomain::get_perf_domain_id)\n- [.get_flags()](IterablePerfDomain::get_flags)\n- [.get_cpus()](IterablePerfDomain::get_cpus)\n\n"]
1244 pub fn op_get_perf_domains_dump(self) -> OpGetPerfDomainsDump<'buf> {
1245 let mut res = OpGetPerfDomainsDump::new(self);
1246 res.request.do_writeback(
1247 res.protocol(),
1248 "op-get-perf-domains-dump",
1249 OpGetPerfDomainsDump::lookup,
1250 );
1251 res
1252 }
1253 #[doc = "Get the list of information for all performance domains.\n\nRequest attributes:\n- [.push_perf_domain_id()](PushPerfDomain::push_perf_domain_id)\n\nReply attributes:\n- [.get_perf_domain_id()](IterablePerfDomain::get_perf_domain_id)\n- [.get_flags()](IterablePerfDomain::get_flags)\n- [.get_cpus()](IterablePerfDomain::get_cpus)\n\n"]
1254 pub fn op_get_perf_domains_do(self) -> OpGetPerfDomainsDo<'buf> {
1255 let mut res = OpGetPerfDomainsDo::new(self);
1256 res.request.do_writeback(
1257 res.protocol(),
1258 "op-get-perf-domains-do",
1259 OpGetPerfDomainsDo::lookup,
1260 );
1261 res
1262 }
1263 #[doc = "Get the energy model table of a performance domain.\n\nRequest attributes:\n- [.push_perf_domain_id()](PushPerfTable::push_perf_domain_id)\n\nReply attributes:\n- [.get_perf_domain_id()](IterablePerfTable::get_perf_domain_id)\n- [.get_perf_state()](IterablePerfTable::get_perf_state)\n\n"]
1264 pub fn op_get_perf_table_do(self) -> OpGetPerfTableDo<'buf> {
1265 let mut res = OpGetPerfTableDo::new(self);
1266 res.request.do_writeback(
1267 res.protocol(),
1268 "op-get-perf-table-do",
1269 OpGetPerfTableDo::lookup,
1270 );
1271 res
1272 }
1273}
1274#[cfg(test)]
1275mod generated_tests {
1276 use super::*;
1277 #[test]
1278 fn tests() {
1279 let _ = IterablePerfDomain::get_cpus;
1280 let _ = IterablePerfDomain::get_flags;
1281 let _ = IterablePerfDomain::get_perf_domain_id;
1282 let _ = IterablePerfTable::get_perf_domain_id;
1283 let _ = IterablePerfTable::get_perf_state;
1284 let _ = OpPerfDomainCreatedNotif;
1285 let _ = OpPerfDomainDeletedNotif;
1286 let _ = OpPerfDomainUpdatedNotif;
1287 let _ = PushPerfDomain::<&mut Vec<u8>>::push_perf_domain_id;
1288 let _ = PushPerfTable::<&mut Vec<u8>>::push_perf_domain_id;
1289 }
1290}