diff options
Diffstat (limited to 'erts/emulator/beam/beam_bp.c')
-rw-r--r-- | erts/emulator/beam/beam_bp.c | 190 |
1 files changed, 104 insertions, 86 deletions
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c index 48e7b6675a..3e776fa951 100644 --- a/erts/emulator/beam/beam_bp.c +++ b/erts/emulator/beam/beam_bp.c @@ -549,6 +549,8 @@ static void bp_hash_rehash(bp_time_hash_t *hash, Uint n) { item[ix].pid = NIL; } + /* rehash, old hash -> new hash */ + for( ix = 0; ix < hash->n; ix++) { if (hash->item[ix].pid != NIL) { @@ -654,45 +656,51 @@ void erts_schedule_time_break(Process *p, Uint schedule) { Uint ix = 0; bp_data_time_item_t sitem, *item = NULL; bp_time_hash_t *h = NULL; + BpDataTime *pbdt = NULL; ASSERT(p); pbt = ERTS_PROC_GET_CALL_TIME(p); +#ifdef ERTS_SMP + ix = p->scheduler_data->no - 1; +#else + ix = 0; +#endif +/* ASSERT( (p->status == P_RUNNING) || (p->status == P_WAITING) || (p->status == P_RUNABLE)); - +*/ if (pbt) { get_sys_now(&ms,&s,&us); switch(schedule) { case ERTS_BP_CALL_TIME_SCHEDULE_EXITING : + break; case ERTS_BP_CALL_TIME_SCHEDULE_OUT : /* When a process is scheduled _out_, * timestamp it and add its delta to * the previous breakpoint. */ -#ifdef ERTS_SMP - ix = p->scheduler_data->no - 1; -#else - ix = 0; -#endif - bp_time_diff(&sitem, pbt, ms, s, us); - sitem.pid = p->id; - sitem.count = 1; - /*count is set to 0 if out and 1 if exiting */ + pbdt = (BpDataTime *) is_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); + if (pbdt) { + bp_time_diff(&sitem, pbt, ms, s, us); + sitem.pid = p->id; + sitem.count = 0; - h = &(pbt->bdt->hash[ix]); + h = &(pbdt->hash[ix]); - ASSERT(h->item); + ASSERT(h); + ASSERT(h->item); - item = bp_hash_get(h, &sitem); - if (!item) { - item = bp_hash_put(h, &sitem); - } else { - BP_TIME_ADD(item, &sitem); + item = bp_hash_get(h, &sitem); + if (!item) { + item = bp_hash_put(h, &sitem); + } else { + BP_TIME_ADD(item, &sitem); + } } break; case ERTS_BP_CALL_TIME_SCHEDULE_IN : @@ -700,21 +708,6 @@ void erts_schedule_time_break(Process *p, Uint schedule) { * timestamp it and remove the previous * timestamp in the psd. */ - sitem.pid = p->id; - sitem.count = -1; - sitem.us_time = 0; - sitem.s_time = 0; - - h = &(pbt->bdt->hash[ix]); - - ASSERT(h->item); - - item = bp_hash_get(h, &sitem); - if (!item) { - item = bp_hash_put(h, &sitem); - } else { - BP_TIME_ADD(item, &sitem); - } pbt->ms = ms; pbt->s = s; pbt->us = us; @@ -748,15 +741,15 @@ void erts_schedule_time_break(Process *p, Uint schedule) { * - egil */ -void erts_do_time_break(Process *p, BpDataTime *bdt, Uint type) { +void erts_trace_time_break(Process *p, BeamInstr *pc, BpDataTime *bdt, Uint type) { Uint ms,s,us; process_breakpoint_time_t *pbt = NULL; int ix = 0; bp_data_time_item_t sitem, *item = NULL; bp_time_hash_t *h = NULL; + BpDataTime *pbdt = NULL; ASSERT(p); - ASSERT(bdt); ASSERT(p->status == P_RUNNING); /* get previous timestamp and breakpoint @@ -765,61 +758,81 @@ void erts_do_time_break(Process *p, BpDataTime *bdt, Uint type) { pbt = ERTS_PROC_GET_CALL_TIME(p); get_sys_now(&ms,&s,&us); +#ifdef ERTS_SMP + ix = p->scheduler_data->no - 1; +#else + ix = 0; +#endif + switch(type) { - case ERTS_BP_CALL_TIME_CALL: /* get pbt * timestamp = t0 + * lookup bdt from code * set ts0 to pbt * add call count here? */ - if (!pbt) { - pbt = Alloc(sizeof(process_breakpoint_time_t)); - (void *) ERTS_PROC_SET_CALL_TIME(p, ERTS_PROC_LOCK_MAIN, pbt); - } - - pbt->bdt = bdt; /* needed for schedule? */ - - pbt->ms = ms; - pbt->s = s; - pbt->us = us; - - - break; + case ERTS_BP_CALL_TIME_CALL: case ERTS_BP_CALL_TIME_TAIL_CALL: - ASSERT(pbt); - -#ifdef ERTS_SMP - ix = p->scheduler_data->no - 1; -#else - ix = 0; -#endif + if (pbt) { + ASSERT(pbt->pc); + /* add time to previous code */ bp_time_diff(&sitem, pbt, ms, s, us); sitem.pid = p->id; - sitem.count = 1; + sitem.count = 0; - h = &(bdt->hash[ix]); + /* previous breakpoint */ + pbdt = (BpDataTime *) is_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); - ASSERT(h->item); + /* if null then the breakpoint was removed */ + if (pbdt) { + h = &(pbdt->hash[ix]); - item = bp_hash_get(h, &sitem); - if (!item) { - item = bp_hash_put(h, &sitem); - } else { - BP_TIME_ADD(item, &sitem); + ASSERT(h); + ASSERT(h->item); + + item = bp_hash_get(h, &sitem); + if (!item) { + item = bp_hash_put(h, &sitem); + } else { + BP_TIME_ADD(item, &sitem); + } } + } else { + /* first call of process to instrumented function */ + pbt = Alloc(sizeof(process_breakpoint_time_t)); + (void *) ERTS_PROC_SET_CALL_TIME(p, ERTS_PROC_LOCK_MAIN, pbt); + } + /* add count to this code */ + sitem.pid = p->id; + sitem.count = 1; + sitem.s_time = 0; + sitem.us_time = 0; - pbt->bdt = bdt; /* needed for schedule? */ + /* this breakpoint */ + ASSERT(bdt); + h = &(bdt->hash[ix]); - pbt->ms = ms; - pbt->s = s; - pbt->us = us; - break; + ASSERT(h); + ASSERT(h->item); + item = bp_hash_get(h, &sitem); + if (!item) { + item = bp_hash_put(h, &sitem); + } else { + BP_TIME_ADD(item, &sitem); + } + + pbt->pc = pc; + pbt->ms = ms; + pbt->s = s; + pbt->us = us; + break; case ERTS_BP_CALL_TIME_RETURN: /* get pbt + * lookup bdt from code * timestamp = t1 * get ts0 from pbt * get item from bdt->hash[bp_hash(p->id)] @@ -830,30 +843,34 @@ void erts_do_time_break(Process *p, BpDataTime *bdt, Uint type) { /* might have been removed due to * trace_pattern(false) */ -#ifdef ERTS_SMP - ix = p->scheduler_data->no - 1; -#else - ix = 0; -#endif + ASSERT(pbt->pc); + bp_time_diff(&sitem, pbt, ms, s, us); sitem.pid = p->id; - sitem.count = 1; + sitem.count = 0; - h = &(bdt->hash[ix]); + /* previous breakpoint */ + pbdt = (BpDataTime *) is_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); - ASSERT(h->item); + if (pbdt) { - item = bp_hash_get(h, &sitem); - if (!item) { - item = bp_hash_put(h, &sitem); - } else { - BP_TIME_ADD(item, &sitem); + h = &(pbdt->hash[ix]); + + ASSERT(h); + ASSERT(h->item); + + item = bp_hash_get(h, &sitem); + if (!item) { + item = bp_hash_put(h, &sitem); + } else { + BP_TIME_ADD(item, &sitem); + } } - pbt->bdt = NULL; - pbt->ms = ms; - pbt->s = s; - pbt->us = us; + pbt->pc = pc; + pbt->ms = ms; + pbt->s = s; + pbt->us = us; } break; } @@ -976,7 +993,8 @@ static int set_function_break(Module *modp, BeamInstr *pc, BpDataTime *bdt = (BpDataTime *) bd; Uint i = 0; - /*XXX: must block system */ + ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0)); + if (count_op == erts_break_stop) { bdt->pause = 1; } else { |