Commit 4045b6a2e9352030c6eb8f9ce22d5df7e16421e8
authorMichel Pollet <buserror@gmail.com>
Thu, 23 Feb 2017 10:50:18 +0000 (10:50 +0000)
committerMichel Pollet <buserror@gmail.com>
Thu, 2 Mar 2017 17:31:15 +0000 (17:31 +0000)
Also, try to find an empty slot in the pool when adding an IRQ

Signed-off-by: Michel Pollet <buserror@gmail.com>
2 files changed:
simavr/sim/sim_irq.c
simavr/sim/sim_irq.h

index 16e3418d2c795421b837b8ea27bb0e3c9974a4f5..d0148a02a85f30e4fdd06ed46e0997c5645fd9b2 100644 (file)
@@ -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
index d3ac30b7d3e0972404a4c285a63909d462fc21fb..bf02a352e5e34dd4f237907cf288445880dfe0c2 100644 (file)
@@ -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