Commit 1f933911e37e1d75108a7ac6df21f2dec0ec0d00
authorMichel Pollet <buserror@gmail.com>
Fri, 31 Aug 2012 07:42:34 +0000 (08:42 +0100)
committerMichel Pollet <buserror@gmail.com>
Fri, 31 Aug 2012 07:43:14 +0000 (08:43 +0100)
Made the trade buffer growable, to accomadate busy tracers
Also converted the traces to AVR_LOG in that bit.

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

index 8d71e6b17d6f02d1225702f7afc94cd4cf0e91b9..8d87f87469a229c4b5daba9aecdf036f1500cab0 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include "sim_vcd_file.h"
 #include "sim_avr.h"
 #include "sim_time.h"
@@ -55,11 +56,28 @@ void _avr_vcd_notify(struct avr_irq_t * irq, uint32_t value, void * param)
        avr_vcd_t * vcd = (avr_vcd_t *)param;
        if (!vcd->output)
                return;
-       avr_vcd_signal_t * s = (avr_vcd_signal_t*)irq;
-       if (vcd->logindex == AVR_VCD_LOG_SIZE) {
-               printf("_avr_vcd_notify %s overrun value buffer %d\n", s->name, AVR_VCD_LOG_SIZE);
-               return;
+
+       /*
+        * buffer starts empty, the first trace will resize it to AVR_VCD_LOG_CHUNK_SIZE,
+        * further growth will resize it accordingly. There's a bit of
+        */
+       if (vcd->logindex >= vcd->logsize) {
+               vcd->logsize += AVR_VCD_LOG_CHUNK_SIZE;
+               vcd->log = (avr_vcd_log_p)realloc(vcd->log, vcd->logsize * sizeof(vcd->log[0]));
+               AVR_LOG(vcd->avr, LOG_TRACE, "%s trace buffer resized to %d\n",
+                               __func__, (int)vcd->logsize);
+               if ((vcd->logsize / AVR_VCD_LOG_CHUNK_SIZE) == 5) {
+                       AVR_LOG(vcd->avr, LOG_WARNING, "%s log size runnaway (%d) flush problem?\n",
+                                       __func__, (int)vcd->logsize);
+               }
+               if (!vcd->log) {
+                       AVR_LOG(vcd->avr, LOG_ERROR, "%s log resizing, out of memory (%d)!\n",
+                                       __func__, (int)vcd->logsize);
+                       vcd->logsize = 0;
+                       return;
+               }
        }
+       avr_vcd_signal_t * s = (avr_vcd_signal_t*)irq;
        avr_vcd_log_t *l = &vcd->log[vcd->logindex++];
        l->signal = s;
        l->when = vcd->avr->cycle;
@@ -152,7 +170,7 @@ int avr_vcd_start(avr_vcd_t * vcd)
                perror(vcd->filename);
                return -1;
        }
-               
+
        fprintf(vcd->output, "$timescale 1ns $end\n");  // 1ns base
        fprintf(vcd->output, "$scope module logic $end\n");
 
index 1bc38c8c36a90767a21055e78ff2a047e7dc78f7..d3432719ce16a17f38ad515dea4a2b8d474ef96b 100644 (file)
@@ -40,7 +40,6 @@ extern "C" {
  */
 
 #define AVR_VCD_MAX_SIGNALS 32
-#define AVR_VCD_LOG_SIZE       5120
 
 typedef struct avr_vcd_signal_t {
        avr_irq_t       irq;            // receiving IRQ
@@ -53,7 +52,9 @@ typedef struct avr_vcd_log_t {
        uint64_t        when;
        avr_vcd_signal_t * signal;
        uint32_t value;
-} avr_vcd_log_t;
+} avr_vcd_log_t, *avr_vcd_log_p;
+
+#define AVR_VCD_LOG_CHUNK_SIZE (4096 / sizeof(avr_vcd_signal_t))
 
 typedef struct avr_vcd_t {
        struct avr_t *  avr;    // AVR we are attaching timers to..
@@ -67,8 +68,9 @@ typedef struct avr_vcd_t {
        uint64_t period;
        uint64_t start;
 
+       size_t                  logsize;
        uint32_t                logindex;
-       avr_vcd_log_t   log[AVR_VCD_LOG_SIZE];
+       avr_vcd_log_p   log;
 } avr_vcd_t;
 
 // initializes a new VCD trace file, and returns zero if all is well