Search the queue more efficiently by first looking for a non-zero word, and then using the common bit-searching function to find the bit within the word. It would be even nicer if bitops_ffsl() could be hooked up to the compiler intrinsic so that bit-searching instructions could be used, but that's another matter.
Signed-off-by: Scott Wood <scottw...@freescale.com> --- hw/openpic.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/hw/openpic.c b/hw/openpic.c index f2ac286..5accff5 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -270,21 +270,35 @@ static inline int IRQ_testbit(IRQ_queue_t *q, int n_IRQ) static void IRQ_check(OpenPICState *opp, IRQ_queue_t *q) { - int next, i; + int next, word, irq, base; int priority; next = -1; priority = -1; - for (i = 0; i < opp->max_irq; i++) { - if (IRQ_testbit(q, i)) { + + for (word = 0, base = 0; word < ARRAY_SIZE(q->queue); + word++, base += BITS_PER_LONG) { + unsigned long map = q->queue[word]; + + if (!map) { + continue; + } + + while (map) { + int offset = bitops_ffsl(map); + irq = base + offset; + map &= ~(1UL << offset); + DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n", - i, IVPR_PRIORITY(opp->src[i].ivpr), priority); - if (IVPR_PRIORITY(opp->src[i].ivpr) > priority) { - next = i; - priority = IVPR_PRIORITY(opp->src[i].ivpr); + irq, IVPR_PRIORITY(opp->src[irq].ivpr), priority); + + if (IVPR_PRIORITY(opp->src[irq].ivpr) > priority) { + next = irq; + priority = IVPR_PRIORITY(opp->src[irq].ivpr); } } } + q->next = next; q->priority = priority; } -- 1.7.9.5