pub use quantifiable_derive::Quantifiable;
use std::rc::Rc;
use std::cell::RefCell;
use std::ops::Deref;
use crate::routing::RoutingInfo;
#[derive(Quantifiable)]
#[derive(Debug)]
pub struct Phit
{
pub packet: PacketRef,
pub index: usize,
pub virtual_channel: RefCell<Option<usize>>,
}
#[derive(Quantifiable)]
#[derive(Debug,Default)]
pub struct PacketExtraInfo
{
pub link_classes: Vec<usize>,
pub entry_virtual_channels: Vec<Option<usize>>,
pub cycle_per_hop: Vec<usize>,
}
#[derive(Quantifiable)]
#[derive(Debug)]
pub struct Packet
{
pub size: usize,
pub routing_info: RefCell<RoutingInfo>,
pub message: Rc<Message>,
pub index: usize,
pub cycle_into_network: RefCell<usize>,
pub extra: RefCell<Option<PacketExtraInfo>>,
}
#[cfg(feature="slab_packet")]
thread_local!{
static PACKET_SLAB : RefCell<slab::Slab<Packet>> = RefCell::new(slab::Slab::new());
}
impl Packet
{
#[cfg(not(any(feature="raw_packet",feature="slab_packet")))]
pub fn into_ref(self) -> PacketRef {
PacketRef{inner:Rc::new(self)}
}
#[cfg(feature="raw_packet")]
pub fn into_ref(self) -> PacketRef {
let packet = Box::into_raw(Box::new(self));
let inner = PacketRefInner{ packet };
PacketRef {
inner
}
}
#[cfg(feature="slab_packet")]
pub fn into_ref(self) -> PacketRef {
let packet = PACKET_SLAB.with(|slab| {slab.borrow_mut().insert(self) });
let inner = PacketRefInner{ packet };
PacketRef {
inner
}
}
}
#[derive(Quantifiable)]
#[derive(Debug)]
pub struct Message
{
pub origin: usize,
pub destination: usize,
pub size: usize,
pub creation_cycle: usize,
}
impl Phit
{
pub fn is_begin(&self) -> bool
{
self.index==0
}
pub fn is_end(&self) -> bool
{
self.index==self.packet.size-1
}
}
#[derive(Debug,Clone,Quantifiable)]
pub struct PacketRef {
inner: PacketRefInner
}
impl PacketRef
{
#[cfg(not(any(feature="raw_packet",feature="slab_packet")))]
pub fn destroy(&self)
{
}
#[cfg(feature="raw_packet")]
pub fn destroy(&self)
{
let _boxed = unsafe { Box::from_raw(self.inner.packet as *mut Packet) };
}
#[cfg(feature="slab_packet")]
pub fn destroy(&self)
{
let _packet = PACKET_SLAB.with(|slab|slab.borrow_mut().remove(self.inner.packet));
}
}
#[cfg(not(any(feature="raw_packet",feature="slab_packet")))]
pub type PacketRefInner = Rc<Packet>;
#[cfg(feature="raw_packet")]
#[derive(Debug,Clone,Quantifiable)]
pub struct PacketRefInner {
packet: *const Packet,
}
#[cfg(feature="slab_packet")]
#[derive(Debug,Clone,Quantifiable)]
pub struct PacketRefInner {
packet: usize,
}
impl Deref for PacketRef {
type Target = Packet;
#[cfg(not(any(feature="raw_packet",feature="slab_packet")))]
fn deref(&self) -> &<Self as Deref>::Target
{
&*self.inner
}
#[cfg(feature="raw_packet")]
fn deref(&self) -> &<Self as Deref>::Target
{
unsafe {
&*self.inner.packet
}
}
#[cfg(feature="slab_packet")]
fn deref(&self) -> &<Self as Deref>::Target
{
let packet = self.inner.packet;
let pt_packet: *const Packet = PACKET_SLAB.with(|slab|slab.borrow().get(packet).expect("The packet is not in the slab.") as *const Packet);
unsafe {
&*pt_packet
}
}
}
impl AsRef<Packet> for PacketRef {
fn as_ref(&self) -> &Packet { &*self }
}