@@ -64,91 +64,121 @@ pub fn enabled() -> Result<bool, Error> {
6464 unsafe { raw:: read_mib ( & * MIB_OPT_PROF ) . map_err ( Into :: into) }
6565}
6666
67+ // TODO: consider a guard pattern instead of checking for each command.
68+ fn if_enabled < F , T > ( f : F ) -> Result < T , Error >
69+ where
70+ F : FnOnce ( ) -> Result < T , Error > ,
71+ {
72+ if enabled ( ) ? {
73+ f ( )
74+ } else {
75+ Err ( Error :: ProfilingDisabled )
76+ }
77+ }
78+
6779/// Writes `prof.active`.
6880#[ inline]
6981pub fn set_active ( value : bool ) -> Result < ( ) , Error > {
70- // SAFETY: use correct type (bool) for this mallctl command.
71- unsafe { raw:: write_mib ( & * MIB_PROF_ACTIVE , value) . map_err ( Into :: into) }
82+ if_enabled ( move || {
83+ // SAFETY: use correct type (bool) for this mallctl command.
84+ unsafe { raw:: write_mib ( & * MIB_PROF_ACTIVE , value) . map_err ( Into :: into) }
85+ } )
7286}
7387
7488/// Reads `prof.active`.
7589#[ inline]
7690pub fn active ( ) -> Result < bool , Error > {
77- // SAFETY: use correct type (bool) for this mallctl command.
78- unsafe { raw:: read_mib ( & * MIB_PROF_ACTIVE ) . map_err ( Into :: into) }
91+ if_enabled ( move || {
92+ // SAFETY: use correct type (bool) for this mallctl command.
93+ unsafe { raw:: read_mib ( & * MIB_PROF_ACTIVE ) . map_err ( Into :: into) }
94+ } )
7995}
8096
8197/// Writes `prof.thread_active_init`.
8298#[ inline]
8399pub fn set_thread_active_init ( value : bool ) -> Result < ( ) , Error > {
84- // SAFETY: use correct param type (bool) for this mallctl command.
85- unsafe { raw:: write_mib ( & * MIB_PROF_THREAD_ACTIVE_INIT , value) . map_err ( Into :: into) }
100+ if_enabled ( move || {
101+ // SAFETY: use correct param type (bool) for this mallctl command.
102+ unsafe { raw:: write_mib ( & * MIB_PROF_THREAD_ACTIVE_INIT , value) . map_err ( Into :: into) }
103+ } )
86104}
87105
88106/// Reads `prof.thread_active_init`.
89107#[ inline]
90108pub fn thread_active_init ( ) -> Result < bool , Error > {
91- // SAFETY: use correct return type (bool) for this mallctl command.
92- unsafe { raw:: read_mib ( & * MIB_PROF_THREAD_ACTIVE_INIT ) . map_err ( Into :: into) }
109+ if_enabled ( move || {
110+ // SAFETY: use correct return type (bool) for this mallctl command.
111+ unsafe { raw:: read_mib ( & * MIB_PROF_THREAD_ACTIVE_INIT ) . map_err ( Into :: into) }
112+ } )
93113}
94114
95115/// Writes `thread.prof.active`.
96116#[ inline]
97117pub fn set_thread_active ( value : bool ) -> Result < ( ) , Error > {
98- // SAFETY: use correct param type (bool) for this mallctl command.
99- unsafe { raw:: write_mib ( & * MIB_THREAD_PROF_ACTIVE , value) . map_err ( Into :: into) }
118+ if_enabled ( move || {
119+ // SAFETY: use correct param type (bool) for this mallctl command.
120+ unsafe { raw:: write_mib ( & * MIB_THREAD_PROF_ACTIVE , value) . map_err ( Into :: into) }
121+ } )
100122}
101123
102124/// Reads `thread.prof.active`.
103125#[ inline]
104126pub fn thread_active ( ) -> Result < bool , Error > {
105- // SAFETY: use correct return type (bool) for this mallctl command.
106- unsafe { raw:: read_mib ( & * MIB_THREAD_PROF_ACTIVE ) . map_err ( Into :: into) }
127+ if_enabled ( move || {
128+ // SAFETY: use correct return type (bool) for this mallctl command.
129+ unsafe { raw:: read_mib ( & * MIB_THREAD_PROF_ACTIVE ) . map_err ( Into :: into) }
130+ } )
107131}
108132
109133/// Writes `prof.reset`. Optionally settings a new sample interval.
110134#[ allow( clippy:: option_if_let_else, clippy:: borrow_as_ptr) ]
111135#[ inline]
112136pub fn reset ( sample : Option < usize > ) -> Result < ( ) , Error > {
113- let value = match sample {
114- Some ( mut sample) => & mut sample as * mut _ ,
115- None => ptr:: null_mut ( ) ,
116- } ;
117- // SAFETY: use correct param type (*size_t) for this mallctl command.
118- unsafe { write_mib_ptr ( & * MIB_PROF_RESET , value) . map_err ( Into :: into) }
137+ if_enabled ( move || {
138+ let value = match sample {
139+ Some ( mut sample) => & mut sample as * mut _ ,
140+ None => ptr:: null_mut ( ) ,
141+ } ;
142+ // SAFETY: use correct param type (*size_t) for this mallctl command.
143+ unsafe { write_mib_ptr ( & * MIB_PROF_RESET , value) . map_err ( Into :: into) }
144+ } )
119145}
120146
121147/// Reads `prof.lg_sample`.
122148#[ inline]
123149pub fn sample_interval ( ) -> Result < usize , Error > {
124- // SAFETY: use correct return type (size_t) for this mallctl command.
125- unsafe { raw:: read_mib ( & * MIB_PROF_LG_SAMPLE ) . map_err ( Into :: into) }
150+ if_enabled ( move || {
151+ // SAFETY: use correct return type (size_t) for this mallctl command.
152+ unsafe { raw:: read_mib ( & * MIB_PROF_LG_SAMPLE ) . map_err ( Into :: into) }
153+ } )
126154}
127155
128156/// Writes `prof.dump` causing a profile dump into a file.
129157/// If a path is given, use the file as dump target and return its content.
130158/// If not, jemalloc dumps the profile to a file based on name pattern.
131159#[ inline]
132160pub fn dump ( path : Option < & str > ) -> Result < Option < Vec < u8 > > , Error > {
133- let ptr = match path {
134- Some ( s) => ffi:: CString :: new ( s) ?. into_bytes_with_nul ( ) . as_ptr ( ) ,
135- None => ptr:: null ( ) ,
136- } ;
161+ if_enabled ( move || {
162+ let ptr = match path {
163+ Some ( s) => ffi:: CString :: new ( s) ?. into_bytes_with_nul ( ) . as_ptr ( ) ,
164+ None => ptr:: null ( ) ,
165+ } ;
137166
138- // SAFETY: use correct param type (*char+\0) for this mallctl command.
139- unsafe {
140- raw:: write_mib ( & * MIB_PROF_DUMP , ptr) ?;
141- }
167+ // SAFETY: use correct param type (*char+\0) for this mallctl command.
168+ unsafe {
169+ raw:: write_mib ( & * MIB_PROF_DUMP , ptr) ?;
170+ }
142171
143- match path {
144- Some ( path) => {
145- let mut f = fs:: File :: open ( path) ?;
146- let mut buf = Vec :: new ( ) ;
147- io:: copy ( & mut f, & mut buf) ?;
148- Ok ( Some ( buf) )
172+ match path {
173+ Some ( path) => {
174+ let mut f = fs:: File :: open ( path) ?;
175+ let mut buf = Vec :: new ( ) ;
176+ io:: copy ( & mut f, & mut buf) ?;
177+ Ok ( Some ( buf) )
178+ }
179+ None => Ok ( None ) ,
149180 }
150- None => Ok ( None ) ,
151- }
181+ } )
152182}
153183
154184pub fn stats ( ) -> Result < Vec < u8 > , Error > {
@@ -176,6 +206,9 @@ unsafe fn write_mib_ptr<T>(mib: &[usize], value: *mut T) -> Result<(), Error> {
176206
177207#[ derive( thiserror:: Error , fmt:: Debug ) ]
178208pub enum Error {
209+ #[ error( "mallctl: profiling disabled" ) ]
210+ ProfilingDisabled ,
211+
179212 #[ error( "mallctl error: {0}" ) ]
180213 Mallctl ( #[ from] MallctlError ) ,
181214
0 commit comments