From 1d1df11d0582bef07ef2b33e8e82a75b08f32be4 Mon Sep 17 00:00:00 2001 From: compudj Date: Sun, 15 Aug 2004 03:33:47 +0000 Subject: [PATCH] likely/unlikely branch prediction git-svn-id: http://ltt.polymtl.ca/svn@771 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/ltt/compiler.h | 26 +++++++ ltt/branches/poly/ltt/event.c | 14 ++-- ltt/branches/poly/ltt/ltt.h | 5 +- ltt/branches/poly/ltt/time.h | 17 ++-- ltt/branches/poly/ltt/tracefile.c | 26 +++---- ltt/branches/poly/lttv/lttv/attribute.c | 13 ++-- ltt/branches/poly/lttv/lttv/hook.c | 49 +++++++----- ltt/branches/poly/lttv/lttv/hook.h | 2 +- ltt/branches/poly/lttv/lttv/state.c | 28 ++++--- ltt/branches/poly/lttv/lttv/tracecontext.c | 32 ++++---- ltt/branches/poly/lttv/lttv/traceset.c | 2 +- .../lttv/modules/gui/controlflow/drawing.c | 10 +-- .../lttv/modules/gui/controlflow/drawitem.c | 20 ++--- .../lttv/modules/gui/controlflow/eventhooks.c | 77 ++++++++++--------- .../modules/gui/controlflow/processlist.c | 44 +++++------ 15 files changed, 204 insertions(+), 161 deletions(-) create mode 100644 ltt/branches/poly/ltt/compiler.h diff --git a/ltt/branches/poly/ltt/compiler.h b/ltt/branches/poly/ltt/compiler.h new file mode 100644 index 00000000..cef7a476 --- /dev/null +++ b/ltt/branches/poly/ltt/compiler.h @@ -0,0 +1,26 @@ +/* This file is part of the Linux Trace Toolkit trace reading library + * Copyright (C) 2003-2004 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef COMPILER_H +#define COMPILER_H + +/* Fast prediction if likely branches */ +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +#endif //COMPILER_H diff --git a/ltt/branches/poly/ltt/event.c b/ltt/branches/poly/ltt/event.c index b230fd30..395d46b1 100644 --- a/ltt/branches/poly/ltt/event.c +++ b/ltt/branches/poly/ltt/event.c @@ -227,21 +227,19 @@ LttField *ltt_event_field(LttEvent *e) { LttField * field; LttEventType * event_type = ltt_event_eventtype(e); - if(!event_type) return NULL; + if(unlikely(!event_type)) return NULL; field = event_type->root_field; - if(!field) return NULL; + if(unlikely(!field)) return NULL; //check if the field need refresh - if(e->which_block != event_type->latest_block || - e->which_event != event_type->latest_event){ + if(likely(e->which_block != event_type->latest_block || + e->which_event != event_type->latest_event)){ event_type->latest_block = e->which_block; event_type->latest_event = e->which_event; - if(field->field_fixed == 1)return field; - - //refresh the field - ltt_event_refresh_fields(0, 0, field, e->data); + if(unlikely(field->field_fixed != 1)) + ltt_event_refresh_fields(0, 0, field, e->data); } return field; } diff --git a/ltt/branches/poly/ltt/ltt.h b/ltt/branches/poly/ltt/ltt.h index 021173f9..3af7cd32 100644 --- a/ltt/branches/poly/ltt/ltt.h +++ b/ltt/branches/poly/ltt/ltt.h @@ -19,8 +19,9 @@ #ifndef LTT_H #define LTT_H -#include #include +#include +#include /* A trace is associated with a tracing session run on a single, possibly multi-cpu, system. It is defined as a pathname to a directory containing @@ -130,5 +131,5 @@ typedef enum _LttTypeEnum LTT_SEQUENCE, LTT_STRUCT, LTT_UNION } LttTypeEnum; - + #endif // LTT_H diff --git a/ltt/branches/poly/ltt/time.h b/ltt/branches/poly/ltt/time.h index a2570182..fe7641df 100644 --- a/ltt/branches/poly/ltt/time.h +++ b/ltt/branches/poly/ltt/time.h @@ -20,7 +20,7 @@ #define LTT_TIME_H #include - +#include typedef struct _LttTime { unsigned long tv_sec; @@ -42,7 +42,11 @@ static inline LttTime ltt_time_sub(LttTime t1, LttTime t2) LttTime res; res.tv_sec = t1.tv_sec - t2.tv_sec; res.tv_nsec = t1.tv_nsec - t2.tv_nsec; - if(t1.tv_nsec < t2.tv_nsec) { + /* unlikely : given equal chance to be anywhere in t1.tv_nsec, and + * higher probability of low value for t2.tv_sec, we will habitually + * not wrap. + */ + if(unlikely(t1.tv_nsec < t2.tv_nsec)) { res.tv_sec--; res.tv_nsec += NANOSECONDS_PER_SECOND; } @@ -55,16 +59,17 @@ static inline LttTime ltt_time_add(LttTime t1, LttTime t2) LttTime res; res.tv_nsec = t1.tv_nsec + t2.tv_nsec; res.tv_sec = t1.tv_sec + t2.tv_sec; - if(res.tv_nsec >= NANOSECONDS_PER_SECOND) { + /* unlikely : given equal chance to be anywhere in t1.tv_nsec, and + * higher probability of low value for t2.tv_sec, we will habitually + * not wrap. + */ + if(unlikely(res.tv_nsec >= NANOSECONDS_PER_SECOND)) { res.tv_sec++; res.tv_nsec -= NANOSECONDS_PER_SECOND; } return res; } -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) - /* Fastest comparison : t1 > t2 */ static inline int ltt_time_compare(LttTime t1, LttTime t2) { diff --git a/ltt/branches/poly/ltt/tracefile.c b/ltt/branches/poly/ltt/tracefile.c index e5506c0d..8092201b 100644 --- a/ltt/branches/poly/ltt/tracefile.c +++ b/ltt/branches/poly/ltt/tracefile.c @@ -1208,13 +1208,13 @@ int skipEvent(LttTracefile * t) evT = ltt_trace_eventtype_get(t->trace,(unsigned)evId); - if(evT) rootFld = evT->root_field; + if(likely(evT)) rootFld = evT->root_field; else return ERANGE; - if(rootFld){ + if(likely(rootFld)){ //event has string/sequence or the last event is not the same event - if((evT->latest_block!=t->which_block || evT->latest_event!=t->which_event) - && rootFld->field_fixed == 0){ + if(likely((evT->latest_block!=t->which_block || evT->latest_event!=t->which_event) + && rootFld->field_fixed == 0)){ setFieldsOffset(t, evT, evData, t->trace); } t->cur_event_pos += EVENT_HEADER_SIZE + rootFld->field_size; @@ -1224,7 +1224,7 @@ int skipEvent(LttTracefile * t) evT->latest_event = t->which_event; //the next event is in the next block - if(evId == TRACE_BLOCK_END){ + if(unlikely(evId == TRACE_BLOCK_END)){ t->cur_event_pos = t->buffer + t->block_size; }else{ t->which_event++; @@ -1290,12 +1290,12 @@ static inline LttTime getEventTime(LttTracefile * tf) guint16 evId; evId = *(guint16 *)tf->cur_event_pos; - if(evId == TRACE_BLOCK_START){ + if(unlikely(evId == TRACE_BLOCK_START)){ tf->count = 0; tf->pre_cycle_count = 0; tf->cur_cycle_count = tf->a_block_start->cycle_count; return tf->a_block_start->time; - }else if(evId == TRACE_BLOCK_END){ + }else if(unlikely(evId == TRACE_BLOCK_END)){ tf->count = 0; tf->pre_cycle_count = 0; tf->cur_cycle_count = tf->a_block_end->cycle_count; @@ -1305,7 +1305,7 @@ static inline LttTime getEventTime(LttTracefile * tf) // Calculate total time in cycles from start of buffer for this event cycle_count = (LttCycleCount)*(guint32 *)(tf->cur_event_pos + EVENT_ID_SIZE); - if(cycle_count < tf->pre_cycle_count)tf->count++; + if(unlikely(cycle_count < tf->pre_cycle_count)) tf->count++; tf->pre_cycle_count = cycle_count; cycle_count += (LttCycleCount)tf->count << 32; @@ -1343,7 +1343,7 @@ void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace* t) LttField * rootFld = evT->root_field; // rootFld->base_address = evD; - if(rootFld) + if(likely(rootFld)) rootFld->field_size = getFieldtypeSize(tf, evT, 0,0,rootFld, evD,t); } @@ -1367,13 +1367,13 @@ int getFieldtypeSize(LttTracefile * t, LttEventType * evT, int offsetRoot, int size, size1, element_number, i, offset1, offset2; LttType * type = fld->field_type; - if(t){ - if(evT->latest_block==t->which_block && evT->latest_event==t->which_event){ + if(likely(t)){ + if(unlikely(evT->latest_block==t->which_block && evT->latest_event==t->which_event)){ return fld->field_size; } } - if(fld->field_fixed == 1){ + if(likely(fld->field_fixed == 1)){ if(fld == evT->root_field) return fld->field_size; } @@ -1434,7 +1434,7 @@ int getFieldtypeSize(LttTracefile * t, LttEventType * evT, int offsetRoot, case LTT_STRUCT: element_number = (int) type->element_number; size = 0; - if(fld->field_fixed == -1){ + if(fld->field_fixed == -1){ offset1 = offsetRoot; offset2 = 0; for(i=0;i #include #include +#include typedef union _AttributeValue { int dv_int; @@ -177,7 +178,7 @@ lttv_attribute_remove(LttvAttribute *self, unsigned i) /* The element used to replace the removed element has its index entry all wrong now. Reinsert it with its new position. */ - if(self->attributes->len != i){ + if(likely(self->attributes->len != i)){ g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name)); g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1)); } @@ -189,7 +190,7 @@ lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name) unsigned i; i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i == 0) g_error("remove by name non existent attribute"); + if(unlikely(i == 0)) g_error("remove by name non existent attribute"); lttv_attribute_remove(self, i - 1); } @@ -209,9 +210,9 @@ lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name) LttvAttribute *new; i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i != 0) { + if(likely(i != 0)) { a = g_array_index(self->attributes, Attribute, i - 1); - if(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject)) { + if(likely(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject))) { return LTTV_ATTRIBUTE(a.value.dv_gobject); } else return NULL; @@ -230,9 +231,9 @@ lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, Attribute *a; i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i != 0) { + if(likely(i != 0)) { a = &g_array_index(self->attributes, Attribute, i - 1); - if(a->type != t) return FALSE; + if(unlikely(a->type != t)) return FALSE; *v = address_of_value(t, &(a->value)); return TRUE; } diff --git a/ltt/branches/poly/lttv/lttv/hook.c b/ltt/branches/poly/lttv/lttv/hook.c index 9f08b98b..926e5fd0 100644 --- a/ltt/branches/poly/lttv/lttv/hook.c +++ b/ltt/branches/poly/lttv/lttv/hook.c @@ -18,7 +18,7 @@ #include - +#include typedef struct _LttvHookClosure { LttvHook hook; @@ -29,9 +29,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 +54,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 +100,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 +214,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 +234,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 +262,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 +281,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 +302,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 +336,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 +354,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 +383,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; @@ -402,11 +411,11 @@ void lttv_hooks_by_id_destroy(LttvHooksById *h) g_ptr_array_free(h, 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(); + 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]; } @@ -418,7 +427,7 @@ unsigned lttv_hooks_by_id_max_id(LttvHooksById *h) void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id) { - if(id < h->len && h->pdata[id] != NULL) { + if(likely(id < h->len && h->pdata[id] != NULL)) { lttv_hooks_destroy((LttvHooks *)h->pdata[id]); h->pdata[id] = NULL; } diff --git a/ltt/branches/poly/lttv/lttv/hook.h b/ltt/branches/poly/lttv/lttv/hook.h index 77a5dd5f..7da21346 100644 --- a/ltt/branches/poly/lttv/lttv/hook.h +++ b/ltt/branches/poly/lttv/lttv/hook.h @@ -147,7 +147,7 @@ unsigned lttv_hooks_by_id_max_id(LttvHooksById *h); static inline LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id) { LttvHooks *ret; - if(id < h->len) ret = h->pdata[id]; + if(likely(id < h->len)) ret = h->pdata[id]; else ret = NULL; return ret; diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c index d60b4588..55bd4e05 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -104,17 +104,21 @@ guint process_hash(gconstpointer key) } +/* If the hash table hash function is well distributed, + * the process_equal should compare different pid */ gboolean process_equal(gconstpointer a, gconstpointer b) { const LttvProcessState *process_a, *process_b; - + gboolean ret = TRUE; + process_a = (const LttvProcessState *)a; process_b = (const LttvProcessState *)b; + + if(likely(process_a->pid != process_b->pid)) ret = FALSE; + else if(likely(process_a->pid == 0 && + process_a->last_cpu != process_b->last_cpu)) ret = FALSE; - if(process_a->pid != process_b->pid) return FALSE; - if(process_a->pid == 0 && - process_a->last_cpu != process_b->last_cpu) return FALSE; - return TRUE; + return ret; } @@ -840,7 +844,7 @@ lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid) { LttvProcessState *process = lttv_state_find_process(tfs, pid); - if(process == NULL) process = lttv_state_create_process(tfs, NULL, pid); + if(unlikely(process == NULL)) process = lttv_state_create_process(tfs, NULL, pid); return process; } @@ -964,7 +968,7 @@ static gboolean schedchange(void *hook_data, void *call_data) pid_out = ltt_event_get_unsigned(s->parent.e, h->f2); state_out = ltt_event_get_unsigned(s->parent.e, h->f3); - if(s->process != NULL) { + if(likely(s->process != NULL)) { /* We could not know but it was not the idle process executing. This should only happen at the beginning, before the first schedule @@ -972,14 +976,14 @@ static gboolean schedchange(void *hook_data, void *call_data) is missing. It is not obvious how we could, after the fact, compensate the wrongly attributed statistics. */ - if(s->process->pid != pid_out) { + if(unlikely(s->process->pid != pid_out)) { g_assert(s->process->pid == 0); } - if(s->process->state->s == LTTV_STATE_EXIT) { + if(unlikely(s->process->state->s == LTTV_STATE_EXIT)) { s->process->state->s = LTTV_STATE_ZOMBIE; } else { - if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU; + if(unlikely(state_out == 0)) s->process->state->s = LTTV_STATE_WAIT_CPU; else s->process->state->s = LTTV_STATE_WAIT; } /* FIXME : we do not remove process here, because the kernel * still has them : they may be zombies. We need to know @@ -1012,7 +1016,7 @@ static gboolean process_fork(LttvTraceHook *trace_hook, LttvTracefileState *s) zombie_process = lttv_state_find_process(s, child_pid); - if(zombie_process != NULL) { + if(unlikely(zombie_process != NULL)) { /* Reutilisation of PID. Only now we are sure that the old PID * has been released. FIXME : sould know when release_task happens instead. */ @@ -1027,7 +1031,7 @@ static gboolean process_fork(LttvTraceHook *trace_hook, LttvTracefileState *s) static gboolean process_exit(LttvTraceHook *trace_hook, LttvTracefileState *s) { - if(s->process != NULL) { + if(likely(s->process != NULL)) { s->process->state->s = LTTV_STATE_EXIT; } return FALSE; diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.c b/ltt/branches/poly/lttv/lttv/tracecontext.c index 601208e8..af39ffdc 100644 --- a/ltt/branches/poly/lttv/lttv/tracecontext.c +++ b/ltt/branches/poly/lttv/lttv/tracecontext.c @@ -26,16 +26,16 @@ -gint compare_tracefile(gconstpointer a, gconstpointer b) +static gint compare_tracefile(gconstpointer a, gconstpointer b) { gint comparison = 0; const LttvTracefileContext *trace_a = (const LttvTracefileContext *)a; const LttvTracefileContext *trace_b = (const LttvTracefileContext *)b; - if(trace_a != trace_b) { + if(likely(trace_a != trace_b)) { comparison = ltt_time_compare(trace_a->timestamp, trace_b->timestamp); - if(comparison == 0) { + if(unlikely(comparison == 0)) { if(trace_a->index < trace_b->index) comparison = -1; else if(trace_a->index > trace_b->index) comparison = 1; else if(trace_a->t_context->index < trace_b->t_context->index) @@ -667,7 +667,7 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, tfc = NULL; g_tree_foreach(pqueue, get_first, &tfc); /* End of traceset : tfc is NULL */ - if(tfc == NULL) + if(unlikely(tfc == NULL)) { return count; } @@ -680,11 +680,11 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, * break the loop. */ - if(last_ret == TRUE || - count >= nb_events || + if(unlikely(last_ret == TRUE || + count >= nb_events || (end_position!=NULL&<tv_traceset_context_ctx_pos_compare(self, end_position) == 0)|| - ltt_time_compare(end, tfc->timestamp) <= 0) + ltt_time_compare(end, tfc->timestamp) <= 0)) { return count; } @@ -700,7 +700,7 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, last_ret = lttv_hooks_call_merge(tfc->event, tfc, lttv_hooks_by_id_get(tfc->event_by_id, id), tfc); - if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) { + if(likely(ltt_tracefile_read(tfc->tf, tfc->e) != NULL)) { tfc->timestamp = ltt_event_time(tfc->e); g_tree_insert(pqueue, tfc, tfc); } @@ -740,7 +740,7 @@ void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start) tfc = self->tracefiles[i]; ltt_tracefile_seek_time(tfc->tf, start); g_tree_remove(pqueue, tfc); - if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) { + if(likely(ltt_tracefile_read(tfc->tf, tfc->e) != NULL)) { tfc->timestamp = ltt_event_time(tfc->e); g_tree_insert(pqueue, tfc, tfc); } @@ -771,7 +771,7 @@ gboolean lttv_process_tracefile_seek_position(LttvTracefileContext *self, ltt_tracefile_seek_position(tfc->tf, pos); g_tree_remove(pqueue, tfc); - if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) { + if(likely(ltt_tracefile_read(tfc->tf, tfc->e) != NULL)) { tfc->timestamp = ltt_event_time(tfc->e); g_tree_insert(pqueue, tfc, tfc); } @@ -862,10 +862,10 @@ lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type, guint nb, pos; nb = ltt_trace_facility_find(t, facility, &pos); - if(nb < 1) g_error("No %s facility", facility); + if(unlikely(nb < 1)) g_error("No %s facility", facility); f = ltt_trace_facility_get(t, pos); et = ltt_facility_eventtype_get_by_name(f, event_type); - if(et == NULL) g_error("Event %s does not exist", event_type); + if(unlikely(et == NULL)) g_error("Event %s does not exist", event_type); th->h = h; th->id = ltt_eventtype_id(et); @@ -987,7 +987,7 @@ gint lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext *self, nb_trace = lttv_traceset_number(self->ts); - if(pos->nb_trace != nb_trace) + if(unlikely(pos->nb_trace != nb_trace)) g_error("lttv_traceset_context_ctx_pos_compare : nb_trace does not match."); for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) { @@ -995,7 +995,7 @@ gint lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext *self, nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + ltt_trace_per_cpu_tracefile_number(tc->t); - if(pos->t_pos[iter_trace].nb_tracefile != nb_tracefile) + if(unlikely(pos->t_pos[iter_trace].nb_tracefile != nb_tracefile)) g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match."); for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) { @@ -1021,13 +1021,13 @@ gint lttv_traceset_context_pos_pos_compare( gint ret; nb_trace = pos1->nb_trace; - if(nb_trace != pos2->nb_trace) + if(unlikely(nb_trace != pos2->nb_trace)) g_error("lttv_traceset_context_pos_pos_compare : nb_trace does not match."); for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) { nb_tracefile = pos1->t_pos[iter_trace].nb_tracefile; - if(nb_tracefile != pos2->t_pos[iter_trace].nb_tracefile) + if(unlikely(nb_tracefile != pos2->t_pos[iter_trace].nb_tracefile)) g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match."); for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) { diff --git a/ltt/branches/poly/lttv/lttv/traceset.c b/ltt/branches/poly/lttv/lttv/traceset.c index a190486a..bfd75107 100644 --- a/ltt/branches/poly/lttv/lttv/traceset.c +++ b/ltt/branches/poly/lttv/lttv/traceset.c @@ -203,7 +203,7 @@ guint lttv_trace_ref(LttvTrace * t) guint lttv_trace_unref(LttvTrace * t) { - if(t->ref_count > 0) + if(likely(t->ref_count > 0)) t->ref_count--; return t->ref_count; diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c index 7eecd71d..918d8c3b 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c @@ -592,7 +592,7 @@ expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) (ControlFlowData*)g_object_get_data( G_OBJECT(widget), "control_flow_data"); - if(drawing->gc == NULL) { + if(unlikely(drawing->gc == NULL)) { drawing->gc = gdk_gc_new(drawing->drawing_area->window); gdk_gc_copy(drawing->gc, drawing->drawing_area->style->black_gc); } @@ -1007,12 +1007,12 @@ void drawing_insert_square(Drawing_t *drawing, drawing->width+SAFETY, drawing->height - y); - if (drawing->pixmap) + if(likely(drawing->pixmap)) gdk_pixmap_unref(drawing->pixmap); drawing->pixmap = pixmap; - if(drawing->height==1) drawing->height = height; + if(unlikely(drawing->height==1)) drawing->height = height; else drawing->height += height; gtk_widget_set_size_request(drawing->drawing_area, @@ -1034,7 +1034,7 @@ void drawing_remove_square(Drawing_t *drawing, { GdkPixmap *pixmap; - if(drawing->height == height) { + if(unlikely(drawing->height == height)) { pixmap = gdk_pixmap_new( drawing->drawing_area->window, drawing->width + SAFETY, @@ -1068,7 +1068,7 @@ void drawing_remove_square(Drawing_t *drawing, drawing->height-=height; } - if (drawing->pixmap) + if(likely(drawing->pixmap)) gdk_pixmap_unref(drawing->pixmap); drawing->pixmap = pixmap; diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c b/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c index a3085a8a..22cc9865 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c @@ -160,7 +160,7 @@ gboolean draw_text( void *hook_data, void *call_data) break; } /* verify if there is enough space to draw */ - if(x + width <= draw_context->drawinfo.end.x) { + if(unlikely(x + width <= draw_context->drawinfo.end.x)) { enough_space = TRUE; *offset += width; } @@ -185,14 +185,14 @@ gboolean draw_text( void *hook_data, void *call_data) break; } /* verify if there is enough space to draw */ - if(x - width >= draw_context->drawinfo.start.x) { + if(unlikely(x - width >= draw_context->drawinfo.start.x)) { enough_space = TRUE; *offset -= width; } break; } - if(enough_space) + if(unlikely(enough_space)) gdk_draw_layout_with_colors(draw_context->drawable, draw_context->gc, x, @@ -220,7 +220,7 @@ gboolean draw_icon( void *hook_data, void *call_data) g_assert(lttv_iattribute_find_by_path(attributes, icon_name, LTTV_POINTER, &value)); - if(*(value.v_pointer) == NULL) + if(unlikely(*(value.v_pointer) == NULL)) { *(value.v_pointer) = icon_info = g_new(IconStruct,1); @@ -258,7 +258,7 @@ gboolean draw_icon( void *hook_data, void *call_data) break; } /* verify if there is enough space to draw */ - if(x + width <= draw_context->drawinfo.end.x) { + if(unlikely(x + width <= draw_context->drawinfo.end.x)) { enough_space = TRUE; *offset += width; } @@ -283,14 +283,14 @@ gboolean draw_icon( void *hook_data, void *call_data) break; } /* verify if there is enough space to draw */ - if(x - width >= draw_context->drawinfo.start.x) { + if(unlikely(x - width >= draw_context->drawinfo.start.x)) { enough_space = TRUE; *offset -= width; } break; } - if(enough_space) { + if(unlikely(enough_space)) { gdk_gc_set_clip_mask(draw_context->gc, icon_info->mask); gdk_gc_set_clip_origin( @@ -391,7 +391,7 @@ gboolean draw_arc( void *hook_data, void *call_data) break; } /* verify if there is enough space to draw */ - if(x + width <= draw_context->drawinfo.end.x) { + if(unlikely(x + width <= draw_context->drawinfo.end.x)) { enough_space = TRUE; *offset += width; } @@ -416,14 +416,14 @@ gboolean draw_arc( void *hook_data, void *call_data) break; } /* verify if there is enough space to draw */ - if(x - width >= draw_context->drawinfo.start.x) { + if(unlikely(x - width >= draw_context->drawinfo.start.x)) { enough_space = TRUE; *offset -= width; } break; } - if(enough_space) + if(unlikely(enough_space)) gdk_draw_arc(draw_context->drawable, draw_context->gc, properties->filled, x, diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c b/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c index fc23e17c..15459377 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c @@ -2020,7 +2020,7 @@ int before_execmode_hook(void *hook_data, void *call_data) ProcessList *process_list = control_flow_data->process_list; LttTime birth = process->creation_time; - if(process_list->current_hash_data[tfc->index] != NULL) { + if(likely(process_list->current_hash_data[tfc->index] != NULL)) { hashed_process_data = process_list->current_hash_data[tfc->index]; } else { hashed_process_data = processlist_get_process_data(process_list, @@ -2028,7 +2028,7 @@ int before_execmode_hook(void *hook_data, void *call_data) process->last_cpu_index, &birth, tfc->t_context->index); - if(hashed_process_data == NULL) + if(unlikely(hashed_process_data == NULL)) { g_assert(pid == 0 || pid != process->ppid); ProcessInfo *process_info; @@ -2066,10 +2066,10 @@ int before_execmode_hook(void *hook_data, void *call_data) */ g_assert(hashed_process_data->x.over != -1); - if(ltt_time_compare(hashed_process_data->next_good_time, - evtime) > 0) + if(likely(ltt_time_compare(hashed_process_data->next_good_time, + evtime) > 0)) { - if(hashed_process_data->x.middle_marked == FALSE) { + if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { processlist_get_pixels_from_data(process_list, hashed_process_data, &y, @@ -2124,10 +2124,10 @@ int before_execmode_hook(void *hook_data, void *call_data) /* Jump over draw if we are at the same x position */ - if(x == hashed_process_data->x.middle && - hashed_process_data->x.middle_used) + if(unlikely(x == hashed_process_data->x.middle && + hashed_process_data->x.middle_used)) { - if(hashed_process_data->x.middle_marked == FALSE) { + if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { /* Draw collision indicator */ gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); gdk_draw_point(drawing->pixmap, @@ -2226,7 +2226,7 @@ int after_execmode_hook(void *hook_data, void *call_data) birth = process->creation_time; - if(process_list->current_hash_data[tfc->index] != NULL) { + if(likely(process_list->current_hash_data[tfc->index] != NULL)) { hashed_process_data = process_list->current_hash_data[tfc->index]; } else { hashed_process_data = processlist_get_process_data(process_list, @@ -2234,7 +2234,7 @@ int after_execmode_hook(void *hook_data, void *call_data) process->last_cpu_index, &birth, tfc->t_context->index); - if(hashed_process_data == NULL) + if(unlikely(hashed_process_data == NULL)) { g_assert(pid == 0 || pid != process->ppid); /* Process not present */ @@ -2261,8 +2261,8 @@ int after_execmode_hook(void *hook_data, void *call_data) hashed_process_data; } - if(ltt_time_compare(hashed_process_data->next_good_time, - evtime) <= 0) + if(unlikely(ltt_time_compare(hashed_process_data->next_good_time, + evtime) <= 0)) { #if 0 processlist_get_pixels_from_data(process_list, @@ -2346,7 +2346,7 @@ int before_process_hook(void *hook_data, void *call_data) birth = process->creation_time; - if(process_list->current_hash_data[tfc->index] != NULL) { + if(likely(process_list->current_hash_data[tfc->index] != NULL)) { hashed_process_data = process_list->current_hash_data[tfc->index]; } else { hashed_process_data = processlist_get_process_data(process_list, @@ -2354,7 +2354,7 @@ int before_process_hook(void *hook_data, void *call_data) process->last_cpu_index, &birth, tfc->t_context->index); - if(hashed_process_data == NULL) + if(unlikely(hashed_process_data == NULL)) { g_assert(pid == 0 || pid != process->ppid); /* Process not present */ @@ -2389,10 +2389,10 @@ int before_process_hook(void *hook_data, void *call_data) */ g_assert(hashed_process_data->x.over != -1); - if(ltt_time_compare(hashed_process_data->next_good_time, - evtime) > 0) + if(likely(ltt_time_compare(hashed_process_data->next_good_time, + evtime) > 0)) { - if(hashed_process_data->x.middle_marked == FALSE) { + if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { processlist_get_pixels_from_data(process_list, hashed_process_data, &y, @@ -2447,10 +2447,10 @@ int before_process_hook(void *hook_data, void *call_data) /* Jump over draw if we are at the same x position */ - if(x == hashed_process_data->x.middle && - hashed_process_data->x.middle_used) + if(unlikely(x == hashed_process_data->x.middle && + hashed_process_data->x.middle_used)) { - if(hashed_process_data->x.middle_marked == FALSE) { + if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { /* Draw collision indicator */ gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); gdk_draw_point(drawing->pixmap, @@ -2568,7 +2568,7 @@ int after_process_hook(void *hook_data, void *call_data) process_child->last_cpu_index, &birth, tfc->t_context->index); - if(hashed_process_data_child == NULL) + if(likely(hashed_process_data_child == NULL)) { g_assert(child_pid == 0 || child_pid != process_child->ppid); /* Process not present */ @@ -2592,8 +2592,8 @@ int after_process_hook(void *hook_data, void *call_data) } - if(ltt_time_compare(hashed_process_data_child->next_good_time, - evtime) <= 0) + if(likely(ltt_time_compare(hashed_process_data_child->next_good_time, + evtime) <= 0)) { #if 0 processlist_get_pixels_from_data(process_list, @@ -2618,17 +2618,17 @@ int after_process_hook(void *hook_data, void *call_data) width, &new_x); - if(hashed_process_data_child->x.over != new_x) { + if(likely(hashed_process_data_child->x.over != new_x)) { hashed_process_data_child->x.over = new_x; hashed_process_data_child->x.over_used = FALSE; hashed_process_data_child->x.over_marked = FALSE; } - if(hashed_process_data_child->x.middle != new_x) { + if(likely(hashed_process_data_child->x.middle != new_x)) { hashed_process_data_child->x.middle = new_x; hashed_process_data_child->x.middle_used = FALSE; hashed_process_data_child->x.middle_marked = FALSE; } - if(hashed_process_data_child->x.under != new_x) { + if(likely(hashed_process_data_child->x.under != new_x)) { hashed_process_data_child->x.under = new_x; hashed_process_data_child->x.under_used = FALSE; hashed_process_data_child->x.under_marked = FALSE; @@ -2651,7 +2651,7 @@ int after_process_hook(void *hook_data, void *call_data) birth = process->creation_time; - if(process_list->current_hash_data[tfc->index] != NULL) { + if(likely(process_list->current_hash_data[tfc->index] != NULL) ){ hashed_process_data = process_list->current_hash_data[tfc->index]; } else { hashed_process_data = processlist_get_process_data(process_list, @@ -2659,7 +2659,7 @@ int after_process_hook(void *hook_data, void *call_data) process->last_cpu_index, &birth, tfc->t_context->index); - if(hashed_process_data == NULL) + if(unlikely(hashed_process_data == NULL)) { g_assert(pid == 0 || pid != process->ppid); /* Process not present */ @@ -2687,8 +2687,8 @@ int after_process_hook(void *hook_data, void *call_data) hashed_process_data; } - if(ltt_time_compare(hashed_process_data->next_good_time, - evtime) <= 0) + if(unlikely(ltt_time_compare(hashed_process_data->next_good_time, + evtime) <= 0)) { #if 0 processlist_get_pixels_from_data(process_list, @@ -2712,7 +2712,7 @@ int after_process_hook(void *hook_data, void *call_data) evtime, width, &new_x); - if(hashed_process_data->x.middle != new_x) { + if(unlikely(hashed_process_data->x.middle != new_x)) { hashed_process_data->x.middle = new_x; hashed_process_data->x.middle_used = FALSE; hashed_process_data->x.middle_marked = FALSE; @@ -3164,18 +3164,19 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) process = lttv_state_find_process(tfs, process_info->pid); - if(process != NULL) { + if(unlikely(process != NULL)) { /* Only draw for processes that are currently in the trace states */ guint y = 0, height = 0, pl_height = 0; ProcessList *process_list = control_flow_data->process_list; LttTime birth = process_info->birth; - +#ifdef EXTRA_CHECK /* Should be alike when background info is ready */ if(control_flow_data->background_info_waiting==0) g_assert(ltt_time_compare(process->creation_time, process_info->birth) == 0); +#endif //EXTRA_CHECK /* process HAS to be present */ processlist_get_pixels_from_data(process_list, hashed_process_data, @@ -3193,8 +3194,8 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) */ g_assert(hashed_process_data->x.over != -1); - if(ltt_time_compare(hashed_process_data->next_good_time, - evtime) <= 0) + if(unlikely(ltt_time_compare(hashed_process_data->next_good_time, + evtime) <= 0)) { TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab); @@ -3243,8 +3244,8 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) } #endif //0 - if(x == hashed_process_data->x.middle && - hashed_process_data->x.middle_used) { + if(unlikely(x == hashed_process_data->x.middle && + hashed_process_data->x.middle_used)) { #if 0 /* do not mark closure : not missing information */ if(hashed_process_data->x.middle_marked == FALSE) { /* Draw collision indicator */ @@ -3264,7 +3265,7 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) draw_line((void*)&prop_line, (void*)&draw_context); /* become the last x position */ - if(x != hashed_process_data->x.middle) { + if(likely(x != hashed_process_data->x.middle)) { hashed_process_data->x.middle = x; /* but don't use the pixel */ hashed_process_data->x.middle_used = FALSE; diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c b/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c index 93e730ae..6f792f0e 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c @@ -239,27 +239,24 @@ static guint process_list_hash_fct(gconstpointer key) return ((pid>>8 ^ pid>>4 ^ pid>>2 ^ pid) ^ ((ProcessInfo*)key)->cpu); } +/* If hash is good, should be different */ static gboolean process_list_equ_fct(gconstpointer a, gconstpointer b) { const ProcessInfo *pa = (const ProcessInfo*)a; const ProcessInfo *pb = (const ProcessInfo*)b; - if(pa->pid != pb->pid) - return 0; - - if((pa->pid == 0 && (pa->cpu != pb->cpu))) - return 0; - - if(pa->birth.tv_sec != pb->birth.tv_sec) - return 0; - - if(pa->birth.tv_nsec != pb->birth.tv_nsec) - return 0; - - if(pa->trace_num != pb->trace_num) - return 0; - - return 1; + gboolean ret = TRUE; + + if(likely(pa->pid != pb->pid)) + ret = FALSE; + else if(likely((pa->pid == 0 && (pa->cpu != pb->cpu)))) + ret = FALSE; + else if(unlikely(ltt_time_compare(pa->birth, pb->birth) != 0)) + ret = FALSE; + else if(unlikely(pa->trace_num != pb->trace_num)) + ret = FALSE; + + return ret; } void destroy_hash_key(gpointer key); @@ -416,9 +413,9 @@ static gboolean remove_hash_item(ProcessInfo *process_info, gtk_list_store_remove (process_list->list_store, &iter); - if(process_list->current_hash_data != NULL) { - if(hashed_process_data == - process_list->current_hash_data[process_info->cpu]) + if(likely(process_list->current_hash_data != NULL)) { + if(likely(hashed_process_data == + process_list->current_hash_data[process_info->cpu])) process_list->current_hash_data[process_info->cpu] = NULL; } return TRUE; /* remove the element from the hash table */ @@ -550,10 +547,11 @@ int processlist_remove( ProcessList *process_list, process_info.trace_num = trace_num; - if(hashed_process_data = + hashed_process_data = (HashedProcessData*)g_hash_table_lookup( process_list->process_hash, - &process_info)) + &process_info); + if(likely(hashed_process_data != NULL)) { iter = hashed_process_data->y_iter; @@ -562,8 +560,8 @@ int processlist_remove( ProcessList *process_list, g_hash_table_remove(process_list->process_hash, &process_info); - if(process_list->current_hash_data != NULL) { - if(hashed_process_data == process_list->current_hash_data[cpu]) { + if(likely(process_list->current_hash_data != NULL)) { + if(likely(hashed_process_data == process_list->current_hash_data[cpu])) { process_list->current_hash_data[cpu] = NULL; } } -- 2.34.1