Esempio n. 1
0
static int
rr_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
{
	struct rr_si *si;
	struct rr_queue *rrq;

	if (m != q->mq.head) {
		if (dn_enqueue(q, m, 0)) /* packet was dropped */
			return 1;
		if (m != q->mq.head)
			return 0;
	}

	/* If reach this point, queue q was idle */
	si = (struct rr_si *)(_si + 1);
	rrq = (struct rr_queue *)q;

	if (rrq->status == 1) /* Queue is already in the queue list */
		return 0;

	/* Insert the queue in the queue list */
	rr_append(rrq, si);

	return 0;
}
Esempio n. 2
0
/*
 * This file implements a FIFO scheduler for a single queue.
 * The queue is allocated as part of the scheduler instance,
 * and there is a single flowset is in the template which stores
 * queue size and policy.
 * Enqueue and dequeue use the default library functions.
 */
static int 
fifo_enqueue(struct dn_sch_inst *si, struct dn_queue *q, struct mbuf *m)
{
	/* XXX if called with q != NULL and m=NULL, this is a
	 * re-enqueue from an existing scheduler, which we should
	 * handle.
	 */
	return dn_enqueue((struct dn_queue *)(si+1), m, 0);
}
Esempio n. 3
0
static int
wf2qp_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
{
    struct dn_fsk *fs = q->fs;
    struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
    struct wf2qp_queue *alg_fq;
    uint64_t len = m->m_pkthdr.len;

    if (m != q->mq.head) {
	if (dn_enqueue(q, m, 0)) /* packet was dropped */
	    return 1;
	if (m != q->mq.head)	/* queue was already busy */
	    return 0;
    }

    /* If reach this point, queue q was idle */
    alg_fq = (struct wf2qp_queue *)q;

    if (DN_KEY_LT(alg_fq->F, alg_fq->S)) {
        /* F<S means timestamps are invalid ->brand new queue. */
        alg_fq->S = si->V;		/* init start time */
        si->wsum += fs->fs.par[0];	/* add weight of new queue. */
	si->inv_wsum = ONE_FP/si->wsum;
    } else { /* if it was idle then it was in the idle heap */
        heap_extract(&si->idle_heap, q);
        alg_fq->S = MAX64(alg_fq->F, si->V);	/* compute new S */
    }
    alg_fq->F = alg_fq->S + len * alg_fq->inv_w;

    /* if nothing is backlogged, make sure this flow is eligible */
    if (si->ne_heap.elements == 0 && si->sch_heap.elements == 0)
        si->V = MAX64(alg_fq->S, si->V);

    /*
     * Look at eligibility. A flow is not eligibile if S>V (when
     * this happens, it means that there is some other flow already
     * scheduled for the same pipe, so the sch_heap cannot be
     * empty). If the flow is not eligible we just store it in the
     * ne_heap. Otherwise, we store in the sch_heap.
     * Note that for all flows in sch_heap (SCH), S_i <= V,
     * and for all flows in ne_heap (NEH), S_i > V.
     * So when we need to compute max(V, min(S_i)) forall i in
     * SCH+NEH, we only need to look into NEH.
     */
    if (DN_KEY_LT(si->V, alg_fq->S)) {
        /* S>V means flow Not eligible. */
        if (si->sch_heap.elements == 0)
            D("++ ouch! not eligible but empty scheduler!");
        heap_insert(&si->ne_heap, alg_fq->S, q);
    } else {
        heap_insert(&si->sch_heap, alg_fq->F, q);
    }
    return 0;
}
Esempio n. 4
0
/*
 * If a queue with the same priority is already backlogged, use
 * that one instead of the queue passed as argument.
 */
static int 
prio_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
{
	struct prio_si *si = (struct prio_si *)(_si + 1);
	int prio = q->fs->fs.par[0];

	if (test_bit(prio, &si->bitmap) == 0) {
		/* No queue with this priority, insert */
		__set_bit(prio, &si->bitmap);
		si->q_array[prio] = q;
	} else { /* use the existing queue */
		q = si->q_array[prio];
	}
	if (dn_enqueue(q, m, 0))
		return 1;
	return 0;
}