Patchwork [1/3] irq: Add new function qemu_init_irqs

login
register
mail settings
Submitter Stefan Weil
Date Sept. 24, 2012, 7:08 p.m.
Message ID <1348513730-7485-2-git-send-email-sw@weilnetz.de>
Download mbox | patch
Permalink /patch/186518/
State Under Review
Headers show

Comments

Stefan Weil - Sept. 24, 2012, 7:08 p.m.
It is used to avoid dynamic memory allocation for qemu_irq arrays
with known size or single qemu_irq variables.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
---
 hw/irq.c |   15 +++++++++------
 hw/irq.h |    4 ++++
 2 files changed, 13 insertions(+), 6 deletions(-)
Peter Maydell - Sept. 24, 2012, 7:26 p.m.
On 24 September 2012 20:08, Stefan Weil <sw@weilnetz.de> wrote:
> It is used to avoid dynamic memory allocation for qemu_irq arrays
> with known size or single qemu_irq variables.

This patch is going to collide with Peter Crosthwaite's patch
that allows an irq array to be extended.

Also, the memory allocated with qemu_allocate_irqs() can be
freed with qemu_free_irqs(), but you don't seem to have
provided any way for direct callers of qemu_init_irqs()
to free the allocated IRQState array.

It feels to me like it ought to be possible to avoid having
random free-floating qemu_irq arrays at all : they should
all belong to devices which have (in theory) an opportunity
to free them in a deinit function. Explicit copying of qemu_irqs
out of one array and into other places, in particular, suggests
that maybe the code should be using qdev_get_gpio_in and
qdev_connect_gpio_out instead.

-- PMM

Patch

diff --git a/hw/irq.c b/hw/irq.c
index d413a0b..fd284b0 100644
--- a/hw/irq.c
+++ b/hw/irq.c
@@ -38,14 +38,11 @@  void qemu_set_irq(qemu_irq irq, int level)
     irq->handler(irq->opaque, irq->n, level);
 }
 
-qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
+void qemu_init_irqs(qemu_irq_handler handler, void *opaque,
+                    qemu_irq *s, int n)
 {
-    qemu_irq *s;
-    struct IRQState *p;
     int i;
-
-    s = (qemu_irq *)g_malloc0(sizeof(qemu_irq) * n);
-    p = (struct IRQState *)g_malloc0(sizeof(struct IRQState) * n);
+    struct IRQState *p = g_new0(struct IRQState, n);
     for (i = 0; i < n; i++) {
         p->handler = handler;
         p->opaque = opaque;
@@ -53,6 +50,12 @@  qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
         s[i] = p;
         p++;
     }
+}
+
+qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
+{
+    qemu_irq *s = g_new(qemu_irq, n);
+    qemu_init_irqs(handler, opaque, s, n);
     return s;
 }
 
diff --git a/hw/irq.h b/hw/irq.h
index 56c55f0..368b88f 100644
--- a/hw/irq.h
+++ b/hw/irq.h
@@ -23,6 +23,10 @@  static inline void qemu_irq_pulse(qemu_irq irq)
     qemu_set_irq(irq, 0);
 }
 
+/* Initialize an array of N IRQs. */
+void qemu_init_irqs(qemu_irq_handler handler, void *opaque,
+                    qemu_irq *irqs, int n);
+
 /* Returns an array of N IRQs.  */
 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
 void qemu_free_irqs(qemu_irq *s);