FreeBSD/sys/netpfil/ipfw/ip_dn_io.c
/*
 * Send traffic from a scheduler instance due by 'now'.
 * Return a pointer to the head of the queue.
 */
Send traffic from a scheduler instance due by 'now'.
Return a pointer to the head of the queue.
Send traffic from a scheduler instance due by ' now ' . Return a pointer to the head of the queue .
static struct mbuf *
serve_sched(struct mq *q, struct dn_sch_inst *si, uint64_t now)
{
	struct mq def_q;
	struct dn_schk *s = si->sched;
	struct mbuf *m = NULL;
	int delay_line_idle = (si->dline.mq.head == NULL);
	int done, bw;
	if (q == NULL) {
		q = &def_q;
		q->head = NULL;
	}
	bw = s->link.bandwidth;
	si->kflags &= ~DN_ACTIVE;
	if (bw > 0)
		si->credit += (now - si->sched_time) * bw;
	else
		si->credit = 0;
	si->sched_time = now;
	done = 0;
	while (si->credit >= 0 && (m = s->fp->dequeue(si)) != NULL) {
		uint64_t len_scaled;
		done++;
		len_scaled = (bw == 0) ? 0 : hz *
			(m->m_pkthdr.len * 8 + extra_bits(m, s));
		si->credit -= len_scaled;
		dn_tag_get(m)->output_time = dn_cfg.curr_time + s->link.delay ;
		mq_append(&si->dline.mq, m);
	}
	if (si->credit >= 0) {
		si->idle_time = now;
	} else {
		uint64_t t;
		KASSERT (bw > 0, ("bw=0 and credit<0 ?"));
		t = div64(bw - 1 - si->credit, bw);
		if (m)
			dn_tag_get(m)->output_time += t;
		si->kflags |= DN_ACTIVE;
		heap_insert(&dn_cfg.evheap, now + t, si);
	}
	if (delay_line_idle && done)
		transmit_event(q, &si->dline, now);
	return q->head;
}
static struct mbuf * serve_sched ( struct mq * q , struct dn_sch_inst * si , uint64_t now ) { struct mq def_q ; struct dn_schk * s = si -> sched ; struct mbuf * m = NULL ; int delay_line_idle = ( si -> dline . mq . head == NULL ) ; int done , bw ; if ( q == NULL ) { q = & def_q ; q -> head = NULL ; } bw = s -> link . bandwidth ; si -> kflags &= ~ DN_ACTIVE ; if ( bw > 0 ) si -> credit += ( now - si -> sched_time ) * bw ; else si -> credit = 0 ; si -> sched_time = now ; done = 0 ; while ( si -> credit >= 0 && ( m = s -> fp -> dequeue ( si ) ) != NULL ) { uint64_t len_scaled ; done ++ ; len_scaled = ( bw == 0 ) ? 0 : hz * ( m -> m_pkthdr . len * 8 + extra_bits ( m , s ) ) ; si -> credit -= len_scaled ; dn_tag_get ( m ) -> output_time = dn_cfg . curr_time + s -> link . delay ; mq_append ( & si -> dline . mq , m ) ; } if ( si -> credit >= 0 ) { si -> idle_time = now ; } else { uint64_t t ; KASSERT ( bw > 0 , ( " " ) ) ; t = div64 ( bw - 1 - si -> credit , bw ) ; if ( m ) dn_tag_get ( m ) -> output_time += t ; si -> kflags |= DN_ACTIVE ; heap_insert ( & dn_cfg . evheap , now + t , si ) ; } if ( delay_line_idle && done ) transmit_event ( q , & si -> dline , now ) ; return q -> head ; }
Send traffic from a scheduler instance due by 'now'.
Send traffic from a scheduler instance due by ' now ' .
/* Move packet in the delay line */ /*
	 * If credit >= 0 the instance is idle, mark time.
	 * Otherwise put back in the heap, and adjust the output
	 * time of the last inserted packet, m, which was too early.
	 */