Skip to content

Commit 8cac70d

Browse files
committed
Porting musl/arch/x86_64/atomic_arch.h to unsafe Rust.
1 parent f507e4d commit 8cac70d

File tree

5 files changed

+136
-119
lines changed

5 files changed

+136
-119
lines changed

musl/arch/x86_64/atomic_arch.h

Lines changed: 1 addition & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,2 @@
11
#define a_cas a_cas
2-
static inline int a_cas(volatile int *p, int t, int s)
3-
{
4-
__asm__ __volatile__ (
5-
"lock ; cmpxchg %3, %1"
6-
: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
7-
return t;
8-
}
9-
10-
#define a_cas_p a_cas_p
11-
static inline void *a_cas_p(volatile void *p, void *t, void *s)
12-
{
13-
__asm__( "lock ; cmpxchg %3, %1"
14-
: "=a"(t), "=m"(*(void *volatile *)p)
15-
: "a"(t), "r"(s) : "memory" );
16-
return t;
17-
}
18-
19-
#define a_swap a_swap
20-
static inline int a_swap(volatile int *p, int v)
21-
{
22-
__asm__ __volatile__(
23-
"xchg %0, %1"
24-
: "=r"(v), "=m"(*p) : "0"(v) : "memory" );
25-
return v;
26-
}
27-
28-
#define a_fetch_add a_fetch_add
29-
static inline int a_fetch_add(volatile int *p, int v)
30-
{
31-
__asm__ __volatile__(
32-
"lock ; xadd %0, %1"
33-
: "=r"(v), "=m"(*p) : "0"(v) : "memory" );
34-
return v;
35-
}
36-
37-
#define a_and a_and
38-
static inline void a_and(volatile int *p, int v)
39-
{
40-
__asm__ __volatile__(
41-
"lock ; and %1, %0"
42-
: "=m"(*p) : "r"(v) : "memory" );
43-
}
44-
45-
#define a_or a_or
46-
static inline void a_or(volatile int *p, int v)
47-
{
48-
__asm__ __volatile__(
49-
"lock ; or %1, %0"
50-
: "=m"(*p) : "r"(v) : "memory" );
51-
}
52-
53-
#define a_and_64 a_and_64
54-
static inline void a_and_64(volatile uint64_t *p, uint64_t v)
55-
{
56-
__asm__ __volatile(
57-
"lock ; and %1, %0"
58-
: "=m"(*p) : "r"(v) : "memory" );
59-
}
60-
61-
#define a_or_64 a_or_64
62-
static inline void a_or_64(volatile uint64_t *p, uint64_t v)
63-
{
64-
__asm__ __volatile__(
65-
"lock ; or %1, %0"
66-
: "=m"(*p) : "r"(v) : "memory" );
67-
}
68-
69-
#define a_inc a_inc
70-
static inline void a_inc(volatile int *p)
71-
{
72-
__asm__ __volatile__(
73-
"lock ; incl %0"
74-
: "=m"(*p) : "m"(*p) : "memory" );
75-
}
76-
77-
#define a_dec a_dec
78-
static inline void a_dec(volatile int *p)
79-
{
80-
__asm__ __volatile__(
81-
"lock ; decl %0"
82-
: "=m"(*p) : "m"(*p) : "memory" );
83-
}
84-
85-
#define a_store a_store
86-
static inline void a_store(volatile int *p, int x)
87-
{
88-
__asm__ __volatile__(
89-
"mov %1, %0 ; lock ; orl $0,(%%rsp)"
90-
: "=m"(*p) : "r"(x) : "memory" );
91-
}
92-
93-
#define a_barrier a_barrier
94-
static inline void a_barrier()
95-
{
96-
__asm__ __volatile__( "" : : : "memory" );
97-
}
98-
99-
#define a_pause a_pause
100-
static inline void a_spin()
101-
{
102-
__asm__ __volatile__( "pause" : : : "memory" );
103-
}
104-
105-
#define a_crash a_crash
106-
static inline void a_crash()
107-
{
108-
__asm__ __volatile__( "hlt" : : : "memory" );
109-
}
110-
111-
#define a_ctz_64 a_ctz_64
112-
static inline int a_ctz_64(uint64_t x)
113-
{
114-
__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
115-
return x;
116-
}
2+
int a_cas(volatile int *p, int t, int s);

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![no_std]
2-
#![feature(lang_items, linkage)]
2+
#![feature(asm, lang_items, linkage)]
33

44
#![allow(non_camel_case_types)]
55

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use core::sync::atomic::{AtomicPtr, Ordering};
2+
use c_types::*;
3+
4+
#[inline(always)]
5+
#[no_mangle]
6+
pub unsafe extern fn a_cas(p: *mut c_int, mut t: c_int, s: c_int) -> c_int {
7+
asm!("lock ; cmpxchgl $3, $1" :
8+
"=A"(t), "=*m"(p) :
9+
"A"(t), "r"(s) :
10+
"memory" :
11+
"volatile");
12+
t
13+
}
14+
15+
#[inline(always)]
16+
#[no_mangle]
17+
pub unsafe extern fn a_cas_p(p: *mut c_int, mut t: *mut c_int, s: *mut c_int) -> *mut c_void {
18+
asm!("lock ; cmpxchg $3, $1" :
19+
"=A"(t), "=*m"(p) :
20+
"A"(t), "r"(s) :
21+
"memory" :
22+
"volatile");
23+
t as *mut c_void
24+
}
25+
26+
#[inline(always)]
27+
#[no_mangle]
28+
pub unsafe extern fn a_swap(p: *mut c_int, mut v: c_int) -> c_int {
29+
*AtomicPtr::new(p).swap(&mut v, Ordering::Relaxed)
30+
}
31+
32+
#[inline(always)]
33+
#[no_mangle]
34+
pub unsafe extern fn a_store(p: *mut c_int, x: c_int) {
35+
asm!("mov $1, $0 ; lock ; orl $$0, (%rsp)"
36+
: "=*m"(p) : "r"(x) : "memory" : "volatile");
37+
}
38+
39+
#[inline(always)]
40+
#[no_mangle]
41+
pub unsafe extern fn a_inc(p: *mut c_int) {
42+
asm!(
43+
"lock ; incl $0"
44+
:"=*m"(p)
45+
:"m"(*p)
46+
:"memory"
47+
:"volatile"
48+
);
49+
}
50+
51+
#[inline(always)]
52+
#[no_mangle]
53+
pub unsafe extern fn a_dec(p: *mut c_int) {
54+
asm!(
55+
"lock ; decl $0"
56+
:"=*m"(p)
57+
:"m"(*p)
58+
:"memory"
59+
:"volatile"
60+
);
61+
}
62+
63+
#[inline(always)]
64+
#[no_mangle]
65+
pub unsafe extern fn a_fetch_add(p: *mut c_int, mut v: c_int) -> c_int {
66+
asm!("lock ; xadd $0, $1"
67+
: "=r"(v), "=*m"(p) : "0"(v) : "memory" : "volatile");
68+
v
69+
}
70+
71+
#[inline(always)]
72+
#[no_mangle]
73+
pub unsafe extern fn a_and(p: *mut c_int, v: c_int) {
74+
asm!("lock ; and $1, $0"
75+
: "=*m"(p) : "r"(v) : "memory" : "volatile");
76+
}
77+
78+
#[inline(always)]
79+
#[no_mangle]
80+
pub unsafe extern fn a_or(p: *mut c_int, v: c_int) {
81+
asm!("lock ; or $1, $0"
82+
: "=*m"(p) : "r"(v) : "memory" : "volatile");
83+
}
84+
85+
#[inline(always)]
86+
#[no_mangle]
87+
pub unsafe extern fn a_and_64(p: *mut u64, v: u64) {
88+
asm!("lock ; and $1, $0"
89+
: "=*m"(p) : "r"(v) : "memory" : "volatile");
90+
}
91+
92+
#[inline(always)]
93+
#[no_mangle]
94+
pub unsafe extern fn a_or_64(p: *mut u64, v: u64) {
95+
asm!("lock ; or $1, $0"
96+
: "=*m"(p) : "r"(v) : "memory" : "volatile");
97+
}
98+
99+
#[inline(always)]
100+
#[no_mangle]
101+
pub unsafe extern fn a_crash() {
102+
asm!("hlt" ::: "memory" : "volatile");
103+
}
104+
105+
#[inline(always)]
106+
#[no_mangle]
107+
pub unsafe extern fn a_spin() {
108+
asm!("pause" ::: "memory" : "volatile");
109+
}
110+
111+
#[inline(always)]
112+
#[no_mangle]
113+
pub unsafe extern fn a_barrier() {
114+
asm!("" ::: "memory" : "volatile");
115+
}
116+
117+
#[inline(always)]
118+
#[no_mangle]
119+
pub unsafe extern fn a_ctz_64(mut x: u64) -> u64 {
120+
asm!("bsf $1, $0" : "=r"(x) : "r"(x));
121+
x
122+
}

src/platform/linux-x86_64/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub use self::errno::*;
22

3+
pub mod atomic;
34
pub mod errno;

src/thread/mod.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@ pub const FUTEX_PRIVATE: c_int = 128;
1515
pub const FUTEX_CLOCK_REALTIME: c_int = 256;
1616

1717
#[no_mangle]
18-
pub unsafe extern fn __wake(address: *mut c_void, count: c_int, private: c_int) {
19-
let private = if private != 0 { 128 } else { private };
18+
pub unsafe extern "C" fn __wake(address: *mut c_void, count: c_int, private: c_int) {
19+
let private = if private != 0 {
20+
128
21+
} else {
22+
private
23+
};
2024

21-
let count = if count < 0 { C_INT_MAX } else { count };
25+
let count = if count < 0 {
26+
C_INT_MAX
27+
} else {
28+
count
29+
};
2230

2331
let res = syscall!(FUTEX, address, FUTEX_WAKE | private, count);
2432

0 commit comments

Comments
 (0)