diff mbox

[12/15] openpic: IRQ_check: search the queue a word at a time

Message ID 1356142552-13453-13-git-send-email-scottwood@freescale.com
State New
Headers show

Commit Message

Scott Wood Dec. 22, 2012, 2:15 a.m. UTC
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 <scottwood@freescale.com>
---
 hw/openpic.c |   28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

Comments

Alexander Graf Jan. 3, 2013, 6:53 p.m. UTC | #1
On 22.12.2012, at 03:15, Scott Wood wrote:

> 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 <scottwood@freescale.com>

What we really want is a bitmap wide ffs() bipops helper function that returns the first set bit in a bitmap and can optimize the hell out of that operation inside of itself. I don't think this belongs to the OpenPIC code.


Alex

> ---
> 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
> 
>
diff mbox

Patch

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;
 }