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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
use std::cell::{UnsafeCell};
use std::ops::{Deref, DerefMut};
use crossbeam::atomic::AtomicCell;

type BorrowFlag = isize;
const UNUSED: BorrowFlag = 0;

#[inline(always)]
fn is_writing(x: BorrowFlag) -> bool {
    x < UNUSED
}

#[inline(always)]
fn is_reading(x: BorrowFlag) -> bool {
    x > UNUSED
}


struct BorrowRef<'b> {
    borrow: &'b AtomicCell<BorrowFlag>,
}

impl<'b> BorrowRef<'b> {
    #[inline]
    fn new(borrow: &'b AtomicCell<BorrowFlag>) -> Option<BorrowRef<'b>> {
        let b = borrow.fetch_add(1);
        if !is_reading(b + 1) {
            // Incrementing borrow can result in a non-reading value (<= 0) in these cases:
            // 1. It was < 0, i.e. there are writing borrows, so we can't allow a read borrow
            //    due to Rust's reference aliasing rules
            // 2. It was isize::max_value() (the max amount of reading borrows) and it overflowed
            //    into isize::min_value() (the max amount of writing borrows) so we can't allow
            //    an additional read borrow because isize can't represent so many read borrows
            //    (this can only happen if you mem::forget more than a small constant amount of
            //    `Ref`s, which is not good practice)
            None
        } else {
            // Incrementing borrow can result in a reading value (> 0) in these cases:
            // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
            // 2. It was > 0 and < isize::max_value(), i.e. there were read borrows, and isize
            //    is large enough to represent having one more read borrow
            Some(BorrowRef { borrow })
        }
    }
}

impl Drop for BorrowRef<'_> {
    #[inline]
    fn drop(&mut self) {
        let borrow = self.borrow.fetch_sub(1);
        debug_assert!(is_reading(borrow));
    }
}

impl Clone for BorrowRef<'_> {
    #[inline]
    fn clone(&self) -> Self {
        // Since this Ref exists, we know the borrow flag
        // is a reading borrow.
        let borrow = self.borrow.fetch_add(1);
        debug_assert!(is_reading(borrow));
        // Prevent the borrow counter from overflowing into
        // a writing borrow.
        assert!(borrow != isize::max_value());
        BorrowRef { borrow: self.borrow }
    }
}

struct BorrowRefMut<'b> {
    borrow: &'b AtomicCell<BorrowFlag>,
}

impl Drop for BorrowRefMut<'_> {
    #[inline]
    fn drop(&mut self) {
        let borrow = self.borrow.fetch_add(1);
        debug_assert!(is_writing(borrow));
    }
}

impl<'b> BorrowRefMut<'b> {
    #[inline]
    fn new(borrow: &'b AtomicCell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
        // NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
        // mutable reference, and so there must currently be no existing
        // references. Thus, while clone increments the mutable refcount, here
        // we explicitly only allow going from UNUSED to UNUSED - 1.
        match borrow.fetch_sub(1) {
            UNUSED => Some(BorrowRefMut { borrow }),
            _ => None,
        }
    }

    // Clones a `BorrowRefMut`.
    //
    // This is only valid if each `BorrowRefMut` is used to track a mutable
    // reference to a distinct, nonoverlapping range of the original object.
    // This isn't in a Clone impl so that code doesn't call this implicitly.
    // #[inline]
    // fn clone(&self) -> BorrowRefMut<'b> {
    //     let borrow = self.borrow.fetch_sub(1);
    //     debug_assert!(is_writing(borrow));
    //     // Prevent the borrow counter from underflowing.
    //     assert!(borrow != isize::min_value());
    //     BorrowRefMut { borrow: self.borrow }
    // }
}

pub struct MutCell<T: ?Sized> {
    borrow: AtomicCell<BorrowFlag>,
    value: UnsafeCell<T>,
}


impl<T> MutCell<T> {
    #[inline]
    pub const fn new(value: T) -> MutCell<T> {
        MutCell { value: UnsafeCell::new(value), borrow: AtomicCell::new(UNUSED) }
    }

    pub fn borrow(&self) -> Ref<T> {
        let borrow_ref = BorrowRef::new(&self.borrow).expect("already mutably borrowed");
        Ref {
            t: unsafe{ &*self.value.get() },
            borrow_ref,
        }
    }

    pub fn borrow_mut(&self) -> RefMut<T> {
        let borrow_ref_mut = BorrowRefMut::new(&self.borrow).expect("already borrowed");
        RefMut{
            t: unsafe{ &mut *self.value.get() },
            borrow_ref_mut
        }
    }

    #[inline]
    pub fn into_inner(self) -> T {
        // Since this function takes `self` (the `RefCell`) by value, the
        // compiler statically verifies that it is not currently borrowed.
        // Therefore the following assertion is just a `debug_assert!`.
        debug_assert!(self.borrow.load() == UNUSED);
        self.value.into_inner()
    }

    #[inline]
    pub fn get_mut(&mut self) -> &mut T {
        // SAFETY: `&mut` guarantees unique access.
        unsafe { &mut *self.value.get() }
    }
}

pub struct Ref<'a, T: ?Sized> {
    t: &'a T,
    borrow_ref: BorrowRef<'a>
}

impl<'a,T: ?Sized> Ref<'a,T> {
    pub fn map<F, S: ?Sized>(this: Self, f: F) -> Ref<'a, S>
    where F: FnOnce(&T) -> &S
    {
        Ref {
            t: f(this.t),
            borrow_ref: this.borrow_ref
        }
    }
}

impl<'a, T: 'a> Deref for Ref<'a, T>{
    type Target = T;
    #[inline]
    fn deref(&self) -> &T{
        &self.t
    }
}

pub struct RefMut<'a, T: ?Sized>{
    t: &'a mut T,
    borrow_ref_mut: BorrowRefMut<'a>
}

impl<'a,T: ?Sized> RefMut<'a,T> {
    pub fn map<F, S: ?Sized>(this: Self, f: F) -> RefMut<'a, S>
    where F: FnOnce(&mut T) -> &mut S
    {
        RefMut{
            t: f(this.t),
            borrow_ref_mut: this.borrow_ref_mut
        }
    }
}

impl<'a, T: 'a> Deref for RefMut<'a, T>{
    type Target = T;
    #[inline]
    fn deref(&self) -> &T{
        &self.t
    }
}

impl<'a, T: 'a> DerefMut for RefMut<'a, T>{
    #[inline]
    fn deref_mut(&mut self) -> &mut T{
        unsafe{ &mut *(&*self.t as *const T as *mut T) }
    }
}