Skip to main content

netlink_bindings/dev-energymodel/
mod.rs

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