/src/cpython/Objects/mimalloc/prim/prim.c
Line | Count | Source |
1 | | /* ---------------------------------------------------------------------------- |
2 | | Copyright (c) 2018-2023, Microsoft Research, Daan Leijen |
3 | | This is free software; you can redistribute it and/or modify it under the |
4 | | terms of the MIT license. A copy of the license can be found in the file |
5 | | "LICENSE" at the root of this distribution. |
6 | | -----------------------------------------------------------------------------*/ |
7 | | |
8 | | // Select the implementation of the primitives |
9 | | // depending on the OS. |
10 | | |
11 | | #if defined(_WIN32) |
12 | | #include "windows/prim.c" // VirtualAlloc (Windows) |
13 | | |
14 | | #elif defined(__APPLE__) |
15 | | #include "osx/prim.c" // macOSX (actually defers to mmap in unix/prim.c) |
16 | | |
17 | | #elif defined(__wasi__) |
18 | | #define MI_USE_SBRK |
19 | | #include "wasi/prim.c" // memory-grow or sbrk (Wasm) |
20 | | |
21 | | // CPython: use the unix prim on Emscripten (emmalloc is not linked) |
22 | | #elif defined(__EMSCRIPTEN__) && 0 |
23 | | #include "emscripten/prim.c" // emmalloc_*, + pthread support |
24 | | |
25 | | #else |
26 | | #include "unix/prim.c" // mmap() (Linux, macOSX, BSD, Illumnos, Haiku, DragonFly, etc.) |
27 | | |
28 | | #endif |
29 | | |
30 | | // Generic process initialization |
31 | | #ifndef MI_PRIM_HAS_PROCESS_ATTACH |
32 | | #if defined(__GNUC__) || defined(__clang__) |
33 | | // gcc,clang: use the constructor/destructor attribute |
34 | | // which for both seem to run before regular constructors/destructors |
35 | | #if defined(__clang__) |
36 | | #define mi_attr_constructor __attribute__((constructor(101))) |
37 | | #define mi_attr_destructor __attribute__((destructor(101))) |
38 | | #else |
39 | | #define mi_attr_constructor __attribute__((constructor)) |
40 | | #define mi_attr_destructor __attribute__((destructor)) |
41 | | #endif |
42 | 37 | static void mi_attr_constructor mi_process_attach(void) { |
43 | 37 | _mi_auto_process_init(); |
44 | 37 | } |
45 | 0 | static void mi_attr_destructor mi_process_detach(void) { |
46 | 0 | _mi_auto_process_done(); |
47 | 0 | } |
48 | | #elif defined(__cplusplus) |
49 | | // C++: use static initialization to detect process start/end |
50 | | // This is not guaranteed to be first/last but the best we can generally do? |
51 | | struct mi_init_done_t { |
52 | | mi_init_done_t() { |
53 | | _mi_auto_process_init(); |
54 | | } |
55 | | ~mi_init_done_t() { |
56 | | _mi_auto_process_done(); |
57 | | } |
58 | | }; |
59 | | static mi_init_done_t mi_init_done; |
60 | | #else |
61 | | #pragma message("define a way to call _mi_auto_process_init/done on your platform") |
62 | | #endif |
63 | | #endif |
64 | | |
65 | | // Generic allocator init/done callback |
66 | | #ifndef MI_PRIM_HAS_ALLOCATOR_INIT |
67 | 37 | bool _mi_is_redirected(void) { |
68 | 37 | return false; |
69 | 37 | } |
70 | 37 | bool _mi_allocator_init(const char** message) { |
71 | 37 | if (message != NULL) { *message = NULL; } |
72 | 37 | return true; |
73 | 37 | } |
74 | 0 | void _mi_allocator_done(void) { |
75 | | // nothing to do |
76 | 0 | } |
77 | | #endif |