FreeBSD/sys/netpfil/ipfw/dn_sched_fq_pie.c
/*
 * Dequeue a packet from an appropriate queue according to
 * FQ-CoDel algorithm.
 */
Dequeue a packet from an appropriate queue according to
FQ-CoDel algorithm.
Dequeue a packet from an appropriate queue according to FQ - CoDel algorithm .
static struct mbuf *
fq_pie_dequeue(struct dn_sch_inst *_si)
{ 
	struct fq_pie_si *si;
	struct fq_pie_schk *schk;
	struct dn_sch_fq_pie_parms *param;
	struct fq_pie_flow *f;
	struct mbuf *mbuf;
	struct fq_pie_list *fq_pie_flowlist;
	si = (struct fq_pie_si *)_si;
	schk = (struct fq_pie_schk *)(si->_si.sched+1);
	param = &schk->cfg;
	do {
		if (STAILQ_EMPTY(&si->newflows))
			fq_pie_flowlist = &si->oldflows;
		else
			fq_pie_flowlist = &si->newflows;
		if (STAILQ_EMPTY(fq_pie_flowlist)) 
			return NULL;
		f = STAILQ_FIRST(fq_pie_flowlist);
		while (f != NULL)	{
			if (f->deficit < 0) {
				 f->deficit += param->quantum;
				 STAILQ_REMOVE_HEAD(fq_pie_flowlist, flowchain);
				 STAILQ_INSERT_TAIL(&si->oldflows, f, flowchain);
			 } else 
				 break;
			f = STAILQ_FIRST(fq_pie_flowlist);
		}
		if (STAILQ_EMPTY(fq_pie_flowlist)) 
			continue;
		mbuf = pie_dequeue(f, si);
		if (!mbuf) {
			if (fq_pie_flowlist == &si->newflows) {
				STAILQ_REMOVE_HEAD(fq_pie_flowlist, flowchain);
				STAILQ_INSERT_TAIL(&si->oldflows, f, flowchain);
			}	else {
				f->active = 0;
				fq_deactivate_pie(&f->pst);
				STAILQ_REMOVE_HEAD(fq_pie_flowlist, flowchain);
			}
			continue;
		}
		f->deficit -= mbuf->m_pkthdr.len;
		return mbuf;
	} while (1);
	return NULL;
}
static struct mbuf * fq_pie_dequeue ( struct dn_sch_inst * _si ) { struct fq_pie_si * si ; struct fq_pie_schk * schk ; struct dn_sch_fq_pie_parms * param ; struct fq_pie_flow * f ; struct mbuf * mbuf ; struct fq_pie_list * fq_pie_flowlist ; si = ( struct fq_pie_si * ) _si ; schk = ( struct fq_pie_schk * ) ( si -> _si . sched + 1 ) ; param = & schk -> cfg ; do { if ( STAILQ_EMPTY ( & si -> newflows ) ) fq_pie_flowlist = & si -> oldflows ; else fq_pie_flowlist = & si -> newflows ; if ( STAILQ_EMPTY ( fq_pie_flowlist ) ) return NULL ; f = STAILQ_FIRST ( fq_pie_flowlist ) ; while ( f != NULL ) { if ( f -> deficit < 0 ) { f -> deficit += param -> quantum ; STAILQ_REMOVE_HEAD ( fq_pie_flowlist , flowchain ) ; STAILQ_INSERT_TAIL ( & si -> oldflows , f , flowchain ) ; } else break ; f = STAILQ_FIRST ( fq_pie_flowlist ) ; } if ( STAILQ_EMPTY ( fq_pie_flowlist ) ) continue ; mbuf = pie_dequeue ( f , si ) ; if ( ! mbuf ) { if ( fq_pie_flowlist == & si -> newflows ) { STAILQ_REMOVE_HEAD ( fq_pie_flowlist , flowchain ) ; STAILQ_INSERT_TAIL ( & si -> oldflows , f , flowchain ) ; } else { f -> active = 0 ; fq_deactivate_pie ( & f -> pst ) ; STAILQ_REMOVE_HEAD ( fq_pie_flowlist , flowchain ) ; } continue ; } f -> deficit -= mbuf -> m_pkthdr . len ; return mbuf ; } while ( 1 ) ; return NULL ; }
Dequeue a packet from an appropriate queue according to
 FQ-CoDel algorithm.
Dequeue a packet from an appropriate queue according to FQ - CoDel algorithm .
/* select a list to start with */ /* Both new and old queue lists are empty, return NULL */ /* if there is no flow(sub-queue) deficit, increase deficit
			 * by quantum, move the flow to the tail of old flows list
			 * and try another flow.
			 * Otherwise, the flow will be used for dequeue.
			 */ /* the new flows list is empty, try old flows list */ /* Dequeue a packet from the selected flow */ /* pie did not return a packet */ /* If the selected flow belongs to new flows list, then move 
			 * it to the tail of old flows list. Otherwise, deactivate it and
			 * remove it from the old list and
			 */ /* start again */ /* we have a packet to return, 
		 * update flow deficit and return the packet*/ /* unreachable point */