1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![no_std]

extern crate libc;

use libc::{c_int, c_void, size_t, c_char};

pub const MALLOCX_ZERO: c_int = 0x40;

extern "C" {
    // Standard API
    #[cfg_attr(prefixed, link_name = "_rjem_malloc")]
    pub fn malloc(size: size_t) -> *mut c_void;
    #[cfg_attr(prefixed, link_name = "_rjem_calloc")]
    pub fn calloc(number: size_t, size: size_t) -> *mut c_void;
    #[cfg_attr(prefixed, link_name = "_rjem_posix_memalign")]
    pub fn posix_memalign(ptr: *mut *mut c_void, alignment: size_t, size: size_t) -> c_int;
    #[cfg_attr(prefixed, link_name = "_rjem_aligned_alloc")]
    pub fn aligned_alloc(alignment: size_t, size: size_t) -> *mut c_void;
    #[cfg_attr(prefixed, link_name = "_rjem_realloc")]
    pub fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void;
    #[cfg_attr(prefixed, link_name = "_rjem_free")]
    pub fn free(ptr: *mut c_void);

    // Non-standard API
    #[cfg_attr(prefixed, link_name = "_rjem_mallocx")]
    pub fn mallocx(size: size_t, flags: c_int) -> *mut c_void;
    #[cfg_attr(prefixed, link_name = "_rjem_rallocx")]
    pub fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
    #[cfg_attr(prefixed, link_name = "_rjem_xallocx")]
    pub fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
    #[cfg_attr(prefixed, link_name = "_rjem_sallocx")]
    pub fn sallocx(ptr: *const c_void, flags: c_int) -> size_t;
    #[cfg_attr(prefixed, link_name = "_rjem_dallocx")]
    pub fn dallocx(ptr: *mut c_void, flags: c_int);
    #[cfg_attr(prefixed, link_name = "_rjem_sdallocx")]
    pub fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
    #[cfg_attr(prefixed, link_name = "_rjem_nallocx")]
    pub fn nallocx(size: size_t, flags: c_int) -> size_t;
    #[cfg_attr(prefixed, link_name = "_rjem_malloc_usable_size")]
    pub fn malloc_usable_size(ptr: *const c_void) -> size_t;

    // mallctl
    #[cfg_attr(prefixed, link_name = "_rjem_mallctl")]
    pub fn mallctl(name: *const c_char,
                   oldp: *mut c_void,
                   oldpenp: *mut size_t,
                   newp: *mut c_void,
                   newlen: size_t)
                   -> c_int;
    #[cfg_attr(prefixed, link_name = "_rjem_mallctlnametomib")]
    pub fn mallctlnametomib(name: *const c_char, mibp: *mut size_t, miblenp: *mut size_t) -> c_int;
    #[cfg_attr(prefixed, link_name = "_rjem_mallctlbymib")]
    pub fn mallctlbymib(mib: *const size_t,
                        miblen: size_t,
                        oldp: *mut c_void,
                        oldpenp: *mut size_t,
                        newp: *mut c_void,
                        newlen: size_t)
                        -> c_int;

    // stats
    #[cfg_attr(prefixed, link_name = "_rjem_malloc_stats_print")]
    pub fn malloc_stats_print(write_cb: extern "C" fn(*mut c_void, *const c_char),
                              cbopaque: *mut c_void,
                              opts: *const c_char);
}

// These symbols are used by jemalloc on android but the really old android
// we're building on doesn't have them defined, so just make sure the symbols
// are available.
#[no_mangle]
#[cfg(target_os = "android")]
#[doc(hidden)]
pub extern "C" fn pthread_atfork(_prefork: *mut u8,
                                 _postfork_parent: *mut u8,
                                 _postfork_child: *mut u8)
                                 -> i32 {
    0
}

/// Computes `flags` from `align`.
///
/// Equivalent to the MALLOCX_ALIGN(a) macro.
#[inline]
#[allow(non_snake_case)]
pub fn MALLOCX_ALIGN(aling: usize) -> c_int {
    aling.trailing_zeros() as c_int
}