xref: /openbmc/qemu/rust/bql/src/cell.rs (revision b2d86f1c5429979d9ecaf43a7973cc129da1b135)
1 // SPDX-License-Identifier: MIT
2 //
3 // This file is based on library/core/src/cell.rs from
4 // Rust 1.82.0.
5 //
6 // Permission is hereby granted, free of charge, to any
7 // person obtaining a copy of this software and associated
8 // documentation files (the "Software"), to deal in the
9 // Software without restriction, including without
10 // limitation the rights to use, copy, modify, merge,
11 // publish, distribute, sublicense, and/or sell copies of
12 // the Software, and to permit persons to whom the Software
13 // is furnished to do so, subject to the following
14 // conditions:
15 //
16 // The above copyright notice and this permission notice
17 // shall be included in all copies or substantial portions
18 // of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
21 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
22 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
23 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
24 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
27 // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 // DEALINGS IN THE SOFTWARE.
29 
30 //! QEMU-specific mutable containers
31 //!
32 //! Rust memory safety is based on this rule: Given an object `T`, it is only
33 //! possible to have one of the following:
34 //!
35 //! - Having several immutable references (`&T`) to the object (also known as
36 //!   **aliasing**).
37 //! - Having one mutable reference (`&mut T`) to the object (also known as
38 //!   **mutability**).
39 //!
40 //! This is enforced by the Rust compiler. However, there are situations where
41 //! this rule is not flexible enough. Sometimes it is required to have multiple
42 //! references to an object and yet mutate it. In particular, QEMU objects
43 //! usually have their pointer shared with the "outside world very early in
44 //! their lifetime", for example when they create their
45 //! [`MemoryRegion`s](crate::bindings::MemoryRegion).  Therefore, individual
46 //! parts of a  device must be made mutable in a controlled manner; this module
47 //! provides the tools to do so.
48 //!
49 //! ## Cell types
50 //!
51 //! [`BqlCell<T>`] and [`BqlRefCell<T>`] allow doing this via the Big QEMU Lock.
52 //! While they are essentially the same single-threaded primitives that are
53 //! available in `std::cell`, the BQL allows them to be used from a
54 //! multi-threaded context and to share references across threads, while
55 //! maintaining Rust's safety guarantees.  For this reason, unlike
56 //! their `std::cell` counterparts, `BqlCell` and `BqlRefCell` implement the
57 //! `Sync` trait.
58 //!
59 //! BQL checks are performed in debug builds but can be optimized away in
60 //! release builds, providing runtime safety during development with no overhead
61 //! in production.
62 //!
63 //! The two provide different ways of handling interior mutability.
64 //! `BqlRefCell` is best suited for data that is primarily accessed by the
65 //! device's own methods, where multiple reads and writes can be grouped within
66 //! a single borrow and a mutable reference can be passed around.  Instead,
67 //! [`BqlCell`] is a better choice when sharing small pieces of data with
68 //! external code (especially C code), because it provides simple get/set
69 //! operations that can be used one at a time.
70 //!
71 //! Warning: While `BqlCell` and `BqlRefCell` are similar to their `std::cell`
72 //! counterparts, they are not interchangeable. Using `std::cell` types in
73 //! QEMU device implementations is usually incorrect and can lead to
74 //! thread-safety issues.
75 //!
76 //! ### Example
77 //!
78 //! ```ignore
79 //! # use bql::BqlRefCell;
80 //! # use qom::{Owned, ParentField};
81 //! # use system::{InterruptSource, IRQState, SysBusDevice};
82 //! # const N_GPIOS: usize = 8;
83 //! # struct PL061Registers { /* ... */ }
84 //! # unsafe impl ObjectType for PL061State {
85 //! #     type Class = <SysBusDevice as ObjectType>::Class;
86 //! #     const TYPE_NAME: &'static std::ffi::CStr = c"pl061";
87 //! # }
88 //! struct PL061State {
89 //!     parent_obj: ParentField<SysBusDevice>,
90 //!
91 //!     // Configuration is read-only after initialization
92 //!     pullups: u32,
93 //!     pulldowns: u32,
94 //!
95 //!     // Single values shared with C code use BqlCell, in this case via InterruptSource
96 //!     out: [InterruptSource; N_GPIOS],
97 //!     interrupt: InterruptSource,
98 //!
99 //!     // Larger state accessed by device methods uses BqlRefCell or Mutex
100 //!     registers: BqlRefCell<PL061Registers>,
101 //! }
102 //! ```
103 //!
104 //! ### `BqlCell<T>`
105 //!
106 //! [`BqlCell<T>`] implements interior mutability by moving values in and out of
107 //! the cell. That is, an `&mut T` to the inner value can never be obtained as
108 //! long as the cell is shared. The value itself cannot be directly obtained
109 //! without copying it, cloning it, or replacing it with something else. This
110 //! type provides the following methods, all of which can be called only while
111 //! the BQL is held:
112 //!
113 //!  - For types that implement [`Copy`], the [`get`](BqlCell::get) method
114 //!    retrieves the current interior value by duplicating it.
115 //!  - For types that implement [`Default`], the [`take`](BqlCell::take) method
116 //!    replaces the current interior value with [`Default::default()`] and
117 //!    returns the replaced value.
118 //!  - All types have:
119 //!    - [`replace`](BqlCell::replace): replaces the current interior value and
120 //!      returns the replaced value.
121 //!    - [`set`](BqlCell::set): this method replaces the interior value,
122 //!      dropping the replaced value.
123 //!
124 //! ### `BqlRefCell<T>`
125 //!
126 //! [`BqlRefCell<T>`] uses Rust's lifetimes to implement "dynamic borrowing", a
127 //! process whereby one can claim temporary, exclusive, mutable access to the
128 //! inner value:
129 //!
130 //! ```ignore
131 //! fn clear_interrupts(&self, val: u32) {
132 //!     // A mutable borrow gives read-write access to the registers
133 //!     let mut regs = self.registers.borrow_mut();
134 //!     let old = regs.interrupt_status();
135 //!     regs.update_interrupt_status(old & !val);
136 //! }
137 //! ```
138 //!
139 //! Borrows for `BqlRefCell<T>`s are tracked at _runtime_, unlike Rust's native
140 //! reference types which are entirely tracked statically, at compile time.
141 //! Multiple immutable borrows are allowed via [`borrow`](BqlRefCell::borrow),
142 //! or a single mutable borrow via [`borrow_mut`](BqlRefCell::borrow_mut).  The
143 //! thread will panic if these rules are violated or if the BQL is not held.
144 use std::{
145     cell::{Cell, UnsafeCell},
146     cmp::Ordering,
147     fmt,
148     marker::PhantomData,
149     mem,
150     ops::{Deref, DerefMut},
151     ptr::NonNull,
152 };
153 
154 /// A mutable memory location that is protected by the Big QEMU Lock.
155 ///
156 /// # Memory layout
157 ///
158 /// `BqlCell<T>` has the same in-memory representation as its inner type `T`.
159 #[repr(transparent)]
160 pub struct BqlCell<T> {
161     value: UnsafeCell<T>,
162 }
163 
164 // SAFETY: Same as for std::sync::Mutex.  In the end this *is* a Mutex,
165 // except it is stored out-of-line
166 unsafe impl<T: Send> Send for BqlCell<T> {}
167 unsafe impl<T: Send> Sync for BqlCell<T> {}
168 
169 impl<T: Copy> Clone for BqlCell<T> {
170     #[inline]
171     fn clone(&self) -> BqlCell<T> {
172         BqlCell::new(self.get())
173     }
174 }
175 
176 impl<T: Default> Default for BqlCell<T> {
177     /// Creates a `BqlCell<T>`, with the `Default` value for T.
178     #[inline]
179     fn default() -> BqlCell<T> {
180         BqlCell::new(Default::default())
181     }
182 }
183 
184 impl<T: PartialEq + Copy> PartialEq for BqlCell<T> {
185     #[inline]
186     fn eq(&self, other: &BqlCell<T>) -> bool {
187         self.get() == other.get()
188     }
189 }
190 
191 impl<T: Eq + Copy> Eq for BqlCell<T> {}
192 
193 impl<T: PartialOrd + Copy> PartialOrd for BqlCell<T> {
194     #[inline]
195     fn partial_cmp(&self, other: &BqlCell<T>) -> Option<Ordering> {
196         self.get().partial_cmp(&other.get())
197     }
198 }
199 
200 impl<T: Ord + Copy> Ord for BqlCell<T> {
201     #[inline]
202     fn cmp(&self, other: &BqlCell<T>) -> Ordering {
203         self.get().cmp(&other.get())
204     }
205 }
206 
207 impl<T> From<T> for BqlCell<T> {
208     /// Creates a new `BqlCell<T>` containing the given value.
209     fn from(t: T) -> BqlCell<T> {
210         BqlCell::new(t)
211     }
212 }
213 
214 impl<T: fmt::Debug + Copy> fmt::Debug for BqlCell<T> {
215     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216         self.get().fmt(f)
217     }
218 }
219 
220 impl<T: fmt::Display + Copy> fmt::Display for BqlCell<T> {
221     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222         self.get().fmt(f)
223     }
224 }
225 
226 impl<T> BqlCell<T> {
227     /// Creates a new `BqlCell` containing the given value.
228     ///
229     /// # Examples
230     ///
231     /// ```
232     /// use bql::BqlCell;
233     /// # bql::start_test();
234     ///
235     /// let c = BqlCell::new(5);
236     /// ```
237     #[inline]
238     pub const fn new(value: T) -> BqlCell<T> {
239         BqlCell {
240             value: UnsafeCell::new(value),
241         }
242     }
243 
244     /// Sets the contained value.
245     ///
246     /// # Examples
247     ///
248     /// ```
249     /// use bql::BqlCell;
250     /// # bql::start_test();
251     ///
252     /// let c = BqlCell::new(5);
253     ///
254     /// c.set(10);
255     /// ```
256     #[inline]
257     pub fn set(&self, val: T) {
258         self.replace(val);
259     }
260 
261     /// Replaces the contained value with `val`, and returns the old contained
262     /// value.
263     ///
264     /// # Examples
265     ///
266     /// ```
267     /// use bql::BqlCell;
268     /// # bql::start_test();
269     ///
270     /// let cell = BqlCell::new(5);
271     /// assert_eq!(cell.get(), 5);
272     /// assert_eq!(cell.replace(10), 5);
273     /// assert_eq!(cell.get(), 10);
274     /// ```
275     #[inline]
276     pub fn replace(&self, val: T) -> T {
277         assert!(crate::is_locked());
278         // SAFETY: This can cause data races if called from multiple threads,
279         // but it won't happen as long as C code accesses the value
280         // under BQL protection only.
281         mem::replace(unsafe { &mut *self.value.get() }, val)
282     }
283 
284     /// Unwraps the value, consuming the cell.
285     ///
286     /// # Examples
287     ///
288     /// ```
289     /// use bql::BqlCell;
290     /// # bql::start_test();
291     ///
292     /// let c = BqlCell::new(5);
293     /// let five = c.into_inner();
294     ///
295     /// assert_eq!(five, 5);
296     /// ```
297     pub fn into_inner(self) -> T {
298         assert!(crate::is_locked());
299         self.value.into_inner()
300     }
301 }
302 
303 impl<T: Copy> BqlCell<T> {
304     /// Returns a copy of the contained value.
305     ///
306     /// # Examples
307     ///
308     /// ```
309     /// use bql::BqlCell;
310     /// # bql::start_test();
311     ///
312     /// let c = BqlCell::new(5);
313     ///
314     /// let five = c.get();
315     /// ```
316     #[inline]
317     pub fn get(&self) -> T {
318         assert!(crate::is_locked());
319         // SAFETY: This can cause data races if called from multiple threads,
320         // but it won't happen as long as C code accesses the value
321         // under BQL protection only.
322         unsafe { *self.value.get() }
323     }
324 }
325 
326 impl<T> BqlCell<T> {
327     /// Returns a raw pointer to the underlying data in this cell.
328     ///
329     /// # Examples
330     ///
331     /// ```
332     /// use bql::BqlCell;
333     /// # bql::start_test();
334     ///
335     /// let c = BqlCell::new(5);
336     ///
337     /// let ptr = c.as_ptr();
338     /// ```
339     #[inline]
340     pub const fn as_ptr(&self) -> *mut T {
341         self.value.get()
342     }
343 }
344 
345 impl<T: Default> BqlCell<T> {
346     /// Takes the value of the cell, leaving `Default::default()` in its place.
347     ///
348     /// # Examples
349     ///
350     /// ```
351     /// use bql::BqlCell;
352     /// # bql::start_test();
353     ///
354     /// let c = BqlCell::new(5);
355     /// let five = c.take();
356     ///
357     /// assert_eq!(five, 5);
358     /// assert_eq!(c.into_inner(), 0);
359     /// ```
360     pub fn take(&self) -> T {
361         self.replace(Default::default())
362     }
363 }
364 
365 /// A mutable memory location with dynamically checked borrow rules,
366 /// protected by the Big QEMU Lock.
367 ///
368 /// See the [module-level documentation](self) for more.
369 ///
370 /// # Memory layout
371 ///
372 /// `BqlRefCell<T>` starts with the same in-memory representation as its
373 /// inner type `T`.
374 #[repr(C)]
375 pub struct BqlRefCell<T> {
376     // It is important that this is the first field (which is not the case
377     // for std::cell::BqlRefCell), so that we can use offset_of! on it.
378     // UnsafeCell and repr(C) both prevent usage of niches.
379     value: UnsafeCell<T>,
380     borrow: Cell<BorrowFlag>,
381     // Stores the location of the earliest currently active borrow.
382     // This gets updated whenever we go from having zero borrows
383     // to having a single borrow. When a borrow occurs, this gets included
384     // in the panic message
385     #[cfg(feature = "debug_cell")]
386     borrowed_at: Cell<Option<&'static std::panic::Location<'static>>>,
387 }
388 
389 // Positive values represent the number of `BqlRef` active. Negative values
390 // represent the number of `BqlRefMut` active. Right now QEMU's implementation
391 // does not allow to create `BqlRefMut`s that refer to distinct, nonoverlapping
392 // components of a `BqlRefCell` (e.g., different ranges of a slice).
393 //
394 // `BqlRef` and `BqlRefMut` are both two words in size, and so there will likely
395 // never be enough `BqlRef`s or `BqlRefMut`s in existence to overflow half of
396 // the `usize` range. Thus, a `BorrowFlag` will probably never overflow or
397 // underflow. However, this is not a guarantee, as a pathological program could
398 // repeatedly create and then mem::forget `BqlRef`s or `BqlRefMut`s. Thus, all
399 // code must explicitly check for overflow and underflow in order to avoid
400 // unsafety, or at least behave correctly in the event that overflow or
401 // underflow happens (e.g., see BorrowRef::new).
402 type BorrowFlag = isize;
403 const UNUSED: BorrowFlag = 0;
404 
405 #[inline(always)]
406 const fn is_writing(x: BorrowFlag) -> bool {
407     x < UNUSED
408 }
409 
410 #[inline(always)]
411 const fn is_reading(x: BorrowFlag) -> bool {
412     x > UNUSED
413 }
414 
415 impl<T> BqlRefCell<T> {
416     /// Creates a new `BqlRefCell` containing `value`.
417     ///
418     /// # Examples
419     ///
420     /// ```
421     /// use bql::BqlRefCell;
422     ///
423     /// let c = BqlRefCell::new(5);
424     /// ```
425     #[inline]
426     pub const fn new(value: T) -> BqlRefCell<T> {
427         BqlRefCell {
428             value: UnsafeCell::new(value),
429             borrow: Cell::new(UNUSED),
430             #[cfg(feature = "debug_cell")]
431             borrowed_at: Cell::new(None),
432         }
433     }
434 }
435 
436 // This ensures the panicking code is outlined from `borrow_mut` for
437 // `BqlRefCell`.
438 #[inline(never)]
439 #[cold]
440 #[cfg(feature = "debug_cell")]
441 fn panic_already_borrowed(source: &Cell<Option<&'static std::panic::Location<'static>>>) -> ! {
442     // If a borrow occurred, then we must already have an outstanding borrow,
443     // so `borrowed_at` will be `Some`
444     panic!("already borrowed at {:?}", source.take().unwrap())
445 }
446 
447 #[inline(never)]
448 #[cold]
449 #[cfg(not(feature = "debug_cell"))]
450 fn panic_already_borrowed() -> ! {
451     panic!("already borrowed")
452 }
453 
454 impl<T> BqlRefCell<T> {
455     #[inline]
456     #[allow(clippy::unused_self)]
457     fn panic_already_borrowed(&self) -> ! {
458         #[cfg(feature = "debug_cell")]
459         {
460             panic_already_borrowed(&self.borrowed_at)
461         }
462         #[cfg(not(feature = "debug_cell"))]
463         {
464             panic_already_borrowed()
465         }
466     }
467 
468     /// Immutably borrows the wrapped value.
469     ///
470     /// The borrow lasts until the returned `BqlRef` exits scope. Multiple
471     /// immutable borrows can be taken out at the same time.
472     ///
473     /// # Panics
474     ///
475     /// Panics if the value is currently mutably borrowed.
476     ///
477     /// # Examples
478     ///
479     /// ```
480     /// use bql::BqlRefCell;
481     /// # bql::start_test();
482     ///
483     /// let c = BqlRefCell::new(5);
484     ///
485     /// let borrowed_five = c.borrow();
486     /// let borrowed_five2 = c.borrow();
487     /// ```
488     ///
489     /// An example of panic:
490     ///
491     /// ```should_panic
492     /// use bql::BqlRefCell;
493     /// # bql::start_test();
494     ///
495     /// let c = BqlRefCell::new(5);
496     ///
497     /// let m = c.borrow_mut();
498     /// let b = c.borrow(); // this causes a panic
499     /// ```
500     #[inline]
501     #[track_caller]
502     pub fn borrow(&self) -> BqlRef<'_, T> {
503         if let Some(b) = BorrowRef::new(&self.borrow) {
504             // `borrowed_at` is always the *first* active borrow
505             if b.borrow.get() == 1 {
506                 #[cfg(feature = "debug_cell")]
507                 self.borrowed_at.set(Some(std::panic::Location::caller()));
508             }
509 
510             crate::block_unlock(true);
511 
512             // SAFETY: `BorrowRef` ensures that there is only immutable access
513             // to the value while borrowed.
514             let value = unsafe { NonNull::new_unchecked(self.value.get()) };
515             BqlRef { value, borrow: b }
516         } else {
517             self.panic_already_borrowed()
518         }
519     }
520 
521     /// Mutably borrows the wrapped value.
522     ///
523     /// The borrow lasts until the returned `BqlRefMut` or all `BqlRefMut`s
524     /// derived from it exit scope. The value cannot be borrowed while this
525     /// borrow is active.
526     ///
527     /// # Panics
528     ///
529     /// Panics if the value is currently borrowed.
530     ///
531     /// # Examples
532     ///
533     /// ```
534     /// use bql::BqlRefCell;
535     /// # bql::start_test();
536     ///
537     /// let c = BqlRefCell::new("hello".to_owned());
538     ///
539     /// *c.borrow_mut() = "bonjour".to_owned();
540     ///
541     /// assert_eq!(&*c.borrow(), "bonjour");
542     /// ```
543     ///
544     /// An example of panic:
545     ///
546     /// ```should_panic
547     /// use bql::BqlRefCell;
548     /// # bql::start_test();
549     ///
550     /// let c = BqlRefCell::new(5);
551     /// let m = c.borrow();
552     ///
553     /// let b = c.borrow_mut(); // this causes a panic
554     /// ```
555     #[inline]
556     #[track_caller]
557     pub fn borrow_mut(&self) -> BqlRefMut<'_, T> {
558         if let Some(b) = BorrowRefMut::new(&self.borrow) {
559             #[cfg(feature = "debug_cell")]
560             {
561                 self.borrowed_at.set(Some(std::panic::Location::caller()));
562             }
563 
564             // SAFETY: this only adjusts a counter
565             crate::block_unlock(true);
566 
567             // SAFETY: `BorrowRefMut` guarantees unique access.
568             let value = unsafe { NonNull::new_unchecked(self.value.get()) };
569             BqlRefMut {
570                 value,
571                 _borrow: b,
572                 marker: PhantomData,
573             }
574         } else {
575             self.panic_already_borrowed()
576         }
577     }
578 
579     /// Returns a mutable reference to the underlying data in this cell,
580     /// while the owner already has a mutable reference to the cell.
581     ///
582     /// # Examples
583     ///
584     /// ```
585     /// use bql::BqlRefCell;
586     ///
587     /// let mut c = BqlRefCell::new(5);
588     ///
589     /// *c.get_mut() = 10;
590     /// ```
591     #[inline]
592     pub const fn get_mut(&mut self) -> &mut T {
593         self.value.get_mut()
594     }
595 
596     /// Returns a raw pointer to the underlying data in this cell.
597     ///
598     /// # Examples
599     ///
600     /// ```
601     /// use bql::BqlRefCell;
602     ///
603     /// let c = BqlRefCell::new(5);
604     ///
605     /// let ptr = c.as_ptr();
606     /// ```
607     #[inline]
608     pub const fn as_ptr(&self) -> *mut T {
609         self.value.get()
610     }
611 }
612 
613 // SAFETY: Same as for std::sync::Mutex.  In the end this is a Mutex that is
614 // stored out-of-line.  Even though BqlRefCell includes Cells, they are
615 // themselves protected by the Big QEMU Lock.  Furtheremore, the Big QEMU
616 // Lock cannot be released while any borrows is active.
617 unsafe impl<T> Send for BqlRefCell<T> where T: Send {}
618 unsafe impl<T> Sync for BqlRefCell<T> {}
619 
620 impl<T: Clone> Clone for BqlRefCell<T> {
621     /// # Panics
622     ///
623     /// Panics if the value is currently mutably borrowed.
624     #[inline]
625     #[track_caller]
626     fn clone(&self) -> BqlRefCell<T> {
627         BqlRefCell::new(self.borrow().clone())
628     }
629 
630     /// # Panics
631     ///
632     /// Panics if `source` is currently mutably borrowed.
633     #[inline]
634     #[track_caller]
635     fn clone_from(&mut self, source: &Self) {
636         self.value.get_mut().clone_from(&source.borrow())
637     }
638 }
639 
640 impl<T: Default> Default for BqlRefCell<T> {
641     /// Creates a `BqlRefCell<T>`, with the `Default` value for T.
642     #[inline]
643     fn default() -> BqlRefCell<T> {
644         BqlRefCell::new(Default::default())
645     }
646 }
647 
648 impl<T: PartialEq> PartialEq for BqlRefCell<T> {
649     /// # Panics
650     ///
651     /// Panics if the value in either `BqlRefCell` is currently mutably
652     /// borrowed.
653     #[inline]
654     fn eq(&self, other: &BqlRefCell<T>) -> bool {
655         *self.borrow() == *other.borrow()
656     }
657 }
658 
659 impl<T: Eq> Eq for BqlRefCell<T> {}
660 
661 impl<T: PartialOrd> PartialOrd for BqlRefCell<T> {
662     /// # Panics
663     ///
664     /// Panics if the value in either `BqlRefCell` is currently mutably
665     /// borrowed.
666     #[inline]
667     fn partial_cmp(&self, other: &BqlRefCell<T>) -> Option<Ordering> {
668         self.borrow().partial_cmp(&*other.borrow())
669     }
670 }
671 
672 impl<T: Ord> Ord for BqlRefCell<T> {
673     /// # Panics
674     ///
675     /// Panics if the value in either `BqlRefCell` is currently mutably
676     /// borrowed.
677     #[inline]
678     fn cmp(&self, other: &BqlRefCell<T>) -> Ordering {
679         self.borrow().cmp(&*other.borrow())
680     }
681 }
682 
683 impl<T> From<T> for BqlRefCell<T> {
684     /// Creates a new `BqlRefCell<T>` containing the given value.
685     fn from(t: T) -> BqlRefCell<T> {
686         BqlRefCell::new(t)
687     }
688 }
689 
690 struct BorrowRef<'b> {
691     borrow: &'b Cell<BorrowFlag>,
692 }
693 
694 impl<'b> BorrowRef<'b> {
695     #[inline]
696     fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
697         let b = borrow.get().wrapping_add(1);
698         if !is_reading(b) {
699             // Incrementing borrow can result in a non-reading value (<= 0) in these cases:
700             // 1. It was < 0, i.e. there are writing borrows, so we can't allow a read
701             //    borrow due to Rust's reference aliasing rules
702             // 2. It was isize::MAX (the max amount of reading borrows) and it overflowed
703             //    into isize::MIN (the max amount of writing borrows) so we can't allow an
704             //    additional read borrow because isize can't represent so many read borrows
705             //    (this can only happen if you mem::forget more than a small constant amount
706             //    of `BqlRef`s, which is not good practice)
707             None
708         } else {
709             // Incrementing borrow can result in a reading value (> 0) in these cases:
710             // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read
711             //    borrow
712             // 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize is
713             //    large enough to represent having one more read borrow
714             borrow.set(b);
715             Some(BorrowRef { borrow })
716         }
717     }
718 }
719 
720 impl Drop for BorrowRef<'_> {
721     #[inline]
722     fn drop(&mut self) {
723         let borrow = self.borrow.get();
724         debug_assert!(is_reading(borrow));
725         self.borrow.set(borrow - 1);
726         crate::block_unlock(false)
727     }
728 }
729 
730 impl Clone for BorrowRef<'_> {
731     #[inline]
732     fn clone(&self) -> Self {
733         BorrowRef::new(self.borrow).unwrap()
734     }
735 }
736 
737 /// Wraps a borrowed reference to a value in a `BqlRefCell` box.
738 /// A wrapper type for an immutably borrowed value from a `BqlRefCell<T>`.
739 ///
740 /// See the [module-level documentation](self) for more.
741 pub struct BqlRef<'b, T: 'b> {
742     // NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a
743     // `BqlRef` argument doesn't hold immutability for its whole scope, only until it drops.
744     // `NonNull` is also covariant over `T`, just like we would have with `&T`.
745     value: NonNull<T>,
746     borrow: BorrowRef<'b>,
747 }
748 
749 impl<T> Deref for BqlRef<'_, T> {
750     type Target = T;
751 
752     #[inline]
753     fn deref(&self) -> &T {
754         // SAFETY: the value is accessible as long as we hold our borrow.
755         unsafe { self.value.as_ref() }
756     }
757 }
758 
759 impl<'b, T> BqlRef<'b, T> {
760     /// Copies a `BqlRef`.
761     ///
762     /// The `BqlRefCell` is already immutably borrowed, so this cannot fail.
763     ///
764     /// This is an associated function that needs to be used as
765     /// `BqlRef::clone(...)`. A `Clone` implementation or a method would
766     /// interfere with the widespread use of `r.borrow().clone()` to clone
767     /// the contents of a `BqlRefCell`.
768     #[must_use]
769     #[inline]
770     #[allow(clippy::should_implement_trait)]
771     pub fn clone(orig: &BqlRef<'b, T>) -> BqlRef<'b, T> {
772         BqlRef {
773             value: orig.value,
774             borrow: orig.borrow.clone(),
775         }
776     }
777 }
778 
779 impl<T: fmt::Debug> fmt::Debug for BqlRef<'_, T> {
780     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
781         (**self).fmt(f)
782     }
783 }
784 
785 impl<T: fmt::Display> fmt::Display for BqlRef<'_, T> {
786     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
787         (**self).fmt(f)
788     }
789 }
790 
791 struct BorrowRefMut<'b> {
792     borrow: &'b Cell<BorrowFlag>,
793 }
794 
795 impl<'b> BorrowRefMut<'b> {
796     #[inline]
797     fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
798         // There must currently be no existing references when borrow_mut() is
799         // called, so we explicitly only allow going from UNUSED to UNUSED - 1.
800         match borrow.get() {
801             UNUSED => {
802                 borrow.set(UNUSED - 1);
803                 Some(BorrowRefMut { borrow })
804             }
805             _ => None,
806         }
807     }
808 }
809 
810 impl Drop for BorrowRefMut<'_> {
811     #[inline]
812     fn drop(&mut self) {
813         let borrow = self.borrow.get();
814         debug_assert!(is_writing(borrow));
815         self.borrow.set(borrow + 1);
816         crate::block_unlock(false)
817     }
818 }
819 
820 /// A wrapper type for a mutably borrowed value from a `BqlRefCell<T>`.
821 ///
822 /// See the [module-level documentation](self) for more.
823 pub struct BqlRefMut<'b, T: 'b> {
824     // NB: we use a pointer instead of `&'b mut T` to avoid `noalias` violations, because a
825     // `BqlRefMut` argument doesn't hold exclusivity for its whole scope, only until it drops.
826     value: NonNull<T>,
827     _borrow: BorrowRefMut<'b>,
828     // `NonNull` is covariant over `T`, so we need to reintroduce invariance.
829     marker: PhantomData<&'b mut T>,
830 }
831 
832 impl<T> Deref for BqlRefMut<'_, T> {
833     type Target = T;
834 
835     #[inline]
836     fn deref(&self) -> &T {
837         // SAFETY: the value is accessible as long as we hold our borrow.
838         unsafe { self.value.as_ref() }
839     }
840 }
841 
842 impl<T> DerefMut for BqlRefMut<'_, T> {
843     #[inline]
844     fn deref_mut(&mut self) -> &mut T {
845         // SAFETY: the value is accessible as long as we hold our borrow.
846         unsafe { self.value.as_mut() }
847     }
848 }
849 
850 impl<T: fmt::Debug> fmt::Debug for BqlRefMut<'_, T> {
851     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
852         (**self).fmt(f)
853     }
854 }
855 
856 impl<T: fmt::Display> fmt::Display for BqlRefMut<'_, T> {
857     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
858         (**self).fmt(f)
859     }
860 }
861