Support to multi-threading and pthread interface (POSIX.1-2008) (#23)
[lunaix-os.git] / lunaix-os / scripts / gdb / lunadbg / mem.py
1 from .commands import LunadbgCommand
2 from .pp import MyPrettyPrinter
3 from .profiling.pmstat import PhysicalMemProfile
4 from .structs.pagetable import PageTable, PageTableEntry
5
6 class MMStats(LunadbgCommand):
7     def __init__(self) -> None:
8         super().__init__("mm")
9         subparsers = self._parser.add_subparsers(dest="cmd")
10         
11         stats = subparsers.add_parser("stats")
12         stats.add_argument("state_type")
13         stats.add_argument("-g", "--granule", type=int, default=512)
14         stats.add_argument("--cols", type=int, default=32)
15
16         lookup = subparsers.add_parser("lookup")
17         lookup.add_argument("mem_type")
18         lookup.add_argument("address")
19         lookup.add_argument("-l", "--level", type=int, default=-1)
20         lookup.add_argument("-n", type=int, default=0)
21         lookup.add_argument("-t", "--to", dest="to_addr", default='0')
22
23         self.__ptw = PageTable()
24
25     def print_pmem_stats(self, pp: MyPrettyPrinter, optn):
26         pmem = PhysicalMemProfile()
27         pmem.rescan_pmem(optn.granule)
28
29         pp.printf("Total: %dKiB (%d@4K)", 
30                   pmem.max_mem_sz, pmem.max_mem_pg)
31         
32         pp.printf("Used:  %dKiB (%d@4K) ~%.2f%%", 
33                   pmem.consumed_pg * 4096, 
34                   pmem.consumed_pg, pmem.utilisation * 100)
35         
36         pp.printf("Fragmentations: %d ~%.2f%%", pmem.discontig, pmem.fragmentation * 100)
37         pp.print()
38         
39         pp.print("Distribution")
40         pp2 = pp.next_level(2)
41         row = []
42         for i in range(0, len(pmem.mem_distr)):
43             ratio = pmem.mem_distr[i] / pmem.page_per_granule
44             cat = int(ratio * 9)
45             if ratio == 0:
46                 row.append('.')
47             elif ratio == 1:
48                 row.append('F')
49             else:
50                 row.append(str(cat))
51                 
52             if (i + 1) % optn.cols == 0:
53                 pp2.print(''.join(row))
54                 row.clear()
55         if (i + 1) % optn.cols != 0:
56             pp2.print(''.join(row))
57         
58         pp.printf("(granule: %d, density: %d@4K)", optn.granule, pmem.page_per_granule)
59
60     def vm_lookup(self, pp, va, optn):
61         to_addr = int(optn.to_addr, 0)
62         if not optn.n and not to_addr:
63             pp.print(self.__ptw.get_pte(va, level=optn.level))
64         else:
65             if to_addr:
66                 self.__ptw.print_ptes_between(pp, va, to_addr, optn.level)
67             else:
68                 self.__ptw.print_ptes(pp, va, optn.n, optn.level)
69
70     def __do_stats(self, pp, optn):
71         if optn.state_type == "pmem":
72             self.print_pmem_stats(pp, optn)
73         else:
74             print("unknow stats type:", optn.state_type)
75
76     def __do_lookup(self, pp, address, optn):
77         if optn.mem_type == "vm":
78             self.vm_lookup(pp, int(address, base=0), optn)
79         else:
80             print("unknow mem type:", optn.state_type)
81
82     def invoke(self, argument: str, from_tty: bool) -> None:
83         optn = self._parse_args(argument)
84         pp = MyPrettyPrinter()
85
86         if optn.cmd == 'stats':
87             self.__do_stats(pp, optn)
88         elif optn.cmd == 'lookup':
89             self.__do_lookup(pp, optn.address, optn)
90         else:
91             print("unknown command:", optn.cmd)