From 72ffb256cf2d4f40af7037950b436b6b4203f1d2 Mon Sep 17 00:00:00 2001 From: victorjin Date: Mon, 20 May 2024 14:54:43 +0800 Subject: [PATCH] Adjust PmuData class to optimize memory free --- python/modules/_libkperf/Config.py | 6 +-- python/modules/_libkperf/Pmu.py | 59 ++++++++++++++++++++++-------- python/modules/_libkperf/Symbol.py | 19 +++++----- python/modules/kperf/pmu.py | 58 +++++------------------------ python/modules/ksym/symbol.py | 6 +-- 5 files changed, 68 insertions(+), 80 deletions(-) diff --git a/python/modules/_libkperf/Config.py b/python/modules/_libkperf/Config.py index f885f3e..6991f0f 100644 --- a/python/modules/_libkperf/Config.py +++ b/python/modules/_libkperf/Config.py @@ -23,16 +23,16 @@ VERSION = '1.0' UTF_8 = 'utf-8' -def lib_path(): +def lib_path() -> str: return os.path.dirname(os.path.abspath(__file__)) -def libsym_path(): +def libsym_path() -> str: libsym = 'libsym.so' return os.path.join(lib_path(), libsym) -def libkperf_path(): +def libkperf_path() -> str: libkperf = 'libkperf.so' return os.path.join(lib_path(), libkperf) diff --git a/python/modules/_libkperf/Pmu.py b/python/modules/_libkperf/Pmu.py index cbf4ee2..18baad5 100644 --- a/python/modules/_libkperf/Pmu.py +++ b/python/modules/_libkperf/Pmu.py @@ -56,7 +56,7 @@ class CtypesPmuAttr(ctypes.Structure): dataFilter: int = 0, evFilter: int = 0, minLatency: int = 0, - *args: Any, **kw: Any): + *args: Any, **kw: Any) -> None: super().__init__(*args, **kw) if evtList: @@ -113,7 +113,7 @@ class PmuAttr: symbolMode: int=0, dataFilter: int=0, evFilter: int=0, - minLatency: int=0): + minLatency: int=0) -> None: self.__c_pmu_attr = CtypesPmuAttr( evtList=evtList, pidList=pidList, @@ -277,7 +277,7 @@ class CtypesCpuTopology(ctypes.Structure): coreId: int = 0, numaId: int = 0, socketId: int = 0, - *args: Any, **kw: Any): + *args: Any, **kw: Any) -> None: super().__init__(*args, **kw) self.coreId = ctypes.c_int(coreId) self.numaId = ctypes.c_int(numaId) @@ -290,7 +290,7 @@ class CpuTopology: def __init__(self, coreId: int = 0, numaId: int = 0, - socketId: int = 0): + socketId: int = 0) -> None: self.__c_cpu_topo = CtypesCpuTopology( coreId=coreId, numaId=numaId, @@ -345,7 +345,7 @@ class CtypesPmuDataExt(ctypes.Structure): pa: int = 0, va: int = 0, event: int = 0, - *args: Any, **kw: Any): + *args: Any, **kw: Any) -> None: super().__init__(*args, **kw) self.pa = ctypes.c_ulong(pa) self.va = ctypes.c_ulong(va) @@ -358,7 +358,7 @@ class PmuDataExt: def __init__(self, pa: int = 0, va: int = 0, - event: int = 0): + event: int = 0) -> None: self.__c_pmu_data_ext = CtypesPmuDataExt( pa=pa, va=va, @@ -427,7 +427,7 @@ class CtypesPmuData(ctypes.Structure): period: int = 0, count: int = 0, ext: CtypesPmuDataExt = None, - *args: Any, **kw: Any): + *args: Any, **kw: Any) -> None: super().__init__(*args, **kw) self.stack = stack @@ -443,7 +443,7 @@ class CtypesPmuData(ctypes.Structure): self.ext = ext -class PmuData: +class ImplPmuData: __slots__ = ['__c_pmu_data'] def __init__(self, @@ -457,7 +457,7 @@ class PmuData: comm: str = '', period: int = 0, count: int = 0, - ext: PmuDataExt = None): + ext: PmuDataExt = None) -> None: self.__c_pmu_data = CtypesPmuData( stack=stack.c_stack if stack else None, evt=evt, @@ -566,12 +566,39 @@ class PmuData: self.c_pmu_data.ext = ext.c_pmu_data_ext if ext else None @classmethod - def from_c_pmu_data(cls, c_pmu_data: CtypesPmuData) -> 'PmuData': + def from_c_pmu_data(cls, c_pmu_data: CtypesPmuData) -> 'ImplPmuData': pmu_data = cls() pmu_data.__c_pmu_data = c_pmu_data return pmu_data +class PmuData: + + __slots__ = ['__pointer', '__iter', '__len'] + + def __init__(self, pointer: ctypes.POINTER(CtypesPmuData) = None, len: int = 0) -> None: + + self.__pointer = pointer + self.__len = len + self.__iter = (ImplPmuData.from_c_pmu_data(self.__pointer[i]) for i in range(self.__len)) + + def __del__(self) -> None: + self.free() + + @property + def len(self) -> int: + return self.__len + + @property + def iter(self) -> Iterator[ImplPmuData]: + return self.__iter + + def free(self) -> None: + if self.__pointer is not None: + PmuDataFree(self.__pointer) + self.__pointer = None + + def PmuOpen(collectType: int, pmuAttr: PmuAttr) -> int: c_PmuOpen = kperf_so.PmuOpen c_PmuOpen.argtypes = [ctypes.c_int, ctypes.POINTER(CtypesPmuAttr)] @@ -629,7 +656,7 @@ def PmuCollect(pd: int, milliseconds: int, interval: int) -> int: c_pd = ctypes.c_int(pd) c_milliseconds = ctypes.c_int(milliseconds) - c_interval = ctypes.c_uint(milliseconds) + c_interval = ctypes.c_uint(interval) return c_PmuCollect(c_pd, c_milliseconds, c_interval) @@ -651,17 +678,16 @@ def PmuDataFree(pmuData: ctypes.POINTER(CtypesPmuData)) -> None: c_PmuDataFree(pmuData) -def PmuRead(pd: int) -> Iterator[PmuData]: +def PmuRead(pd: int) -> PmuData: c_PmuRead = kperf_so.PmuRead c_PmuRead.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.POINTER(CtypesPmuData))] c_PmuRead.restype = ctypes.c_int c_pd = ctypes.c_int(pd) - c_data = ctypes.pointer(CtypesPmuData()) + c_data_pointer = ctypes.pointer(CtypesPmuData()) - c_len_data = c_PmuRead(c_pd, ctypes.byref(c_data)) - data_iter = (PmuData.from_c_pmu_data(c_data[i]) for i in range(c_len_data)) - return data_iter + c_data_len = c_PmuRead(c_pd, ctypes.byref(c_data_pointer)) + return PmuData(c_data_pointer, c_data_len) def PmuAppendData(fromData: ctypes.POINTER(CtypesPmuData), toData: ctypes.POINTER(ctypes.POINTER(CtypesPmuData))) -> int: @@ -686,6 +712,7 @@ __all__ = [ 'PmuAttr', 'CpuTopology', 'PmuDataExt', + 'ImplPmuData', 'PmuData', 'PmuOpen', 'PmuEventList', diff --git a/python/modules/_libkperf/Symbol.py b/python/modules/_libkperf/Symbol.py index 4ef6480..732053a 100644 --- a/python/modules/_libkperf/Symbol.py +++ b/python/modules/_libkperf/Symbol.py @@ -41,7 +41,7 @@ class CtypesSymbol(ctypes.Structure): codeMapEndAddr: int = 0, codeMapAddr: int = 0, count: int = 0, - *args: Any, **kw: Any): + *args: Any, **kw: Any) -> None: super().__init__(*args, **kw) self.addr = ctypes.c_ulong(addr) self.module = ctypes.c_char_p(module.encode(UTF_8)) @@ -69,7 +69,7 @@ class Symbol: offset: int = 0, codeMapEndAddr: int = 0, codeMapAddr: int = 0, - count: int = 0): + count: int = 0) -> None: self.__c_sym = CtypesSymbol( addr=addr, module=module, @@ -169,9 +169,9 @@ class CtypesStack(ctypes.Structure): _fields_ = [ ('symbol', ctypes.POINTER(CtypesSymbol)), - ('next', ctypes.POINTER('CtypesStack')), - ('prev', ctypes.POINTER('CtypesStack')), - ('count', ctypes.c_uint64) + ('next', ctypes.POINTER('CtypesStack')), + ('prev', ctypes.POINTER('CtypesStack')), + ('count', ctypes.c_uint64) ] def __init__(self, @@ -179,7 +179,7 @@ class CtypesStack(ctypes.Structure): next: 'CtypesStack' = None, prev: 'CtypesStack' = None, count: int = 0, - *args: Any, **kw: Any): + *args: Any, **kw: Any) -> None: super().__init__(*args, **kw) """ ctypes中,一个ctypes对象赋值给一个ctypes.POINTER类型的字段时 @@ -199,7 +199,7 @@ class Stack: symbol: Symbol = None, next: 'Stack' = None, prev: 'Stack' = None, - count: int = 0): + count: int = 0) -> None: self.__c_stack = CtypesStack( symbol=symbol.c_sym if symbol else None, next=next.c_stack if next else None, @@ -266,7 +266,7 @@ class CtypesAsmCode(ctypes.Structure): code: str = '', fileName: str = '', lineNum: int = 0, - *args: Any, **kw: Any): + *args: Any, **kw: Any) -> None: super().__init__(*args, **kw) self.addr = ctypes.c_ulong(addr) self.code = ctypes.c_char_p(code.encode(UTF_8)) @@ -282,7 +282,7 @@ class AsmCode: addr: int = 0, code: str = '', fileName: str = '', - lineNum: int = 0): + lineNum: int = 0) -> None: self.__c_asm_code = CtypesAsmCode( addr=addr, code=code, @@ -373,7 +373,6 @@ def StackToHash(pid: int, stackList: List[int]) -> Iterator[Stack]: c_stack = c_StackToHash(c_pid, c_stack_list, c_nr) while c_stack: - # 此处指针转换可能还有问题,TODO stack = Stack.from_c_stack(c_stack) yield stack c_stack = c_stack.contents.next diff --git a/python/modules/kperf/pmu.py b/python/modules/kperf/pmu.py index 6c0e69d..17c89e2 100644 --- a/python/modules/kperf/pmu.py +++ b/python/modules/kperf/pmu.py @@ -12,7 +12,7 @@ Author: Victor Jin Create: 2024-05-16 Description: kperf pmu module """ -from typing import Iterator, List +from typing import List, Iterator import _libkperf import ksym @@ -88,7 +88,7 @@ class PmuAttr(_libkperf.PmuAttr): symbolMode: int = 0, dataFilter: int = 0, evFilter: int = 0, - minLatency: int = 0): + minLatency: int = 0) -> None: super().__init__( evtList=evtList, pidList=pidList, @@ -105,58 +105,19 @@ class PmuAttr(_libkperf.PmuAttr): class CpuTopology(_libkperf.CpuTopology): - - def __init__(self, - coreId: int = 0, - numaId: int = 0, - socketId: int = 0): - super().__init__( - coreId=coreId, - numaId=numaId, - socketId=socketId - ) + pass class PmuDataExt(_libkperf.PmuDataExt): + pass - def __init__(self, - pa: int = 0, - va: int = 0, - event: int = 0): - super().__init__( - pa=pa, - va=va, - event=event - ) +class ImplPmuData(_libkperf.ImplPmuData): + pass -class PmuData(_libkperf.PmuData): - def __init__(self, - stack: ksym.Stack = None, - evt: str = '', - ts: int = 0, - pid: int = 0, - tid: int = 0, - cpu: int = 0, - cpuTopo: CpuTopology = None, - comm: str = '', - period: int = 0, - count: int = 0, - ext: PmuDataExt = None): - super().__init__( - stack=stack.c_stack if stack else None, - evt=evt, - ts=ts, - pid=pid, - tid=tid, - cpu=cpu, - cpuTopo=cpuTopo.c_cpu_topo if cpuTopo else None, - comm=comm, - period=period, - count=count, - ext=ext.c_pmu_data_ext if ext else None, - ) +class PmuData(_libkperf.PmuData): + pass def open(collect_type: PmuTaskType, pmu_attr: PmuAttr) -> int: @@ -175,7 +136,7 @@ def disable(pd: int)-> int: return _libkperf.PmuDisable(pd) -def read(pd: int) -> Iterator[PmuData]: +def read(pd: int) -> PmuData: return _libkperf.PmuRead(pd) @@ -196,6 +157,7 @@ __all__ = [ 'PmuAttr', 'CpuTopology', 'PmuDataExt', + 'ImplPmuData', 'PmuData', 'open', 'event_list', diff --git a/python/modules/ksym/symbol.py b/python/modules/ksym/symbol.py index 8d9338a..e674344 100644 --- a/python/modules/ksym/symbol.py +++ b/python/modules/ksym/symbol.py @@ -28,7 +28,7 @@ class Symbol(_libkperf.Symbol): offset: int = 0, codeMapEndAddr: int = 0, codeMapAddr: int = 0, - count: int = 0): + count: int = 0) -> None: super().__init__( addr=addr, module=module, @@ -48,7 +48,7 @@ class Stack(_libkperf.Stack): symbol: Symbol = None, next: 'Stack' = None, prev: 'Stack' = None, - count: int = 0): + count: int = 0) -> None: super().__init__( symbol=symbol.c_sym if symbol else None, next=next.c_stack if next else None, @@ -85,8 +85,8 @@ def destroy() -> None: __all__ = [ - 'Stack', 'Symbol', + 'Stack', 'record_kernel', 'record_module', 'get_stack', -- Gitee