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}