gallivm: store callbacks in a linked list rather than fixed size array
authorBrian Paul <brianp@vmware.com>
Mon, 13 Dec 2010 18:47:26 +0000 (11:47 -0700)
committerBrian Paul <brianp@vmware.com>
Mon, 13 Dec 2010 18:47:28 +0000 (11:47 -0700)
Should fix http://bugs.freedesktop.org/show_bug.cgi?id=32308

src/gallium/auxiliary/gallivm/lp_bld_init.c

index efe8d38b8f069af68d7cca48e4502981196cd053..7504cb5cf2fae17468568d30dc26401ec67809e6 100644 (file)
@@ -30,6 +30,7 @@
 #include "util/u_cpu_detect.h"
 #include "util/u_debug.h"
 #include "util/u_memory.h"
+#include "util/u_simple_list.h"
 #include "lp_bld_debug.h"
 #include "lp_bld_init.h"
 
@@ -291,12 +292,12 @@ struct callback
 {
    garbage_collect_callback_func func;
    void *cb_data;
+   struct callback *prev, *next;
 };
 
 
-#define MAX_CALLBACKS 32
-static struct callback Callbacks[MAX_CALLBACKS];
-static unsigned NumCallbacks = 0;
+/** list of all garbage collector callbacks */
+static struct callback callback_list = {NULL, NULL, NULL, NULL};
 
 
 /**
@@ -307,20 +308,24 @@ void
 gallivm_register_garbage_collector_callback(garbage_collect_callback_func func,
                                             void *cb_data)
 {
-   unsigned i;
+   struct callback *cb;
 
-   for (i = 0; i < NumCallbacks; i++) {
-      if (Callbacks[i].func == func && Callbacks[i].cb_data == cb_data) {
-         /* already in list: no-op */
+   if (!callback_list.prev) {
+      make_empty_list(&callback_list);
+   }
+
+   /* see if already in list */
+   foreach(cb, &callback_list) {
+      if (cb->func == func && cb->cb_data == cb_data)
          return;
-      }
    }
 
-   assert(NumCallbacks < MAX_CALLBACKS);
-   if (NumCallbacks < MAX_CALLBACKS) {
-      Callbacks[NumCallbacks].func = func;
-      Callbacks[NumCallbacks].cb_data = cb_data;
-      NumCallbacks++;
+   /* add to list */
+   cb = CALLOC_STRUCT(callback);
+   if (cb) {
+      cb->func = func;
+      cb->cb_data = cb_data;
+      insert_at_head(&callback_list, cb);
    }
 }
 
@@ -332,15 +337,13 @@ void
 gallivm_remove_garbage_collector_callback(garbage_collect_callback_func func,
                                           void *cb_data)
 {
-   unsigned i;
-
-   for (i = 0; i < NumCallbacks; i++) {
-      if (Callbacks[i].func == func && Callbacks[i].cb_data == cb_data) {
-         /* found, now remove it */
-         NumCallbacks--;
-         for ( ; i < NumCallbacks; i++) {
-            Callbacks[i] = Callbacks[i + 1];
-         }
+   struct callback *cb;
+
+   /* search list */
+   foreach(cb, &callback_list) {
+      if (cb->func == func && cb->cb_data == cb_data) {
+         /* found, remove it */
+         remove_from_list(cb);
          return;
       }
    }
@@ -354,10 +357,9 @@ gallivm_remove_garbage_collector_callback(garbage_collect_callback_func func,
 static void
 call_garbage_collector_callbacks(void)
 {
-   unsigned i;
-
-   for (i = 0; i < NumCallbacks; i++) {
-      Callbacks[i].func(Callbacks[i].cb_data);
+   struct callback *cb;
+   foreach(cb, &callback_list) {
+      cb->func(cb->cb_data);
    }
 }