Skip to content

Instantly share code, notes, and snippets.

@pacmancoder
Last active December 25, 2019 13:43
Show Gist options
  • Save pacmancoder/70788fc112b582f71f885e2c3104c0ab to your computer and use it in GitHub Desktop.
Save pacmancoder/70788fc112b582f71f885e2c3104c0ab to your computer and use it in GitHub Desktop.
Rust-Xtensa atomics support workarround

USE ON YOUR OWN RISK

WARNING

  • Files, lsited in this gist are generated (except generation script itself)
  • Tested only partially
  • GCC compiller from Xtensa toolchain is required to make this code work.
    • Or instead you can generate static library with the GCC once and link it to the rust code
// THIS FILE IS GENERATED; PLEASE DO NOT CHANGE!
#include <stdint.h>
int8_t rust_xtensa__sync_fetch_and_add_1(int8_t* ptr, int8_t arg) {
return __sync_fetch_and_add_1(ptr, arg);
}
int8_t rust_xtensa__sync_fetch_and_sub_1(int8_t* ptr, int8_t arg) {
return __sync_fetch_and_sub_1(ptr, arg);
}
int8_t rust_xtensa__sync_fetch_and_or_1(int8_t* ptr, int8_t arg) {
return __sync_fetch_and_or_1(ptr, arg);
}
int8_t rust_xtensa__sync_fetch_and_and_1(int8_t* ptr, int8_t arg) {
return __sync_fetch_and_and_1(ptr, arg);
}
int8_t rust_xtensa__sync_fetch_and_xor_1(int8_t* ptr, int8_t arg) {
return __sync_fetch_and_xor_1(ptr, arg);
}
int8_t rust_xtensa__sync_fetch_and_nand_1(int8_t* ptr, int8_t arg) {
return __sync_fetch_and_nand_1(ptr, arg);
}
int8_t rust_xtensa__sync_add_and_fetch_1(int8_t* ptr, int8_t arg) {
return __sync_add_and_fetch_1(ptr, arg);
}
int8_t rust_xtensa__sync_sub_and_fetch_1(int8_t* ptr, int8_t arg) {
return __sync_sub_and_fetch_1(ptr, arg);
}
int8_t rust_xtensa__sync_or_and_fetch_1(int8_t* ptr, int8_t arg) {
return __sync_or_and_fetch_1(ptr, arg);
}
int8_t rust_xtensa__sync_and_and_fetch_1(int8_t* ptr, int8_t arg) {
return __sync_and_and_fetch_1(ptr, arg);
}
int8_t rust_xtensa__sync_xor_and_fetch_1(int8_t* ptr, int8_t arg) {
return __sync_xor_and_fetch_1(ptr, arg);
}
int8_t rust_xtensa__sync_nand_and_fetch_1(int8_t* ptr, int8_t arg) {
return __sync_nand_and_fetch_1(ptr, arg);
}
int8_t rust_xtensa__sync_lock_test_and_set_1(int8_t* ptr, int8_t arg) {
return __sync_lock_test_and_set_1(ptr, arg);
}
int8_t rust_xtensa__sync_val_compare_and_swap_1(int8_t* ptr, int8_t old, int8_t new) {
return __sync_val_compare_and_swap_1(ptr, old, new);
}
_Bool rust_xtensa__sync_bool_compare_and_swap_1(int8_t* ptr, int8_t old, int8_t new) {
return __sync_bool_compare_and_swap_1(ptr, old, new);
}
int16_t rust_xtensa__sync_fetch_and_add_2(int16_t* ptr, int16_t arg) {
return __sync_fetch_and_add_2(ptr, arg);
}
int16_t rust_xtensa__sync_fetch_and_sub_2(int16_t* ptr, int16_t arg) {
return __sync_fetch_and_sub_2(ptr, arg);
}
int16_t rust_xtensa__sync_fetch_and_or_2(int16_t* ptr, int16_t arg) {
return __sync_fetch_and_or_2(ptr, arg);
}
int16_t rust_xtensa__sync_fetch_and_and_2(int16_t* ptr, int16_t arg) {
return __sync_fetch_and_and_2(ptr, arg);
}
int16_t rust_xtensa__sync_fetch_and_xor_2(int16_t* ptr, int16_t arg) {
return __sync_fetch_and_xor_2(ptr, arg);
}
int16_t rust_xtensa__sync_fetch_and_nand_2(int16_t* ptr, int16_t arg) {
return __sync_fetch_and_nand_2(ptr, arg);
}
int16_t rust_xtensa__sync_add_and_fetch_2(int16_t* ptr, int16_t arg) {
return __sync_add_and_fetch_2(ptr, arg);
}
int16_t rust_xtensa__sync_sub_and_fetch_2(int16_t* ptr, int16_t arg) {
return __sync_sub_and_fetch_2(ptr, arg);
}
int16_t rust_xtensa__sync_or_and_fetch_2(int16_t* ptr, int16_t arg) {
return __sync_or_and_fetch_2(ptr, arg);
}
int16_t rust_xtensa__sync_and_and_fetch_2(int16_t* ptr, int16_t arg) {
return __sync_and_and_fetch_2(ptr, arg);
}
int16_t rust_xtensa__sync_xor_and_fetch_2(int16_t* ptr, int16_t arg) {
return __sync_xor_and_fetch_2(ptr, arg);
}
int16_t rust_xtensa__sync_nand_and_fetch_2(int16_t* ptr, int16_t arg) {
return __sync_nand_and_fetch_2(ptr, arg);
}
int16_t rust_xtensa__sync_lock_test_and_set_2(int16_t* ptr, int16_t arg) {
return __sync_lock_test_and_set_2(ptr, arg);
}
int16_t rust_xtensa__sync_val_compare_and_swap_2(int16_t* ptr, int16_t old, int16_t new) {
return __sync_val_compare_and_swap_2(ptr, old, new);
}
_Bool rust_xtensa__sync_bool_compare_and_swap_2(int16_t* ptr, int16_t old, int16_t new) {
return __sync_bool_compare_and_swap_2(ptr, old, new);
}
int32_t rust_xtensa__sync_fetch_and_add_4(int32_t* ptr, int32_t arg) {
return __sync_fetch_and_add_4(ptr, arg);
}
int32_t rust_xtensa__sync_fetch_and_sub_4(int32_t* ptr, int32_t arg) {
return __sync_fetch_and_sub_4(ptr, arg);
}
int32_t rust_xtensa__sync_fetch_and_or_4(int32_t* ptr, int32_t arg) {
return __sync_fetch_and_or_4(ptr, arg);
}
int32_t rust_xtensa__sync_fetch_and_and_4(int32_t* ptr, int32_t arg) {
return __sync_fetch_and_and_4(ptr, arg);
}
int32_t rust_xtensa__sync_fetch_and_xor_4(int32_t* ptr, int32_t arg) {
return __sync_fetch_and_xor_4(ptr, arg);
}
int32_t rust_xtensa__sync_fetch_and_nand_4(int32_t* ptr, int32_t arg) {
return __sync_fetch_and_nand_4(ptr, arg);
}
int32_t rust_xtensa__sync_add_and_fetch_4(int32_t* ptr, int32_t arg) {
return __sync_add_and_fetch_4(ptr, arg);
}
int32_t rust_xtensa__sync_sub_and_fetch_4(int32_t* ptr, int32_t arg) {
return __sync_sub_and_fetch_4(ptr, arg);
}
int32_t rust_xtensa__sync_or_and_fetch_4(int32_t* ptr, int32_t arg) {
return __sync_or_and_fetch_4(ptr, arg);
}
int32_t rust_xtensa__sync_and_and_fetch_4(int32_t* ptr, int32_t arg) {
return __sync_and_and_fetch_4(ptr, arg);
}
int32_t rust_xtensa__sync_xor_and_fetch_4(int32_t* ptr, int32_t arg) {
return __sync_xor_and_fetch_4(ptr, arg);
}
int32_t rust_xtensa__sync_nand_and_fetch_4(int32_t* ptr, int32_t arg) {
return __sync_nand_and_fetch_4(ptr, arg);
}
int32_t rust_xtensa__sync_lock_test_and_set_4(int32_t* ptr, int32_t arg) {
return __sync_lock_test_and_set_4(ptr, arg);
}
int32_t rust_xtensa__sync_val_compare_and_swap_4(int32_t* ptr, int32_t old, int32_t new) {
return __sync_val_compare_and_swap_4(ptr, old, new);
}
_Bool rust_xtensa__sync_bool_compare_and_swap_4(int32_t* ptr, int32_t old, int32_t new) {
return __sync_bool_compare_and_swap_4(ptr, old, new);
}
int64_t rust_xtensa__sync_fetch_and_add_8(int64_t* ptr, int64_t arg) {
return __sync_fetch_and_add_8(ptr, arg);
}
int64_t rust_xtensa__sync_fetch_and_sub_8(int64_t* ptr, int64_t arg) {
return __sync_fetch_and_sub_8(ptr, arg);
}
int64_t rust_xtensa__sync_fetch_and_or_8(int64_t* ptr, int64_t arg) {
return __sync_fetch_and_or_8(ptr, arg);
}
int64_t rust_xtensa__sync_fetch_and_and_8(int64_t* ptr, int64_t arg) {
return __sync_fetch_and_and_8(ptr, arg);
}
int64_t rust_xtensa__sync_fetch_and_xor_8(int64_t* ptr, int64_t arg) {
return __sync_fetch_and_xor_8(ptr, arg);
}
int64_t rust_xtensa__sync_fetch_and_nand_8(int64_t* ptr, int64_t arg) {
return __sync_fetch_and_nand_8(ptr, arg);
}
int64_t rust_xtensa__sync_add_and_fetch_8(int64_t* ptr, int64_t arg) {
return __sync_add_and_fetch_8(ptr, arg);
}
int64_t rust_xtensa__sync_sub_and_fetch_8(int64_t* ptr, int64_t arg) {
return __sync_sub_and_fetch_8(ptr, arg);
}
int64_t rust_xtensa__sync_or_and_fetch_8(int64_t* ptr, int64_t arg) {
return __sync_or_and_fetch_8(ptr, arg);
}
int64_t rust_xtensa__sync_and_and_fetch_8(int64_t* ptr, int64_t arg) {
return __sync_and_and_fetch_8(ptr, arg);
}
int64_t rust_xtensa__sync_xor_and_fetch_8(int64_t* ptr, int64_t arg) {
return __sync_xor_and_fetch_8(ptr, arg);
}
int64_t rust_xtensa__sync_nand_and_fetch_8(int64_t* ptr, int64_t arg) {
return __sync_nand_and_fetch_8(ptr, arg);
}
int64_t rust_xtensa__sync_lock_test_and_set_8(int64_t* ptr, int64_t arg) {
return __sync_lock_test_and_set_8(ptr, arg);
}
int64_t rust_xtensa__sync_val_compare_and_swap_8(int64_t* ptr, int64_t old, int64_t new) {
return __sync_val_compare_and_swap_8(ptr, old, new);
}
_Bool rust_xtensa__sync_bool_compare_and_swap_8(int64_t* ptr, int64_t old, int64_t new) {
return __sync_bool_compare_and_swap_8(ptr, old, new);
}
// THIS FILE IS GENERATED; PLEASE DO NOT CHANGE!
#![allow(non_snake_case)]
extern "C" { fn rust_xtensa__sync_fetch_and_add_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_fetch_and_add_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_fetch_and_add_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_sub_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_fetch_and_sub_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_fetch_and_sub_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_or_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_fetch_and_or_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_fetch_and_or_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_and_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_fetch_and_and_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_fetch_and_and_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_xor_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_fetch_and_xor_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_fetch_and_xor_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_nand_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_fetch_and_nand_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_fetch_and_nand_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_add_and_fetch_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_add_and_fetch_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_add_and_fetch_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_sub_and_fetch_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_sub_and_fetch_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_sub_and_fetch_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_or_and_fetch_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_or_and_fetch_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_or_and_fetch_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_and_and_fetch_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_and_and_fetch_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_and_and_fetch_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_xor_and_fetch_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_xor_and_fetch_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_xor_and_fetch_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_nand_and_fetch_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_nand_and_fetch_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_nand_and_fetch_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_lock_test_and_set_1(ptr: *mut i8, arg: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_lock_test_and_set_1(ptr: *mut i8, arg: i8) -> i8 {
rust_xtensa__sync_lock_test_and_set_1(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_val_compare_and_swap_1(ptr: *mut i8, old: i8, new: i8) -> i8; }
#[no_mangle]
unsafe fn __sync_val_compare_and_swap_1(ptr: *mut i8, old: i8, new: i8) -> i8 {
rust_xtensa__sync_val_compare_and_swap_1(ptr, old, new)
}
extern "C" { fn rust_xtensa__sync_bool_compare_and_swap_1(ptr: *mut i8, old: i8, new: i8) -> bool; }
#[no_mangle]
unsafe fn __sync_bool_compare_and_swap_1(ptr: *mut i8, old: i8, new: i8) -> bool {
rust_xtensa__sync_bool_compare_and_swap_1(ptr, old, new)
}
extern "C" { fn rust_xtensa__sync_fetch_and_add_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_fetch_and_add_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_fetch_and_add_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_sub_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_fetch_and_sub_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_fetch_and_sub_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_or_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_fetch_and_or_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_fetch_and_or_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_and_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_fetch_and_and_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_fetch_and_and_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_xor_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_fetch_and_xor_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_fetch_and_xor_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_nand_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_fetch_and_nand_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_fetch_and_nand_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_add_and_fetch_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_add_and_fetch_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_add_and_fetch_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_sub_and_fetch_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_sub_and_fetch_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_sub_and_fetch_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_or_and_fetch_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_or_and_fetch_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_or_and_fetch_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_and_and_fetch_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_and_and_fetch_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_and_and_fetch_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_xor_and_fetch_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_xor_and_fetch_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_xor_and_fetch_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_nand_and_fetch_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_nand_and_fetch_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_nand_and_fetch_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_lock_test_and_set_2(ptr: *mut i16, arg: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_lock_test_and_set_2(ptr: *mut i16, arg: i16) -> i16 {
rust_xtensa__sync_lock_test_and_set_2(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_val_compare_and_swap_2(ptr: *mut i16, old: i16, new: i16) -> i16; }
#[no_mangle]
unsafe fn __sync_val_compare_and_swap_2(ptr: *mut i16, old: i16, new: i16) -> i16 {
rust_xtensa__sync_val_compare_and_swap_2(ptr, old, new)
}
extern "C" { fn rust_xtensa__sync_bool_compare_and_swap_2(ptr: *mut i16, old: i16, new: i16) -> bool; }
#[no_mangle]
unsafe fn __sync_bool_compare_and_swap_2(ptr: *mut i16, old: i16, new: i16) -> bool {
rust_xtensa__sync_bool_compare_and_swap_2(ptr, old, new)
}
extern "C" { fn rust_xtensa__sync_fetch_and_add_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_fetch_and_add_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_fetch_and_add_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_sub_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_fetch_and_sub_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_fetch_and_sub_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_or_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_fetch_and_or_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_fetch_and_or_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_and_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_fetch_and_and_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_fetch_and_and_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_xor_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_fetch_and_xor_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_fetch_and_xor_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_nand_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_fetch_and_nand_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_fetch_and_nand_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_add_and_fetch_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_add_and_fetch_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_add_and_fetch_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_sub_and_fetch_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_sub_and_fetch_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_sub_and_fetch_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_or_and_fetch_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_or_and_fetch_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_or_and_fetch_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_and_and_fetch_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_and_and_fetch_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_and_and_fetch_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_xor_and_fetch_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_xor_and_fetch_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_xor_and_fetch_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_nand_and_fetch_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_nand_and_fetch_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_nand_and_fetch_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_lock_test_and_set_4(ptr: *mut i32, arg: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_lock_test_and_set_4(ptr: *mut i32, arg: i32) -> i32 {
rust_xtensa__sync_lock_test_and_set_4(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_val_compare_and_swap_4(ptr: *mut i32, old: i32, new: i32) -> i32; }
#[no_mangle]
unsafe fn __sync_val_compare_and_swap_4(ptr: *mut i32, old: i32, new: i32) -> i32 {
rust_xtensa__sync_val_compare_and_swap_4(ptr, old, new)
}
extern "C" { fn rust_xtensa__sync_bool_compare_and_swap_4(ptr: *mut i32, old: i32, new: i32) -> bool; }
#[no_mangle]
unsafe fn __sync_bool_compare_and_swap_4(ptr: *mut i32, old: i32, new: i32) -> bool {
rust_xtensa__sync_bool_compare_and_swap_4(ptr, old, new)
}
extern "C" { fn rust_xtensa__sync_fetch_and_add_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_fetch_and_add_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_fetch_and_add_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_sub_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_fetch_and_sub_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_fetch_and_sub_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_or_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_fetch_and_or_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_fetch_and_or_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_and_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_fetch_and_and_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_fetch_and_and_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_xor_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_fetch_and_xor_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_fetch_and_xor_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_fetch_and_nand_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_fetch_and_nand_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_fetch_and_nand_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_add_and_fetch_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_add_and_fetch_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_add_and_fetch_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_sub_and_fetch_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_sub_and_fetch_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_sub_and_fetch_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_or_and_fetch_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_or_and_fetch_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_or_and_fetch_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_and_and_fetch_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_and_and_fetch_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_and_and_fetch_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_xor_and_fetch_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_xor_and_fetch_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_xor_and_fetch_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_nand_and_fetch_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_nand_and_fetch_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_nand_and_fetch_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_lock_test_and_set_8(ptr: *mut i64, arg: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_lock_test_and_set_8(ptr: *mut i64, arg: i64) -> i64 {
rust_xtensa__sync_lock_test_and_set_8(ptr, arg)
}
extern "C" { fn rust_xtensa__sync_val_compare_and_swap_8(ptr: *mut i64, old: i64, new: i64) -> i64; }
#[no_mangle]
unsafe fn __sync_val_compare_and_swap_8(ptr: *mut i64, old: i64, new: i64) -> i64 {
rust_xtensa__sync_val_compare_and_swap_8(ptr, old, new)
}
extern "C" { fn rust_xtensa__sync_bool_compare_and_swap_8(ptr: *mut i64, old: i64, new: i64) -> bool; }
#[no_mangle]
unsafe fn __sync_bool_compare_and_swap_8(ptr: *mut i64, old: i64, new: i64) -> bool {
rust_xtensa__sync_bool_compare_and_swap_8(ptr, old, new)
}
# How to use this script:
# 1) `$ python3 generate_atomic.shim.py`
# - Generate with default params:
# - Generated C file Path: atomic_shim.c
# - Generated Rust file Path: atomic_shim.rs
# - Proxy functions prefix: rust_xtensa
# 2) `$ python3 generate_atomic.shim.py <C file path> <Rust file path>`
# 3) `$ python3 generate_atomic.shim.py <C file path> <Rust file path> <Proxy functions prefix>`
import sys
DEFAULT_C_FILE_PATH = "atomic_shim.c"
DEFAULT_RUST_FILE_PATH = "atomic_shim.rs"
DEFAULT_FN_PREFIX = "rust_xtensa"
HEADER_COMMENT = "// THIS FILE IS GENERATED; PLEASE DO NOT CHANGE!\n"
OPERATION_FETCH_FUNCTIONS = [
"__sync_fetch_and_add",
"__sync_fetch_and_sub",
"__sync_fetch_and_or",
"__sync_fetch_and_and",
"__sync_fetch_and_xor",
"__sync_fetch_and_nand",
"__sync_add_and_fetch",
"__sync_sub_and_fetch",
"__sync_or_and_fetch",
"__sync_and_and_fetch",
"__sync_xor_and_fetch",
"__sync_nand_and_fetch",
# Does not hold any operation, but signature is same
"__sync_lock_test_and_set",
]
class SyncType:
def __init__(self, size, c_type, rust_type):
self.size = size
self.c_type = c_type
self.rust_type = rust_type
SYNC_TYPES = [
SyncType(1, "int8_t", "i8"),
SyncType(2, "int16_t", "i16"),
SyncType(4, "int32_t", "i32"),
SyncType(8, "int64_t", "i64")
]
class AtomicShimGenerator:
def __init__(self, c_file_path, rust_file_path, fn_prefix):
self.c_data = ""
self.rust_data = ""
self.c_file_path = c_file_path
self.rust_file_path = rust_file_path
self.fn_prefix = fn_prefix
def __generate_c_header(self):
self.c_data += HEADER_COMMENT + "#include <stdint.h>\n\n"
def __generate_rust_header(self):
self.rust_data += HEADER_COMMENT + "#![allow(non_snake_case)]\n\n"
def __save(self):
with open(self.c_file_path, 'w') as f:
f.write(self.c_data)
with open(self.rust_file_path, 'w') as f:
f.write(self.rust_data)
def generate(self):
self.__generate_c_header()
self.__generate_rust_header()
for sync_type in SYNC_TYPES:
for func in OPERATION_FETCH_FUNCTIONS:
self.__c_generate_fetch_operation(func, sync_type.c_type, sync_type.size)
self.__rust_generate_fetch_operation(func, sync_type.rust_type, sync_type.size)
self.__c_generate_val_compare_and_swap(sync_type.c_type, sync_type.size)
self.__rust_generate_val_compare_and_swap(sync_type.rust_type, sync_type.size)
self.__c_generate_bool_compare_and_swap(sync_type.c_type, sync_type.size)
self.__rust_generate_bool_compare_and_swap(sync_type.rust_type, sync_type.size)
self.__save()
def __rust_add_extern(self, value):
self.rust_data += "extern \"C\" { " + value + " }\n\n"
def __rust_add_builtin_surrogate(self, value):
self.rust_data += "#[no_mangle]\n" + value + "\n\n"
def __rust_generate_val_compare_and_swap(self, sync_type, suffix):
FN_NAME = "__sync_val_compare_and_swap"
extern_entry = "fn {3}{0}_{2}(ptr: *mut {1}, old: {1}, new: {1}) -> {1};"\
.format(FN_NAME, sync_type, suffix, self.fn_prefix)
self.__rust_add_extern(extern_entry)
builtin_surrogate = ("unsafe fn {0}_{2}(ptr: *mut {1}, old: {1}, new: {1}) -> {1} {{\n"
+ " {3}{0}_{2}(ptr, old, new)\n"
+ "}}").format(FN_NAME, sync_type, suffix, self.fn_prefix)
self.__rust_add_builtin_surrogate(builtin_surrogate)
def __rust_generate_bool_compare_and_swap(self, sync_type, suffix):
FN_NAME = "__sync_bool_compare_and_swap"
extern_entry = "fn {3}{0}_{2}(ptr: *mut {1}, old: {1}, new: {1}) -> bool;"\
.format(FN_NAME, sync_type, suffix, self.fn_prefix)
self.__rust_add_extern(extern_entry)
builtin_surrogate = ("unsafe fn {0}_{2}(ptr: *mut {1}, old: {1}, new: {1}) -> bool {{\n"
+ " {3}{0}_{2}(ptr, old, new)\n"
+ "}}").format(FN_NAME, sync_type, suffix, self.fn_prefix)
self.__rust_add_builtin_surrogate(builtin_surrogate)
def __rust_generate_fetch_operation(self, func, sync_type, suffix):
extern_entry = "fn {3}{0}_{2}(ptr: *mut {1}, arg: {1}) -> {1};"\
.format(func, sync_type, suffix, self.fn_prefix)
self.__rust_add_extern(extern_entry)
builtin_surrogate = ("unsafe fn {0}_{2}(ptr: *mut {1}, arg: {1}) -> {1} {{\n"
+ " {3}{0}_{2}(ptr, arg)\n"
+ "}}").format(func, sync_type, suffix, self.fn_prefix)
self.__rust_add_builtin_surrogate(builtin_surrogate)
def __c_add_builtin_proxy(self, value):
self.c_data += value + "\n\n"
def __c_generate_fetch_operation(self, func, sync_type, suffix):
builtin_proxy = ("{1} {3}{0}_{2}({1}* ptr, {1} arg) {{\n"
+ " return {0}_{2}(ptr, arg);\n"
+ "}}").format(func, sync_type, suffix, self.fn_prefix)
self.__c_add_builtin_proxy(builtin_proxy)
def __c_generate_val_compare_and_swap(self, sync_type, suffix):
FN_NAME = "__sync_val_compare_and_swap"
builtin_proxy = ("{1} {3}{0}_{2}({1}* ptr, {1} old, {1} new) {{\n"
+ " return {0}_{2}(ptr, old, new);\n"
+ "}}").format(FN_NAME, sync_type, suffix, self.fn_prefix)
self.__c_add_builtin_proxy(builtin_proxy)
def __c_generate_bool_compare_and_swap(self, sync_type, suffix):
FN_NAME = "__sync_bool_compare_and_swap"
builtin_proxy = ("_Bool {3}{0}_{2}({1}* ptr, {1} old, {1} new) {{\n"
+ " return {0}_{2}(ptr, old, new);\n"
+ "}}").format(FN_NAME, sync_type, suffix, self.fn_prefix)
self.__c_add_builtin_proxy(builtin_proxy)
def main():
c_file_path = DEFAULT_C_FILE_PATH
rust_file_path = DEFAULT_RUST_FILE_PATH
fn_prefix = DEFAULT_FN_PREFIX
if len(sys.argv) >= 3:
c_file_path = sys.argv[1]
rust_file_path = sys.argv[2]
if len(sys.argv) >= 4:
fn_prefix = sys.argv[3]
AtomicShimGenerator(c_file_path, rust_file_path, fn_prefix).generate()
main()
@pacmancoder
Copy link
Author

UPD: Performed generation script refactoring

@reitermarkus
Copy link

reitermarkus commented Dec 17, 2019

@pacmancoder, is the Rust wrapper strictly needed for some reason? I just removed the rust_xtensa prefix from all the functions, statically compiled it and linked it directly, which is working fine.

@pacmancoder
Copy link
Author

@reitermarkus, nope, I just selected arbitrary prefix which looked fine to me. Just make sure that new function names don't create any name collisions.

@pacmancoder
Copy link
Author

@reitermarkus I just have tested shim functions without prefixes and rust shim code. Can confirm now that this works correctly 👍 . Thank you, I will try to find time to update the gist code this week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment