]> git.lizzy.rs Git - rust.git/blob - src/atomic_shim.rs
Add a feature flag for the JIT
[rust.git] / src / atomic_shim.rs
1 //! Atomic intrinsics are implemented using a global lock for now, as Cranelift doesn't support
2 //! atomic operations yet.
3
4 // FIXME implement atomic instructions in Cranelift.
5
6 use crate::prelude::*;
7
8 #[cfg(feature = "jit")]
9 #[no_mangle]
10 pub static mut __cg_clif_global_atomic_mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER;
11
12 pub(crate) fn init_global_lock(module: &mut Module<impl Backend>, bcx: &mut FunctionBuilder<'_>) {
13     if std::env::var("CG_CLIF_JIT").is_ok () {
14         // When using JIT, dylibs won't find the __cg_clif_global_atomic_mutex data object defined here,
15         // so instead define it in the cg_clif dylib.
16
17         return;
18     }
19
20     let mut data_ctx = DataContext::new();
21     data_ctx.define_zeroinit(1024); // 1024 bytes should be big enough on all platforms.
22     let atomic_mutex = module.declare_data(
23         "__cg_clif_global_atomic_mutex",
24         Linkage::Export,
25         true,
26         false,
27         Some(16),
28     ).unwrap();
29     module.define_data(atomic_mutex, &data_ctx).unwrap();
30
31     let pthread_mutex_init = module.declare_function("pthread_mutex_init", Linkage::Import, &cranelift_codegen::ir::Signature {
32         call_conv: module.target_config().default_call_conv,
33         params: vec![
34             AbiParam::new(module.target_config().pointer_type() /* *mut pthread_mutex_t */),
35             AbiParam::new(module.target_config().pointer_type() /* *const pthread_mutex_attr_t */),
36         ],
37         returns: vec![AbiParam::new(types::I32 /* c_int */)],
38     }).unwrap();
39
40     let pthread_mutex_init = module.declare_func_in_func(pthread_mutex_init, bcx.func);
41
42     let atomic_mutex = module.declare_data_in_func(atomic_mutex, bcx.func);
43     let atomic_mutex = bcx.ins().global_value(module.target_config().pointer_type(), atomic_mutex);
44
45     let nullptr = bcx.ins().iconst(module.target_config().pointer_type(), 0);
46
47     bcx.ins().call(pthread_mutex_init, &[atomic_mutex, nullptr]);
48 }
49
50 pub(crate) fn lock_global_lock(fx: &mut FunctionCx<'_, '_, impl Backend>) {
51     let atomic_mutex = fx.module.declare_data(
52         "__cg_clif_global_atomic_mutex",
53         Linkage::Import,
54         true,
55         false,
56         None,
57     ).unwrap();
58
59     let pthread_mutex_lock = fx.module.declare_function("pthread_mutex_lock", Linkage::Import, &cranelift_codegen::ir::Signature {
60         call_conv: fx.module.target_config().default_call_conv,
61         params: vec![
62             AbiParam::new(fx.module.target_config().pointer_type() /* *mut pthread_mutex_t */),
63         ],
64         returns: vec![AbiParam::new(types::I32 /* c_int */)],
65     }).unwrap();
66
67     let pthread_mutex_lock = fx.module.declare_func_in_func(pthread_mutex_lock, fx.bcx.func);
68
69     let atomic_mutex = fx.module.declare_data_in_func(atomic_mutex, fx.bcx.func);
70     let atomic_mutex = fx.bcx.ins().global_value(fx.module.target_config().pointer_type(), atomic_mutex);
71
72     fx.bcx.ins().call(pthread_mutex_lock, &[atomic_mutex]);
73 }
74
75 pub(crate) fn unlock_global_lock(fx: &mut FunctionCx<'_, '_, impl Backend>) {
76     let atomic_mutex = fx.module.declare_data(
77         "__cg_clif_global_atomic_mutex",
78         Linkage::Import,
79         true,
80         false,
81         None,
82     ).unwrap();
83
84     let pthread_mutex_unlock = fx.module.declare_function("pthread_mutex_unlock", Linkage::Import, &cranelift_codegen::ir::Signature {
85         call_conv: fx.module.target_config().default_call_conv,
86         params: vec![
87             AbiParam::new(fx.module.target_config().pointer_type() /* *mut pthread_mutex_t */),
88         ],
89         returns: vec![AbiParam::new(types::I32 /* c_int */)],
90     }).unwrap();
91
92     let pthread_mutex_unlock = fx.module.declare_func_in_func(pthread_mutex_unlock, fx.bcx.func);
93
94     let atomic_mutex = fx.module.declare_data_in_func(atomic_mutex, fx.bcx.func);
95     let atomic_mutex = fx.bcx.ins().global_value(fx.module.target_config().pointer_type(), atomic_mutex);
96
97     fx.bcx.ins().call(pthread_mutex_unlock, &[atomic_mutex]);
98 }