sweep through entire page table to free up intermediate tables
[lunaix-os.git] / lunaix-os / scripts / gdb / lunadbg / profiling / pmstat.py
1 from ..symbols import LunaixSymbols
2 from ..structs.page import PageStruct
3 from ..structs.pmem import PMem
4 from ..pp import MyPrettyPrinter
5 import math
6
7 ENTER_CONTIG = 0
8 LEAVE_CONTIG = 1
9
10 class PhysicalMemProfile:
11     def __init__(self) -> None:
12         super().__init__()
13         self._pmem    = PMem(LunaixSymbols.debug_sym("pmm", "memory").value().address)
14
15         self.max_mem_pg = self._pmem.list_len()
16         self.max_mem_sz = self.max_mem_pg * 4096
17         self.mem_distr = []
18
19     def rescan_pmem(self, distr_granule = 256):
20         self.__mem_distr_granule = distr_granule
21         self.mem_distr.clear()
22
23         pplist = self._pmem.pplist()
24         page_per_granule = int(self.max_mem_pg) // self.__mem_distr_granule
25         remainder = self.max_mem_pg % self.__mem_distr_granule
26         bucket = 0
27         non_contig = 0
28         contig_state = LEAVE_CONTIG
29         new_state = LEAVE_CONTIG
30
31         i = 0
32         while i < self.max_mem_pg:
33             element = PageStruct(pplist[i].address)
34
35             nr_pgs = 1
36             if element.lead_page():
37                 nr_pgs = 1 << element.order
38                 if element.busy():
39                     bucket += nr_pgs
40                     new_state = ENTER_CONTIG
41                 else:
42                     new_state = LEAVE_CONTIG
43             
44             i += nr_pgs
45
46             if contig_state != new_state:
47                 non_contig += int(new_state == LEAVE_CONTIG)
48                 contig_state = new_state
49
50             if i % page_per_granule == 0:
51                 self.mem_distr.append(bucket)
52                 bucket = 0
53         
54         if remainder > 0:
55             if bucket > 0:
56                 bucket += page_per_granule - remainder
57             self.mem_distr.append(bucket)
58
59         self.consumed_pg = sum(self.mem_distr)
60         self.utilisation = self.consumed_pg / self.max_mem_pg
61         self.fragmentation = 2 * non_contig / self.max_mem_pg
62         self.discontig = non_contig
63         self.page_per_granule = page_per_granule
64