create directories branches, tags, trunk
[lttv.git] / ltt / branches / poly / lttv / lttv / hook.c
index 926e5fd0b8d670929132170f758dfbaccb7dd144..c7b43a50b956c5517538ef28b6a63dd4db04d8ce 100644 (file)
  * MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <lttv/hook.h>
 #include <ltt/compiler.h>
+#include <ltt/ltt.h>
 
 typedef struct _LttvHookClosure {
   LttvHook      hook;
@@ -293,10 +297,10 @@ gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data)
  * The second case that should occur the most often is
  * h1 != NULL , h2 == NULL.
  */
-gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1,
+gint lttv_hooks_call_merge(LttvHooks *h1, void *call_data1,
                                LttvHooks *h2, void *call_data2)
 {
-  gboolean ret, sum_ret = FALSE;
+  gint ret, sum_ret = 0;
 
   LttvHookClosure *c1, *c2;
 
@@ -309,12 +313,12 @@ gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1,
         c2 = &g_array_index(h2, LttvHookClosure, j);
         if(c1->prio <= c2->prio) {
           ret = c1->hook(c1->hook_data,call_data1);
-          sum_ret = sum_ret || ret;
+          sum_ret = sum_ret | ret;
           i++;
         }
         else {
           ret = c2->hook(c2->hook_data,call_data2);
-          sum_ret = sum_ret || ret;
+          sum_ret = sum_ret | ret;
           j++;
         }
       }
@@ -322,25 +326,25 @@ gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1,
       for(;i < h1->len; i++) {
         c1 = &g_array_index(h1, LttvHookClosure, i);
         ret = c1->hook(c1->hook_data,call_data1);
-        sum_ret = sum_ret || ret;
+        sum_ret = sum_ret | ret;
       }
       for(;j < h2->len; j++) {
         c2 = &g_array_index(h2, LttvHookClosure, j);
         ret = c2->hook(c2->hook_data,call_data2);
-        sum_ret = sum_ret || ret;
+        sum_ret = sum_ret | ret;
       }
     } else {  /* h1 != NULL && h2 == NULL */
       for(i = 0 ; i < h1->len ; i++) {
         c1 = &g_array_index(h1, LttvHookClosure, i);
         ret = c1->hook(c1->hook_data,call_data1);
-        sum_ret = sum_ret || ret;
+        sum_ret = sum_ret | ret;
       }
     }
   } else if(likely(h2 != NULL)) { /* h1 == NULL && h2 != NULL */
      for(j = 0 ; j < h2->len ; j++) {
       c2 = &g_array_index(h2, LttvHookClosure, j);
       ret = c2->hook(c2->hook_data,call_data2);
-      sum_ret = sum_ret || ret;
+      sum_ret = sum_ret | ret;
     }
   }
 
@@ -394,10 +398,20 @@ gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1,
 
 }
 
+/* Two pointer arrays : 
+ * * one indexed by id for quick search : 
+ *  size : max id
+ *  typically 4 bytes * 256 facilities * 10 events = 10kbytes
+ * * another array that keeps a list of used numbers (for later deletion)
+ *  size : number of ids used.
+ */
 
 LttvHooksById *lttv_hooks_by_id_new() 
 {
-  return g_ptr_array_new();
+  LttvHooksById *h = g_new(LttvHooksById, 1);
+  h->index = g_ptr_array_sized_new(NUM_FACILITIES * AVG_EVENTS_PER_FACILITIES);
+  h->array = g_array_sized_new(FALSE, FALSE, sizeof(guint), 50);
+  return h;
 }
 
 
@@ -405,31 +419,42 @@ void lttv_hooks_by_id_destroy(LttvHooksById *h)
 {
   guint i;
 
-  for(i = 0 ; i < h->len ; i++) {
-    if(h->pdata[i] != NULL) lttv_hooks_destroy((LttvHooks *)(h->pdata[i]));
+  for(i = 0 ; i < h->array->len ; i++) {
+    guint index = g_array_index(h->array, guint, i);
+    if(h->index->pdata[index] != NULL) { /* hook may have been removed */
+      lttv_hooks_destroy(h->index->pdata[index]);
+      h->index->pdata[index] = NULL;  /* Must be there in case of 
+                                         multiple addition of the same index */
+    }
   }
-  g_ptr_array_free(h, TRUE);
+  g_ptr_array_free(h->index, TRUE);
+  g_array_free(h->array, TRUE);
 }
 
 /* Optimised for searching an existing hook */
 LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id)
 {
-  if(unlikely(h->len <= id)) g_ptr_array_set_size(h, id + 1);
-  if(unlikely(h->pdata[id] == NULL)) h->pdata[id] = lttv_hooks_new();
-  return h->pdata[id];
+  if(unlikely(h->index->len <= id)) g_ptr_array_set_size(h->index, id + 1);
+  if(unlikely(h->index->pdata[id] == NULL)) {
+    h->index->pdata[id] = lttv_hooks_new();
+    g_array_append_val(h->array, id);
+  }
+  return h->index->pdata[id];
 }
 
 
 unsigned lttv_hooks_by_id_max_id(LttvHooksById *h)
 {
-  return h->len;
+  return h->index->len;
 }
 
+/* We don't bother removing the used slot array id : lttv_hooks_by_id_destroy is
+ * almost never called and is able to deal with used slot repetition. */
 void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id)
 {
-  if(likely(id < h->len && h->pdata[id] != NULL)) {
-    lttv_hooks_destroy((LttvHooks *)h->pdata[id]);
-    h->pdata[id] = NULL;
+  if(likely(id < h->index->len && h->index->pdata[id] != NULL)) {
+    lttv_hooks_destroy((LttvHooks *)h->index->pdata[id]);
+    h->index->pdata[id] = NULL;
   }
 }
 
This page took 0.024768 seconds and 4 git commands to generate.