From 4045b6a2e9352030c6eb8f9ce22d5df7e16421e8 Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Thu, 23 Feb 2017 10:50:18 +0000 Subject: [PATCH] irq: Small cleanup Also, try to find an empty slot in the pool when adding an IRQ Signed-off-by: Michel Pollet --- simavr/sim/sim_irq.c | 23 +++++++++++++++-------- simavr/sim/sim_irq.h | 12 ++++++------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/simavr/sim/sim_irq.c b/simavr/sim/sim_irq.c index 16e3418..d0148a0 100644 --- a/simavr/sim/sim_irq.c +++ b/simavr/sim/sim_irq.c @@ -28,7 +28,7 @@ typedef struct avr_irq_hook_t { struct avr_irq_hook_t * next; int busy; // prevent reentrance of callbacks - + struct avr_irq_t * chain; // raise the IRQ on this too - optional if "notify" is on avr_irq_notify_t notify; // called when IRQ is raised - optional if "chain" is on void * param; // "notify" parameter @@ -39,11 +39,18 @@ _avr_irq_pool_add( avr_irq_pool_t * pool, avr_irq_t * irq) { - if ((pool->count & 0xf) == 0) { - pool->irq = (avr_irq_t**)realloc(pool->irq, - (pool->count + 16) * sizeof(avr_irq_t *)); + int insert = 0; + /* lookup a slot */ + for (; insert < pool->count && pool->irq[insert]; insert++) + ; + if (insert == pool->count) { + if ((pool->count & 0xf) == 0) { + pool->irq = (avr_irq_t**)realloc(pool->irq, + (pool->count + 16) * sizeof(avr_irq_t *)); + } + pool->count++; } - pool->irq[pool->count++] = irq; + pool->irq[insert] = irq; irq->pool = pool; } @@ -92,7 +99,7 @@ avr_alloc_irq( avr_irq_t * irq = (avr_irq_t*)malloc(sizeof(avr_irq_t) * count); avr_init_irq(pool, irq, base, count, names); for (int i = 0; i < count; i++) - irq[i].flags |= IRQ_FLAG_ALLOC; + irq[i].flags |= IRQ_FLAG_ALLOC; return irq; } @@ -143,7 +150,7 @@ avr_irq_register_notify( { if (!irq || !notify) return; - + avr_irq_hook_t *hook = irq->hook; while (hook) { if (hook->notify == notify && hook->param == param) @@ -205,7 +212,7 @@ avr_raise_irq( if (hook->chain) avr_raise_irq(hook->chain, output); hook->busy--; - } + } hook = next; } // the value is set after the callbacks are called, so the callbacks diff --git a/simavr/sim/sim_irq.h b/simavr/sim/sim_irq.h index d3ac30b..bf02a35 100644 --- a/simavr/sim/sim_irq.h +++ b/simavr/sim/sim_irq.h @@ -30,16 +30,16 @@ extern "C" { /* * Internal IRQ system - * + * * This subsystem allows any piece of code to "register" a hook to be called when an IRQ is * raised. The IRQ definition is up to the module defining it, for example a IOPORT pin change * might be an IRQ in which case any piece of code can be notified when a pin has changed state - * + * * The notify hooks are chained, and duplicates are filtered out so you can't register a * notify hook twice on one particular IRQ - * + * * IRQ calling order is not defined, so don't rely on it. - * + * * IRQ hook needs to be registered in reset() handlers, ie after all modules init() bits * have been called, to prevent race condition of the initialization order. */ @@ -70,8 +70,8 @@ typedef struct avr_irq_pool_t { * Public IRQ structure */ typedef struct avr_irq_t { - struct avr_irq_pool_t * pool; // TODO: migration in progress - const char * name; + struct avr_irq_pool_t * pool; + const char * name; uint32_t irq; //!< any value the user needs uint32_t value; //!< current value uint8_t flags; //!< IRQ_* flags -- 2.39.5