1use core::{
6 cell::UnsafeCell,
7 sync::atomic::{AtomicUsize, Ordering},
8};
9
10pub trait Head {
13 fn num_bytes_used(&self) -> usize;
14 fn bump(&self, inc: usize);
15 fn set(&self, v: usize);
16}
17
18pub struct ThreadSafeHead(AtomicUsize);
19
20impl ThreadSafeHead {
21 pub const fn new() -> Self {
22 ThreadSafeHead(AtomicUsize::new(0))
23 }
24}
25
26impl Head for ThreadSafeHead {
27 fn num_bytes_used(&self) -> usize {
28 self.0.load(Ordering::SeqCst)
29 }
30
31 fn bump(&self, inc: usize) {
32 self.0.fetch_add(inc, Ordering::SeqCst);
33 }
34
35 fn set(&self, v: usize) {
36 self.0.store(v, Ordering::SeqCst);
37 }
38}
39
40impl Default for ThreadSafeHead {
41 fn default() -> Self {
42 ThreadSafeHead(AtomicUsize::new(0))
43 }
44}
45
46pub struct SingleThreadedHead(UnsafeCell<usize>);
47
48unsafe impl Sync for SingleThreadedHead {}
49
50impl SingleThreadedHead {
51 pub const fn new() -> Self {
52 SingleThreadedHead(UnsafeCell::new(0))
53 }
54}
55
56impl Head for SingleThreadedHead {
57 fn num_bytes_used(&self) -> usize {
58 unsafe { *self.0.get() }
59 }
60
61 fn bump(&self, inc: usize) {
62 unsafe {
63 *self.0.get() = self.num_bytes_used() + inc;
64 }
65 }
66
67 fn set(&self, v: usize) {
68 unsafe {
69 *self.0.get() = v;
70 }
71 }
72}
73
74impl Default for SingleThreadedHead {
75 fn default() -> Self {
76 SingleThreadedHead(UnsafeCell::new(0))
77 }
78}