use crate::prelude::*;
use crate::{
ops::TypedOp as Op,
trace,
trace::Tracer,
util::{bi_enum, deref},
};
use alloc::borrow::Cow;
use core::{
alloc::Layout,
any::{Any, TypeId},
hint::unreachable_unchecked,
marker::PhantomData,
mem::size_of,
ops::{Add, AddAssign, Deref, DerefMut},
};
use nohash_hasher::{IntMap, IsEnabled};
#[cfg(feature = "_fuzz")]
use crate::fuzz as atomic;
#[cfg(not(feature = "_fuzz"))]
use core::sync::atomic;
#[cfg(feature = "_fuzz")]
use crate::fuzz::spin_loop;
#[cfg(not(feature = "_fuzz"))]
fn spin_loop() {}
use atomic::{AtomicU64, Ordering::Relaxed};
use Tag::*;
mod addr;
mod allocator;
mod def;
mod dyn_net;
mod instruction;
mod interact;
mod linker;
mod net;
mod node;
mod parallel;
mod port;
mod wire;
pub use addr::*;
pub use allocator::*;
pub use def::*;
pub use dyn_net::*;
pub use instruction::*;
pub use linker::*;
pub use net::*;
pub use node::*;
pub use port::*;
pub use wire::*;
pub type Lab = u16;
pub unsafe trait Mode: Send + Sync + 'static {
const LAZY: bool;
}
pub struct Strict;
unsafe impl Mode for Strict {
const LAZY: bool = false;
}
pub struct Lazy;
unsafe impl Mode for Lazy {
const LAZY: bool = true;
}
#[derive(Clone, Copy, Debug, Default)]
pub struct Rewrites<T = u64> {
pub anni: T,
pub comm: T,
pub eras: T,
pub dref: T,
pub oper: T,
}
type AtomicRewrites = Rewrites<AtomicU64>;
impl Rewrites {
pub fn add_to(&self, target: &AtomicRewrites) {
target.anni.fetch_add(self.anni, Relaxed);
target.comm.fetch_add(self.comm, Relaxed);
target.eras.fetch_add(self.eras, Relaxed);
target.dref.fetch_add(self.dref, Relaxed);
target.oper.fetch_add(self.oper, Relaxed);
}
pub fn total(&self) -> u64 {
self.anni + self.comm + self.eras + self.dref + self.oper
}
}
impl AtomicRewrites {
pub fn add_to(&self, target: &mut Rewrites) {
target.anni += self.anni.load(Relaxed);
target.comm += self.comm.load(Relaxed);
target.eras += self.eras.load(Relaxed);
target.dref += self.dref.load(Relaxed);
target.oper += self.oper.load(Relaxed);
}
}
impl<T: Add> Add for Rewrites<T> {
type Output = Rewrites<T::Output>;
fn add(self, rhs: Self) -> Self::Output {
Rewrites {
anni: self.anni + rhs.anni,
comm: self.comm + rhs.comm,
eras: self.eras + rhs.eras,
dref: self.dref + rhs.dref,
oper: self.oper + rhs.oper,
}
}
}
impl<T: AddAssign> AddAssign for Rewrites<T> {
fn add_assign(&mut self, rhs: Self) {
self.anni += rhs.anni;
self.comm += rhs.comm;
self.eras += rhs.eras;
self.dref += rhs.dref;
self.oper += rhs.oper;
}
}