1 //! Atomic intrinsics are implemented using a global lock for now, as Cranelift doesn't support
2 //! atomic operations yet.
4 // FIXME implement atomic instructions in Cranelift.
8 #[cfg(feature = "jit")]
10 pub static mut __cg_clif_global_atomic_mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER;
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.
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",
29 module.define_data(atomic_mutex, &data_ctx).unwrap();
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,
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 */),
37 returns: vec![AbiParam::new(types::I32 /* c_int */)],
40 let pthread_mutex_init = module.declare_func_in_func(pthread_mutex_init, bcx.func);
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);
45 let nullptr = bcx.ins().iconst(module.target_config().pointer_type(), 0);
47 bcx.ins().call(pthread_mutex_init, &[atomic_mutex, nullptr]);
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",
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,
62 AbiParam::new(fx.module.target_config().pointer_type() /* *mut pthread_mutex_t */),
64 returns: vec![AbiParam::new(types::I32 /* c_int */)],
67 let pthread_mutex_lock = fx.module.declare_func_in_func(pthread_mutex_lock, fx.bcx.func);
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);
72 fx.bcx.ins().call(pthread_mutex_lock, &[atomic_mutex]);
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",
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,
87 AbiParam::new(fx.module.target_config().pointer_type() /* *mut pthread_mutex_t */),
89 returns: vec![AbiParam::new(types::I32 /* c_int */)],
92 let pthread_mutex_unlock = fx.module.declare_func_in_func(pthread_mutex_unlock, fx.bcx.func);
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);
97 fx.bcx.ins().call(pthread_mutex_unlock, &[atomic_mutex]);