1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::fmt;
use std::mem::transmute;
use std::sync::atomic::{AtomicPtr, Ordering};
use atomic::Atomic;
use libc::c_void;
use serde_json;
use value::{Value, Describe, RawType, LevelKind, Assign};
pub struct Integer {
#[allow(dead_code)]
value: Box<Atomic<i64>>,
pointer: AtomicPtr<Atomic<i64>>,
}
impl Integer {
pub fn new() -> Integer {
let tmp = Box::new(Atomic::new(0));
Integer {
pointer: unsafe { transmute(&*tmp) },
value: tmp,
}
}
pub fn incr(&self, val: i64) {
unsafe {
&*self.pointer.load(Ordering::Relaxed)
}.fetch_add(val, Ordering::Relaxed);
}
pub fn decr(&self, val: i64) {
unsafe {
&*self.pointer.load(Ordering::Relaxed)
}.fetch_sub(val, Ordering::Relaxed);
}
pub fn set(&self, val: i64) {
unsafe {
&*self.pointer.load(Ordering::Relaxed)
}.store(val, Ordering::Relaxed);
}
pub fn get(&self) -> i64 {
unsafe {
&*self.pointer.load(Ordering::Relaxed)
}.load(Ordering::Relaxed)
}
}
impl fmt::Display for Integer {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{}", unsafe {
&*self.pointer.load(Ordering::Relaxed)
}.load(Ordering::Relaxed))
}
}
impl fmt::Debug for Integer {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "Integer({})", unsafe {
&*self.pointer.load(Ordering::Relaxed)
}.load(Ordering::Relaxed))
}
}
impl Describe for Integer {
fn raw_type(&self) -> RawType { RawType::Level(LevelKind::Signed) }
fn raw_size(&self) -> usize { 8 }
fn as_json(&self) -> serde_json::Value {
serde_json::Value::Number(self.get().into())
}
}
impl Assign for Integer {
fn copy_assign(&self, ptr: *mut c_void) {
let value = self.value.load(Ordering::SeqCst);
let ptr: *mut Atomic<i64> = unsafe { transmute(ptr) };
unsafe { (*ptr).store(value, Ordering::SeqCst) };
self.pointer.store(ptr, Ordering::SeqCst);
}
fn assign(&self, ptr: *mut c_void) {
self.pointer.store(unsafe { transmute(ptr) }, Ordering::SeqCst);
}
fn reset(&self) {
let old_value = unsafe {
&*self.pointer.load(Ordering::SeqCst)
}.load(Ordering::SeqCst);
self.value.store(old_value, Ordering::SeqCst);
self.pointer.store(unsafe { transmute(&*self.value) },
Ordering::SeqCst);
}
}
impl Value for Integer {}