Skip to content

Commit b80b1c9

Browse files
Thom Chiovolonithomcc
authored andcommitted
Add ctests, make them work
1 parent 48dabd8 commit b80b1c9

File tree

6 files changed

+97
-52
lines changed

6 files changed

+97
-52
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ license = "MIT"
1414
readme = "README.md"
1515

1616
[workspace]
17-
members = ["libmimalloc-sys"]
17+
members = ["libmimalloc-sys", "libmimalloc-sys/sys-test"]
1818

1919
[badges]
2020
travis-ci = { repository = "purpleprotocol/mimalloc_rust" }

libmimalloc-sys/src/extended.rs

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -173,15 +173,15 @@ extern "C" {
173173
/// function or stderr by default.
174174
///
175175
/// Most detailed when using a debug build.
176-
pub fn mi_stats_print(_: *const c_void);
176+
pub fn mi_stats_print(_: *mut c_void);
177177

178178
/// Print the main statistics.
179179
///
180180
/// Pass `None` for `out` to use the default. If `out` is provided, `arc` is
181181
/// passed as it's second parameter.
182182
///
183183
/// Most detailed when using a debug build.
184-
pub fn mi_stats_print_out(out: Option<mi_output_fun>, arg: *mut c_void);
184+
pub fn mi_stats_print_out(out: mi_output_fun, arg: *mut c_void);
185185

186186
/// Reset statistics.
187187
///
@@ -193,12 +193,23 @@ extern "C" {
193193
/// Note: This function is thread safe.
194194
pub fn mi_stats_merge();
195195

196+
/// Return the mimalloc version number.
197+
///
198+
/// For example version 1.6.3 would return the number `163`.
199+
pub fn mi_version() -> c_int;
200+
196201
/// Initialize mimalloc on a thread.
197202
///
198203
/// Should not be used as on most systems (pthreads, windows) this is done
199204
/// automatically.
200205
pub fn mi_thread_init();
201206

207+
/// Initialize the process.
208+
///
209+
/// Should not be used on most systems, as it's called by thread_init or the
210+
/// process loader.
211+
pub fn mi_process_init();
212+
202213
/// Uninitialize mimalloc on a thread.
203214
///
204215
/// Should not be used as on most systems (pthreads, windows) this is done
@@ -216,7 +227,7 @@ extern "C" {
216227
/// Most detailed when using a debug build.
217228
///
218229
/// Note: This function is thread safe.
219-
pub fn mi_thread_stats_print_out(out: Option<mi_output_fun>, arg: *mut c_void);
230+
pub fn mi_thread_stats_print_out(out: mi_output_fun, arg: *mut c_void);
220231

221232
/// Register an output function.
222233
///
@@ -227,7 +238,7 @@ extern "C" {
227238
/// like verbose or warning messages.
228239
///
229240
/// Note: This function is thread safe.
230-
pub fn mi_register_output(out: Option<mi_output_fun>, arg: *mut c_void);
241+
pub fn mi_register_output(out: mi_output_fun, arg: *mut c_void);
231242

232243
/// Register a deferred free function.
233244
///
@@ -255,7 +266,7 @@ extern "C" {
255266
/// At most one `deferred_free` function can be active.
256267
///
257268
/// Note: This function is thread safe.
258-
pub fn mi_register_deferred_free(out: Option<mi_deferred_free_fun>, arg: *mut c_void);
269+
pub fn mi_register_deferred_free(out: mi_deferred_free_fun, arg: *mut c_void);
259270

260271
/// Register an error callback function.
261272
///
@@ -278,13 +289,13 @@ extern "C" {
278289
/// - `EINVAL` (22): Trying to free or re-allocate an invalid pointer.
279290
///
280291
/// Note: This function is thread safe.
281-
pub fn mi_register_error(out: Option<mi_error_fun>, arg: *mut c_void);
292+
pub fn mi_register_error(out: mi_error_fun, arg: *mut c_void);
282293
}
283294

284295
/// An output callback. Must be thread-safe.
285296
///
286297
/// See [`mi_stats_print_out`], [`mi_thread_stats_print_out`], [`mi_register_output`]
287-
pub type mi_output_fun = unsafe extern "C" fn(msg: *const c_char, arg: *mut c_void);
298+
pub type mi_output_fun = Option<unsafe extern "C" fn(msg: *const c_char, arg: *mut c_void)>;
288299

289300
/// Type of deferred free functions. Must be thread-safe.
290301
///
@@ -294,27 +305,22 @@ pub type mi_output_fun = unsafe extern "C" fn(msg: *const c_char, arg: *mut c_vo
294305
///
295306
/// See [`mi_register_deferred_free`]
296307
pub type mi_deferred_free_fun =
297-
unsafe extern "C" fn(force: bool, heartbeat: c_ulonglong, arg: *mut c_void);
308+
Option<unsafe extern "C" fn(force: bool, heartbeat: c_ulonglong, arg: *mut c_void)>;
298309

299310
/// Type of error callback functions. Must be thread-safe.
300311
///
301312
/// - `err`: Error code (see [`mi_register_error`] for a list).
302313
/// - `arg`: Argument that was passed at registration to hold extra state.
303314
///
304315
/// See [`mi_register_error`]
305-
pub type mi_error_fun = unsafe extern "C" fn(code: c_int, arg: *mut c_void);
306-
307-
/// Runtime options. Only exists to make ctest happy since this was defined as
308-
/// `typedef enum mi_option_e { ... } mi_option_t;`...
309-
#[doc(hidden)]
310-
pub type mi_option_e = c_int;
316+
pub type mi_error_fun = Option<unsafe extern "C" fn(code: c_int, arg: *mut c_void)>;
311317

312318
/// Runtime options. All options are false by default.
313319
///
314320
/// Note: Currently experimental options (values > `mi_option_verbose` are not
315321
/// given named constants), as they may change and make exposing a stable API
316322
/// difficult.
317-
pub type mi_option_t = mi_option_e;
323+
pub type mi_option_t = c_int;
318324

319325
// Note: mimalloc doc website seems to have the order of show_stats and
320326
// show_errors reversed as of 1.6.3, however what I have here is correct:
@@ -336,7 +342,7 @@ extern "C" {
336342
/// Returns true if the provided option is enabled.
337343
///
338344
/// Note: this function is not thread safe.
339-
pub fn mi_option_enabled(option: mi_option_t) -> bool;
345+
pub fn mi_option_is_enabled(option: mi_option_t) -> bool;
340346

341347
/// Enable or disable the given option.
342348
///
@@ -391,14 +397,8 @@ extern "C" {
391397
///
392398
/// Note: this function is not thread safe.
393399
pub fn mi_option_set_default(option: mi_option_t, value: c_long);
394-
395400
}
396401

397-
#[doc(hidden)]
398-
pub type mi_heap_s = mi_heap_t;
399-
#[doc(hidden)]
400-
pub type mi_heap_area_s = mi_heap_area_t;
401-
402402
/// First-class heaps that can be destroyed in one go.
403403
///
404404
/// Note: The pointers allocated out of a heap can be be freed using
@@ -424,17 +424,13 @@ pub type mi_heap_area_s = mi_heap_area_t;
424424
/// mi::mi_heap_delete(h);
425425
/// }
426426
/// ```
427-
#[repr(C)]
428-
pub struct mi_heap_t {
429-
_priv: [u8; 0],
430-
}
427+
pub enum mi_heap_t {}
431428

432429
/// An area of heap space contains blocks of a single size.
433430
///
434431
/// The bytes in freed blocks are `committed - used`.
435432
#[repr(C)]
436433
#[derive(Debug, Clone, Copy)]
437-
#[non_exhaustive]
438434
pub struct mi_heap_area_t {
439435
/// Start of the area containing heap blocks.
440436
pub blocks: *mut c_void,
@@ -448,34 +444,22 @@ pub struct mi_heap_area_t {
448444
pub block_size: usize,
449445
}
450446

451-
// Provide a default impl so that the `non_exhaustive` bound is not too painful.
452-
impl Default for mi_heap_area_t {
453-
#[inline]
454-
fn default() -> Self {
455-
Self {
456-
blocks: core::ptr::null_mut(),
457-
reserved: 0,
458-
committed: 0,
459-
used: 0,
460-
block_size: 0,
461-
}
462-
}
463-
}
464-
465447
/// Visitor function passed to [`mi_heap_visit_blocks`]
466448
///
467449
/// Should return `true` to continue, and `false` to stop visiting (i.e. break)
468450
///
469451
/// This function is always first called for every `area` with `block` as a null
470452
/// pointer. If `visit_all_blocks` was `true`, the function is then called for
471453
/// every allocated block in that area.
472-
pub type mi_block_visit_fun = unsafe extern "C" fn(
473-
heap: *const mi_heap_t,
474-
area: *const mi_heap_area_t,
475-
block: *mut c_void,
476-
block_size: usize,
477-
arg: *mut c_void,
478-
) -> bool;
454+
pub type mi_block_visit_fun = Option<
455+
unsafe extern "C" fn(
456+
heap: *const mi_heap_t,
457+
area: *const mi_heap_area_t,
458+
block: *mut c_void,
459+
block_size: usize,
460+
arg: *mut c_void,
461+
) -> bool,
462+
>;
479463

480464
extern "C" {
481465
/// Create a new heap that can be used for allocation.
@@ -517,7 +501,7 @@ extern "C" {
517501

518502
/// Release outstanding resources in a specific heap.
519503
///
520-
/// Similar to to [`mi_collect`], but takes the heap to collect as an argument.
504+
/// See also [`mi_collect`].
521505
pub fn mi_heap_collect(heap: *mut mi_heap_t, force: bool);
522506

523507
/// Equivalent to [`mi_malloc`](crate::mi_malloc), but allocates out of the
@@ -689,6 +673,8 @@ extern "C" {
689673
/// `arg` is an extra argument passed into the `visitor`.
690674
///
691675
/// Returns `true` if all areas and blocks were visited.
676+
///
677+
/// Passing a `None` visitor is allowed, and is a no-op.
692678
pub fn mi_heap_visit_blocks(
693679
heap: *const mi_heap_t,
694680
visit_all_blocks: bool,

libmimalloc-sys/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ extern "C" {
6565

6666
/// Return the available bytes in a memory block.
6767
///
68-
/// The returned size can be used to call [`mi_expand`] successfully.
69-
pub fn mi_usable_size(p: *mut c_void) -> usize;
68+
/// The returned size can be used to call `mi_expand` successfully.
69+
pub fn mi_usable_size(p: *const c_void) -> usize;
7070
}
7171

7272
#[cfg(test)]

libmimalloc-sys/sys-test/Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "libmimalloc-sys-test"
3+
version = "0.1.0"
4+
authors = ["Thom Chiovoloni <tchiovoloni@mozilla.com>"]
5+
edition = "2018"
6+
description = "Bindings test for libmimalloc-sys"
7+
license = "MIT"
8+
publish = false
9+
10+
[dependencies]
11+
libmimalloc-sys = { path = "..", features = ["extended"] }
12+
libc = "0.2"
13+
14+
[build-dependencies]
15+
ctest = "0.2"

libmimalloc-sys/sys-test/build.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
fn main() {
2+
let mut cfg = ctest::TestGenerator::new();
3+
cfg.header("mimalloc.h")
4+
.include(concat!(
5+
env!("CARGO_MANIFEST_DIR"),
6+
"/../c_src/mimalloc/include"
7+
))
8+
.cfg("feature", Some("extended"))
9+
.fn_cname(|rust, link_name| link_name.unwrap_or(rust).to_string())
10+
// ignore whether or not the option enum is signed.
11+
.skip_signededness(|c| c.ends_with("_t") || c.ends_with("_e"))
12+
.type_name(|ty, _is_struct, _is_union| {
13+
match ty {
14+
// Special cases. We do this to avoid having both
15+
// `mi_blah_{s,e}` and `mi_blah_t`.
16+
"mi_heap_area_t" => "struct mi_heap_area_s".into(),
17+
"mi_heap_t" => "struct mi_heap_s".into(),
18+
"mi_options_t" => "enum mi_options_e".into(),
19+
20+
// This also works but requires we export `mi_heap_s` and similar
21+
// in addition, so we just hardcode the above.
22+
23+
// t if t.ends_with("_s") => format!("struct {}", t),
24+
// t if t.ends_with("_e") => format!("enum {}", t),
25+
// t if t.ends_with("_t") => t.to_string(),
26+
27+
// mimalloc defines it's callbacks with the pointer at the
28+
// location of use, e.g. `typedef ret mi_some_fun(a0 x, a1 y);`
29+
// and then uses `mi_some_fun *arg` as argument types, which
30+
// appears to upset ctest, which would prefer function pointers
31+
// be declared as pointers, so we clean things up for it.
32+
t if t.ends_with("_fun") => format!("{}*", t),
33+
34+
t => t.to_string(),
35+
}
36+
});
37+
38+
cfg.generate("../src/lib.rs", "all.rs");
39+
}

libmimalloc-sys/sys-test/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![allow(bad_style, clippy::all)]
2+
3+
use libmimalloc_sys::*;
4+
5+
include!(concat!(env!("OUT_DIR"), "/all.rs"));

0 commit comments

Comments
 (0)