55import warnings
66from typing import TYPE_CHECKING
77
8- from pytest_codspeed .utils import SUPPORTS_PERF_TRAMPOLINE
9-
108if TYPE_CHECKING :
11- from .dist_instrument_hooks import InstrumentHooksPointer , LibType
9+ from typing import Any
10+
11+ from pytest_codspeed .utils import SUPPORTS_PERF_TRAMPOLINE
1212
1313
1414class InstrumentHooks :
15- """Zig library wrapper class providing benchmark measurement functionality."""
15+ """Native library wrapper class providing benchmark measurement functionality."""
1616
17- lib : LibType
18- instance : InstrumentHooksPointer
17+ _module : Any
18+ _instance : Any
1919
2020 def __init__ (self ) -> None :
2121 if os .environ .get ("CODSPEED_ENV" ) is None :
@@ -25,31 +25,31 @@ def __init__(self) -> None:
2525 )
2626
2727 try :
28- from .dist_instrument_hooks import lib # type: ignore
28+ from . import dist_instrument_hooks # type: ignore
2929 except ImportError as e :
3030 raise RuntimeError (f"Failed to load instrument hooks library: { e } " ) from e
31- self .lib = lib
31+ self ._module = dist_instrument_hooks
3232
33- self .instance = self .lib .instrument_hooks_init ()
34- if self .instance == 0 :
33+ self ._instance = self ._module .instrument_hooks_init ()
34+ if self ._instance is None :
3535 raise RuntimeError ("Failed to initialize CodSpeed instrumentation library." )
3636
3737 if SUPPORTS_PERF_TRAMPOLINE :
3838 sys .activate_stack_trampoline ("perf" ) # type: ignore
3939
4040 def __del__ (self ):
41- if hasattr ( self , "lib" ) and hasattr ( self , "instance" ):
42- self . lib . instrument_hooks_deinit ( self . instance )
41+ # Don't manually deinit - let the capsule destructor handle it
42+ pass
4343
4444 def start_benchmark (self ) -> None :
4545 """Start a new benchmark measurement."""
46- ret = self .lib .instrument_hooks_start_benchmark (self .instance )
46+ ret = self ._module .instrument_hooks_start_benchmark (self ._instance )
4747 if ret != 0 :
4848 warnings .warn ("Failed to start benchmark measurement" , RuntimeWarning )
4949
5050 def stop_benchmark (self ) -> None :
5151 """Stop the current benchmark measurement."""
52- ret = self .lib .instrument_hooks_stop_benchmark (self .instance )
52+ ret = self ._module .instrument_hooks_stop_benchmark (self ._instance )
5353 if ret != 0 :
5454 warnings .warn ("Failed to stop benchmark measurement" , RuntimeWarning )
5555
@@ -63,20 +63,28 @@ def set_executed_benchmark(self, uri: str, pid: int | None = None) -> None:
6363 if pid is None :
6464 pid = os .getpid ()
6565
66- ret = self .lib .instrument_hooks_set_executed_benchmark (
67- self .instance , pid , uri .encode ("ascii" )
66+ ret = self ._module .instrument_hooks_set_executed_benchmark (
67+ self ._instance , pid , uri .encode ("ascii" )
6868 )
6969 if ret != 0 :
7070 warnings .warn ("Failed to set executed benchmark" , RuntimeWarning )
7171
7272 def set_integration (self , name : str , version : str ) -> None :
7373 """Set the integration name and version."""
74- ret = self .lib .instrument_hooks_set_integration (
75- self .instance , name .encode ("ascii" ), version .encode ("ascii" )
74+ ret = self ._module .instrument_hooks_set_integration (
75+ self ._instance , name .encode ("ascii" ), version .encode ("ascii" )
7676 )
7777 if ret != 0 :
7878 warnings .warn ("Failed to set integration name and version" , RuntimeWarning )
7979
8080 def is_instrumented (self ) -> bool :
8181 """Check if simulation is active."""
82- return self .lib .instrument_hooks_is_instrumented (self .instance )
82+ return self ._module .instrument_hooks_is_instrumented (self ._instance )
83+
84+ def callgrind_start_instrumentation (self ) -> None :
85+ """Start callgrind instrumentation."""
86+ self ._module .callgrind_start_instrumentation ()
87+
88+ def callgrind_stop_instrumentation (self ) -> None :
89+ """Stop callgrind instrumentation."""
90+ self ._module .callgrind_stop_instrumentation ()
0 commit comments