PacketPool

Files CCore/inc/PacketPool.h CCore/src/PacketPool.cpp

The class PacketPool implements a pool of packets. There is the default global packet pool in the CCore. Two global constants PacketPool_PacketCount and PacketPool_PacketMaxDataLen determine properties of this pool. You may override these constants by defining them in you project. Default values are provided by the target as DefaultPacketCount and DefaultPacketMaxDataLen.

The following global pool functions are to work with raw packets.


PacketHeader * TryAllocPacket_raw();

PacketHeader * AllocPacket_raw(); // may return 0

PacketHeader * AllocPacket_raw(MSec timeout);

PacketHeader * AllocPacket_raw(TimeScope time_scope);

PacketHeader * TryAllocPacket_raw_short();

PacketHeader * AllocPacket_raw_short(); // never return 0

PacketHeader * AllocPacket_raw_short(MSec timeout);

PacketHeader * AllocPacket_raw_short(TimeScope time_scope);

void DetachPacketBufs();

TryAllocPacket_raw() is a non-blocking allocation function. If the operation has failed, the return pointer is null. The packet is a "long" packet, i.e. has an attached data buffer. The length of the buffer is PacketPool_PacketMaxDataLen.

AllocPacket_raw() is a blocking allocation function. It blocks while packet pool is empty. Once a packet becomes available it tries to attach a data buffer and return this packet. If this failed, the return pointer is null. So, despite the function is blocking, it still may return a null pointer.

AllocPacket_raw(MSec) and AllocPacket_raw(TimeScope) are timed variants of the AllocPacket_raw(). In case of timeout the null pointer is returned.

There are "short" variants of four functions, mentioned above. They allocate a "short" packet, i.e. this packet does not necessary has an attached data buffer (but may have). AllocPacket_raw_short() never returns null, because of this.

DetachPacketBufs() detaches data buffers from all packets in the pool.

There is no "free" function, because you return a packet back to the pool, when you complete it. Initially pool has a PacketPool_PacketCount packets without attached data buffers.

And there are functions to work with specialized packets. They are direct calls of the correspondent raw functions.


template <class POD>
Packet<POD> TryAllocPacket() { return TryAllocPacket_raw(); }
 
template <class POD>
Packet<POD> AllocPacket() { return AllocPacket_raw(); } // may return 0
 
template <class POD>
Packet<POD> AllocPacket(MSec timeout) { return AllocPacket_raw(timeout); }
 
template <class POD>
Packet<POD> AllocPacket(TimeScope time_scope) { return AllocPacket_raw(time_scope); }
                                                                       
template <class POD>
Packet<POD> TryAllocPacket_short() { return TryAllocPacket_raw_short(); }
 
template <class POD>
Packet<POD> AllocPacket_short() { return AllocPacket_raw_short(); } // never return 0
 
template <class POD>
Packet<POD> AllocPacket_short(MSec timeout) { return AllocPacket_raw_short(timeout); }
 
template <class POD>
Packet<POD> AllocPacket_short(TimeScope time_scope) { return AllocPacket_raw_short(time_scope); }

PacketPool

Here is the PacketPoll class itself. On XCore you may use its methods only in a task context. So you cannot complete a packet in the interrupt context.

The allocation method semantic is the same as of global functions above.

The name is used to name internal synchronization objects.

Internally all packets are stores in a list. Packets with an attached data buffer goes first.

Destructor calls Abort(), if not all packets are released at the moment.


class PacketPool : public Funchor_nocopy
 {
   ....

  public:
   
   // constructors
  
   explicit PacketPool(ulen count,ulen max_data_len=DefaultPacketMaxDataLen);
   
   PacketPool(TextLabel name,ulen count,ulen max_data_len=DefaultPacketMaxDataLen);
   
   ~PacketPool();
   
   // get
   
   PacketHeader * try_get();
   
   PacketHeader * get(); // may return 0
   
   PacketHeader * get(MSec timeout);
   
   PacketHeader * get(TimeScope time_scope);
   
   // get_short
   
   PacketHeader * try_get_short();
   
   PacketHeader * get_short(); // never return 0
   
   PacketHeader * get_short(MSec timeout);
   
   PacketHeader * get_short(TimeScope time_scope);
   
   // detachBufs
   
   void detachBufs();
 };