//@C Copyright Notice //@C ================ //@C This file is part of CPSW. It is subject to the license terms in the LICENSE.txt //@C file found in the top-level directory of this distribution and at //@C https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. //@C //@C No part of CPSW, including this file, may be copied, modified, propagated, or //@C distributed except according to the terms contained in the LICENSE.txt file. #ifndef CPSW_PROTO_MOD_DEPACK_H #define CPSW_PROTO_MOD_DEPACK_H #include #include #include #include #include #include using boost::atomic; using boost::memory_order_relaxed; using std::vector; typedef unsigned FrameID; typedef unsigned FragID; typedef unsigned ProtoVersion; class CProtoModDepack; typedef shared_ptr ProtoModDepack; class IProtoModDepack : public virtual IProtoMod { }; class CAxisFrameHeader { private: FrameID frameNo_; FragID fragNo_; ProtoVersion vers_; uint8_t tDest_; uint8_t tId_; uint8_t tUsr1_; public: static const unsigned VERSION_BIT_OFFSET = 0; static const unsigned VERSION_BIT_SIZE = 4; static const unsigned FRAME_NO_BIT_OFFSET = 4; static const unsigned FRAME_NO_BIT_SIZE = 12; static const unsigned FRAG_NO_BIT_OFFSET = 16; static const unsigned FRAG_NO_BIT_SIZE = 24; static const unsigned FRAG_MAX = (1< frameNo_; public: CAxisFrameNoAllocator() :frameNo_(0) { } FrameID newFrameID() { FrameID id; unsigned shft = (8*sizeof(FrameID)-FRAME_NO_BIT_SIZE); id = frameNo_.fetch_add( (1<> shft; return id & ((1<> VERSION_BIT_OFFSET) & ( (1< fragWin_; bool isComplete_; bool running_; CFrame(unsigned winSize) :nFrags_( 0 ), frameID_( NO_FRAME ), oldestFrag_( 0 ), lastFrag_( NO_FRAG ), fragWin_( winSize ), isComplete_( false ), running_( false ) { } bool isComplete() { return isComplete_; } void release(unsigned *ctr); void updateChain(); friend class CProtoModDepack; }; class CProtoModDepack : public CProtoMod, public CRunnable { private: unsigned badHeaderDrops_; unsigned oldFrameDrops_; unsigned newFrameDrops_; unsigned oldFragDrops_; unsigned newFragDrops_; unsigned duplicateFragDrops_; unsigned duplicateLastSeen_; unsigned noLastSeen_; unsigned fragsAccepted_; unsigned framesAccepted_; unsigned oqueueFullDrops_; unsigned evictedFrames_; unsigned incompleteDrops_; unsigned emptyDrops_; unsigned timedOutFrames_; unsigned pastLastDrops_; CTimeout timeout_; CAxisFrameHeader::CAxisFrameNoAllocator frameIdGen_; protected: unsigned frameWinSize_; unsigned fragWinSize_; FrameID oldestFrame_; vector frameWin_; virtual void processBuffer(BufChain); virtual void frameSync(CAxisFrameHeader *); virtual void* threadBody(); virtual void modStartup(); virtual void modShutdown(); virtual void releaseFrames(bool onlyComplete); virtual bool releaseOldestFrame(bool onlyComplete); virtual BufChain processOutput(BufChain bc); virtual void startTimeout(CFrame *frame); virtual unsigned toFrameIdx(unsigned frameNo) { return frameNo & ( frameWinSize_ - 1 ); } virtual unsigned toFragIdx(unsigned fragNo) { return fragNo & ( fragWinSize_ - 1 ); } virtual int iMatch(ProtoPortMatchParams *cmp); CProtoModDepack( CProtoModDepack &orig, Key &k ); public: CProtoModDepack(Key &k, unsigned oqueueDepth, unsigned ldFrameWinSize, unsigned ldFragWinSize, CTimeout timeout); virtual ~CProtoModDepack(); virtual void dumpInfo(FILE *f); virtual CProtoModDepack * clone(Key &k) { return new CProtoModDepack( *this, k ); } virtual const char *getName() const { return "AXIS Depack"; } virtual void dumpYaml(YAML::Node &node) const; }; #endif