X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Fhook.c;h=0ec856535df6ec094a2ab65cf5c361e2fb252f1a;hb=0bd2f89c122b8ead4c0bec1fbe25956393995622;hp=45870c323a4d62b1e4f614221dee2f1ec473be13;hpb=f210b68b489a31a909bcb7b4e1e8fe2fd4630629;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/hook.c b/ltt/branches/poly/lttv/lttv/hook.c index 45870c32..0ec85653 100644 --- a/ltt/branches/poly/lttv/lttv/hook.c +++ b/ltt/branches/poly/lttv/lttv/hook.c @@ -16,9 +16,13 @@ * MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include +#endif #include - +#include +#include typedef struct _LttvHookClosure { LttvHook hook; @@ -29,9 +33,10 @@ typedef struct _LttvHookClosure { gint lttv_hooks_prio_compare(LttvHookClosure *a, LttvHookClosure *b) { - if(a->prio < b->prio) return -1; - if(a->prio > b->prio) return 1; - return 0; + gint ret=0; + if(a->prio < b->prio) ret = -1; + else if(a->prio > b->prio) ret = 1; + return ret; } @@ -53,7 +58,7 @@ void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data, LttvHookPrio p) LttvHookClosure *c, new_c; guint i; - if(h == NULL)g_error("Null hook added"); + if(unlikely(h == NULL))g_error("Null hook added"); new_c.hook = f; new_c.hook_data = hook_data; @@ -99,7 +104,8 @@ void lttv_hooks_add_list(LttvHooks *h, const LttvHooks *list) LttvHookClosure *c; const LttvHookClosure *new_c; - if(list == NULL) return; + if(unlikely(list == NULL)) return; + for(i = 0, j = 0 ; i < list->len; i++) { new_c = &g_array_index(list, LttvHookClosure, i); gboolean found=FALSE; @@ -212,7 +218,7 @@ void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list) /* Normally the hooks in h are ordered as in list. If this is not the case, try harder here. */ - if(j < list->len) { + if(unlikely(j < list->len)) { for(; j < list->len ; j++) { c_list = &g_array_index(list, LttvHookClosure, j); lttv_hooks_remove_data(h, c_list->hook, c_list->hook_data); @@ -232,7 +238,7 @@ void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data, { LttvHookClosure *c; - if(i >= h->len) + if(unlikely(i >= h->len)) { *f = NULL; *hook_data = NULL; @@ -260,7 +266,7 @@ gboolean lttv_hooks_call(LttvHooks *h, void *call_data) guint i; - if(h != NULL) { + if(likely(h != NULL)) { for(i = 0 ; i < h->len ; i++) { c = &g_array_index(h, LttvHookClosure, i); ret = c->hook(c->hook_data,call_data); @@ -279,11 +285,18 @@ gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data) for(i = 0 ; i < h->len ; i++) { c = &g_array_index(h, LttvHookClosure, i); - if(c->hook(c->hook_data,call_data)) return TRUE; + if(unlikely(c->hook(c->hook_data,call_data))) return TRUE; } return FALSE; } +/* Optimised for h1 == NULL, h2 != NULL. This is the case + * for optimised computation (with specific by id hooks, but + * no main hooks). + * + * The second case that should occur the most often is + * h1 != NULL , h2 == NULL. + */ gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1, LttvHooks *h2, void *call_data2) { @@ -293,8 +306,8 @@ gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1, guint i, j; - if(h1 != NULL) { - if(h2 != NULL) { + if(unlikely(h1 != NULL)) { + if(unlikely(h2 != NULL)) { for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) { c1 = &g_array_index(h1, LttvHookClosure, i); c2 = &g_array_index(h2, LttvHookClosure, j); @@ -327,7 +340,7 @@ gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1, sum_ret = sum_ret || ret; } } - } else if(h2 != NULL) { /* h1 == NULL && h2 != NULL */ + } 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); @@ -345,8 +358,8 @@ gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1, guint i, j; - if(h1 != NULL) { - if(h2 != NULL) { + if(unlikely(h1 != NULL)) { + if(unlikely(h2 != NULL)) { for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) { c1 = &g_array_index(h1, LttvHookClosure, i); c2 = &g_array_index(h2, LttvHookClosure, j); @@ -374,7 +387,7 @@ gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1, if(c1->hook(c1->hook_data,call_data1)) return TRUE; } } - } else if(h2 != NULL) { /* h1 == NULL && h2 != NULL */ + } else if(likely(h2 != NULL)) { /* h1 == NULL && h2 != NULL */ for(j = 0 ; j < h2->len ; j++) { c2 = &g_array_index(h2, LttvHookClosure, j); if(c2->hook(c2->hook_data,call_data2)) return TRUE; @@ -385,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; } @@ -396,42 +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(h->len <= id) g_ptr_array_set_size(h, id + 1); - if(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; } - -inline LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id) -{ - LttvHooks *ret; - if(id < h->len) ret = h->pdata[id]; - else ret = NULL; - - return ret; -} - - +/* 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(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; } }