aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_emu.c
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2010-05-06 20:18:21 +0200
committerRaimo Niskanen <[email protected]>2010-06-03 14:54:21 +0200
commitff9531eb5e6aaa5a4802db0db5e0e850f4233702 (patch)
treeaad69f5d5bc1ceb56b6476a016b744d2bb02567b /erts/emulator/beam/beam_emu.c
parent9a5848fc667acb2aedeb39af94d16a9b346aa47e (diff)
downloadotp-ff9531eb5e6aaa5a4802db0db5e0e850f4233702.tar.gz
otp-ff9531eb5e6aaa5a4802db0db5e0e850f4233702.tar.bz2
otp-ff9531eb5e6aaa5a4802db0db5e0e850f4233702.zip
Add a scheduler array for BpData at BeamInstr[-4]
To solve the issue of multiple schedulers constantly updating the head pointer to the bp data wheel, each scheduler now has its own entrypoint to the wheel. This head pointer can be updated without a locking being taken. Previously there were no lock ...
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r--erts/emulator/beam/beam_emu.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 29d0c0afde..6313319b9b 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -4415,23 +4415,28 @@ apply_bif_or_nif_epilogue:
OpCase(i_time_breakpoint): {
BeamInstr real_I;
- BpDataTime *bdt = (BpDataTime *) (I)[-4];
- Uint tail_call = 0;
+ BpData **bds = (BpData **) (I)[-4];
+ BpDataTime *bdt = NULL;
+ Uint ix = 0;
+#ifdef ERTS_SMP
+ ix = c_p->scheduler_data->no - 1;
+#else
+ ix = 0;
+#endif
+ bdt = (BpDataTime *)bds[ix];
ASSERT((I)[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI));
ASSERT(bdt);
bdt = (BpDataTime *) bdt->next;
ASSERT(bdt);
- (I)[-4] = (BeamInstr) bdt;
+ bds[ix] = (BpData *) bdt;
real_I = bdt->orig_instr;
ASSERT(VALID_INSTR(real_I));
if (IS_TRACED_FL(c_p, F_TRACE_CALLS) && !(bdt->pause)) {
- if (*cp_val((Eterm)c_p->cp) == (BeamInstr) OpCode(i_return_time_trace)) {
- tail_call = 1;
- }
-
- if (tail_call) {
+ if ( (*(c_p->cp) == (BeamInstr) OpCode(i_return_time_trace)) ||
+ (*(c_p->cp) == (BeamInstr) OpCode(return_trace)) ||
+ (*(c_p->cp) == (BeamInstr) OpCode(i_return_to_trace))) {
/* This _IS_ a tail recursive call */
SWAPOUT;
erts_trace_time_break(c_p, I, bdt, ERTS_BP_CALL_TIME_TAIL_CALL);
@@ -4458,7 +4463,7 @@ apply_bif_or_nif_epilogue:
E -= 2;
E[0] = make_cp(I);
E[1] = make_cp(c_p->cp); /* original return address */
- c_p->cp = (Eterm *) make_cp(beam_return_time_trace);
+ c_p->cp = (BeamInstr *) make_cp(beam_return_time_trace);
}
}
@@ -4488,18 +4493,20 @@ apply_bif_or_nif_epilogue:
BeamInstr real_I;
Uint32 flags;
Eterm tracer_pid;
- Uint *cpp;
+ BeamInstr *cpp;
int return_to_trace = 0, need = 0;
flags = 0;
SWAPOUT;
reg[0] = r(0);
if (*(c_p->cp) == (BeamInstr) OpCode(return_trace)) {
- cpp = (Uint*)&E[2];
- } else if (*(c_p->cp)
- == (BeamInstr) OpCode(i_return_to_trace)) {
+ cpp = (BeamInstr*)&E[2];
+ } else if (*(c_p->cp) == (BeamInstr) OpCode(i_return_to_trace)) {
+ return_to_trace = !0;
+ cpp = (BeamInstr*)&E[0];
+ } else if (*(c_p->cp) == (BeamInstr) OpCode(i_return_time_trace)) {
return_to_trace = !0;
- cpp = (Uint*)&E[0];
+ cpp = (BeamInstr*)&E[0];
} else {
cpp = NULL;
}
@@ -4516,6 +4523,8 @@ apply_bif_or_nif_epilogue:
} else if (*cp_val(*cpp) == (BeamInstr) OpCode(i_return_to_trace)) {
return_to_trace = !0;
cpp += 1;
+ } else if (*cp_val(*cpp) == (BeamInstr) OpCode(i_return_time_trace)) {
+ cpp += 2;
} else
break;
}