package ejip123; /** A pool of packets. Encapsulates the access to the static packet buffers. */ public class PacketPool{ private static int CNT = 0; private static final Object mutex = new Object(); private static Packet[] packets; /** Size of packet buffers in bytes. */ private static int BUF_SIZE; private PacketPool(){ } /** Allocates a number of packet buffers. @param cnt Number of packet buffers. Defaults to 8, if <=0. @param size Size of a buffer. Must be a multiple of 4. Defaults to 1500, if <=0. */ public static void init(int cnt, int size){ synchronized(mutex){ CNT = (cnt <= 0) ? 8 : cnt; packets = new Packet[CNT]; BUF_SIZE = (size <= 0) ? 1500 : size; for(int i = 0; i < CNT; ++i){ packets[i] = new Packet(BUF_SIZE); } } } /** Fetches a free packet and sets it to allocated. @return An allocated Packet or null if there are no free packets atm. */ public static Packet getFreshPacket(){ synchronized(mutex){ for(int i = 0; i < CNT; ++i){ Packet p = packets[i]; if(p.testSetStatus(Packet.FREE, Packet.ALLOC)){ return p; } } } //Dbg.wr('!'); return null; } /** Fetches a received packet (that was processed by a link layer) and sets it to allocated. @return An allocated Packet or null if there are no free packets atm. */ public static Packet getReceivedPacket(){ // TODO: we may wanna start the search not at 0 all the time... // packets may starve in the higher slots because new packets arrive and get inserted and processed in the low slots. synchronized(mutex){ for(int i = 0; i < CNT; ++i){ Packet p = packets[i]; if(p.testSetStatus(Packet.RCV, Packet.ALLOC)){ return p; } } } return null; } /** Allocates a free packet and sets its link layer. @param linkLayer The LinkLayer. @return The changed packet or null, if there are no free packets. */ static Packet getFreshRcvPacket(LinkLayer linkLayer){ Packet p = getFreshPacket(); if(p != null){ // Dbg.wr("R "); p.setLinkLayer(linkLayer); } return p; } /** Gets packet ready to be sent. @param ll The LinkLayer through which this packet will be sent. @return a Packet */ public static Packet getTxPacket(LinkLayer ll){ synchronized(mutex){ for(int i = 0; i < CNT; ++i){ Packet p = packets[i]; if(p.linkLayer() == ll && (p.status() == Packet.DGRAM_RDY || p.status() == Packet.CON_RDY)){ return p; } } } return null; } public static int PACKET_CNT(){ return CNT; } public static int PACKET_SIZE(){ return BUF_SIZE; } }