4
* Copyright Ericsson AB 1999-2010. All Rights Reserved.
4
* Copyright Ericsson AB 1999-2011. All Rights Reserved.
6
6
* The contents of this file are subject to the Erlang Public License,
7
7
* Version 1.1, (the "License"); you may not use this file except in
1540
1541
Eterm transformed_args[MAX_ARG];
1541
DeclareTmpHeap(sub_bin_heap_et,ERL_SUB_BIN_SIZE,p);
1542
ErlSubBin *sub_bin_heap = (ErlSubBin *) sub_bin_heap_et;
1542
DeclareTypedTmpHeap(ErlSubBin,sub_bin_heap,p);
1544
1544
ASSERT(tracer_pid);
1545
1545
if (*tracer_pid == am_true) {
1600
1600
if (is_boxed(arg) && header_is_bin_matchstate(*boxed_val(arg))) {
1601
1601
ErlBinMatchState* ms = (ErlBinMatchState *) boxed_val(arg);
1602
1602
ErlBinMatchBuffer* mb = &ms->mb;
1603
ErlSubBin* sb = sub_bin_heap;
1606
1605
ASSERT(sub_bin_heap->thing_word == 0); /* At most one of match context */
1608
1607
bit_size = mb->size - mb->offset;
1609
sb->thing_word = HEADER_SUB_BIN;
1610
sb->size = BYTE_OFFSET(bit_size);
1611
sb->bitsize = BIT_OFFSET(bit_size);
1612
sb->offs = BYTE_OFFSET(mb->offset);
1613
sb->bitoffs = BIT_OFFSET(mb->offset);
1614
sb->is_writable = 0;
1615
sb->orig = mb->orig;
1608
sub_bin_heap->thing_word = HEADER_SUB_BIN;
1609
sub_bin_heap->size = BYTE_OFFSET(bit_size);
1610
sub_bin_heap->bitsize = BIT_OFFSET(bit_size);
1611
sub_bin_heap->offs = BYTE_OFFSET(mb->offset);
1612
sub_bin_heap->bitoffs = BIT_OFFSET(mb->offset);
1613
sub_bin_heap->is_writable = 0;
1614
sub_bin_heap->orig = mb->orig;
1617
arg = make_binary(sb);
1616
arg = make_binary(sub_bin_heap);
1619
1618
transformed_args[i] = arg;
1668
1667
return_flags = 0;
1669
1668
if (match_spec) {
1670
1669
pam_result = erts_match_set_run(p, match_spec, args, arity,
1670
ERTS_PAM_TMP_RESULT, &return_flags);
1672
1671
if (is_non_value(pam_result)) {
1673
1672
erts_match_set_release_result(p);
1674
1673
#if !HEAP_ON_C_STACK
1815
1814
return_flags = 0;
1816
1815
if (match_spec) {
1817
1816
pam_result = erts_match_set_run(p, match_spec, args, arity,
1817
ERTS_PAM_TMP_RESULT, &return_flags);
1819
1818
if (is_non_value(pam_result)) {
1820
1819
erts_match_set_release_result(p);
1821
1820
UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
1945
ERTS_SMP_LC_ASSERT((erts_proc_lc_my_proc_locks(t_p) != 0) || erts_is_system_blocked(0));
1944
ERTS_SMP_LC_ASSERT((erts_proc_lc_my_proc_locks(t_p) != 0)
1945
|| erts_thr_progress_is_blocking());
1946
1946
if (is_internal_port(t_p->tracer_proc)) {
1947
1947
#define LOCAL_HEAP_SIZE (5+5)
1948
1948
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
2094
2094
* entries instead of the original BIF functions.
2097
erts_bif_trace(int bif_index, Process* p,
2098
Eterm arg1, Eterm arg2, Eterm arg3, BeamInstr *I)
2097
erts_bif_trace(int bif_index, Process* p, Eterm* args, BeamInstr* I)
2101
2100
int meta = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_META);
2109
2108
* no tracing will occur. Doing the whole else branch will
2110
2109
* also do nothing, only slower.
2112
Eterm (*func)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = bif_table[bif_index].f;
2113
result = func(p, arg1, arg2, arg3, I);
2111
Eterm (*func)(Process*, Eterm*, BeamInstr*) = bif_table[bif_index].f;
2112
result = func(p, args, I);
2115
Eterm (*func)(Process*, Eterm, Eterm, Eterm, BeamInstr*);
2114
Eterm (*func)(Process*, Eterm*, BeamInstr*);
2116
2115
Export* ep = bif_export[bif_index];
2117
2116
Uint32 flags = 0, flags_meta = 0;
2118
2117
int global = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_GLOBAL);
2124
2123
* export entry */
2125
2124
BeamInstr *cp = p->cp;
2127
Eterm args[3] = {arg1, arg2, arg3};
2130
2127
* Make continuation pointer OK, it is not during direct BIF calls,
2131
2128
* but it is correct during apply of bif.
2158
2155
func = bif_table[bif_index].f;
2160
result = func(p, arg1, arg2, arg3, I);
2157
result = func(p, args, I);
2162
2159
if (applying && (flags & MATCH_SET_RETURN_TO_TRACE)) {
2163
2160
BeamInstr i_return_trace = beam_return_trace[0];
2750
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(t_p) || erts_is_system_blocked(0));
2747
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(t_p)
2748
|| erts_thr_progress_is_blocking());
2752
2750
if (is_internal_port(t_p->tracer_proc)) {
2753
2751
#define LOCAL_HEAP_SIZE (5+5)
3023
3021
static erts_tid_t sys_msg_dispatcher_tid;
3024
3022
static erts_cnd_t smq_cnd;
3026
static int dispatcher_waiting;
3028
3024
ERTS_QUALLOC_IMPL(smq_element, ErtsSysMsgQ, 20, ERTS_ALC_T_SYS_MSG_Q)
3068
3064
erts_smp_mtx_unlock(&smq_mtx);
3072
prepare_for_block(void *unused)
3074
erts_smp_mtx_unlock(&smq_mtx);
3078
resume_after_block(void *unused)
3080
erts_smp_mtx_lock(&smq_mtx);
3084
3068
erts_queue_error_logger_message(Eterm from, Eterm msg, ErlHeapFragment *bp)
3145
3129
&& !erts_system_monitor_flags.busy_port
3146
3130
&& !erts_system_monitor_flags.busy_dist_port)
3147
3131
break; /* Everything is disabled */
3148
erts_smp_block_system(ERTS_BS_FLG_ALLOW_GC);
3132
erts_smp_thr_progress_block();
3149
3133
if (system_monitor == receiver || receiver == NIL)
3150
3134
erts_system_monitor_clear(NULL);
3151
erts_smp_release_system();
3135
erts_smp_thr_progress_unblock();
3153
3137
case SYS_MSG_TYPE_SYSPROF:
3154
3138
if (receiver == NIL
3158
3142
&& !erts_system_profile_flags.scheduler)
3160
3144
/* Block system to clear flags */
3161
erts_smp_block_system(0);
3145
erts_smp_thr_progress_block();
3162
3146
if (system_profile == receiver || receiver == NIL) {
3163
3147
erts_system_profile_clear(NULL);
3165
erts_smp_release_system();
3149
erts_smp_thr_progress_unblock();
3167
3151
case SYS_MSG_TYPE_ERRLGR: {
3168
3152
char *no_elgger = "(no error logger present)";
3191
sys_msg_dispatcher_wakeup(void *vwait_p)
3193
int *wait_p = (int *) vwait_p;
3194
erts_smp_mtx_lock(&smq_mtx);
3196
erts_smp_cnd_signal(&smq_cnd);
3197
erts_smp_mtx_unlock(&smq_mtx);
3201
sys_msg_dispatcher_prep_wait(void *vwait_p)
3203
int *wait_p = (int *) vwait_p;
3204
erts_smp_mtx_lock(&smq_mtx);
3206
erts_smp_mtx_unlock(&smq_mtx);
3210
sys_msg_dispatcher_fin_wait(void *vwait_p)
3212
int *wait_p = (int *) vwait_p;
3213
erts_smp_mtx_lock(&smq_mtx);
3215
erts_smp_mtx_unlock(&smq_mtx);
3219
sys_msg_dispatcher_wait(void *vwait_p)
3221
int *wait_p = (int *) vwait_p;
3222
erts_smp_mtx_lock(&smq_mtx);
3224
erts_smp_cnd_wait(&smq_cnd, &smq_mtx);
3225
erts_smp_mtx_unlock(&smq_mtx);
3207
3229
sys_msg_dispatcher_func(void *unused)
3231
ErtsThrPrgrCallbacks callbacks;
3209
3232
ErtsSysMsgQ *local_sys_message_queue = NULL;
3211
3235
#ifdef ERTS_ENABLE_LOCK_CHECK
3212
3236
erts_lc_set_thread_name("system message dispatcher");
3215
erts_register_blockable_thread();
3216
erts_smp_activity_begin(ERTS_ACTIVITY_IO, NULL, NULL, NULL);
3239
callbacks.arg = (void *) &wait;
3240
callbacks.wakeup = sys_msg_dispatcher_wakeup;
3241
callbacks.prepare_wait = sys_msg_dispatcher_prep_wait;
3242
callbacks.wait = sys_msg_dispatcher_wait;
3243
callbacks.finalize_wait = sys_msg_dispatcher_fin_wait;
3245
erts_thr_progress_register_managed_thread(NULL, &callbacks, 0);
3219
3249
ErtsSysMsgQ *smqp;
3221
ERTS_SMP_LC_ASSERT(!ERTS_LC_IS_BLOCKING);
3251
ERTS_SMP_LC_ASSERT(!erts_thr_progress_is_blocking());
3223
3253
erts_smp_mtx_lock(&smq_mtx);
3232
3262
/* Fetch current trace message queue ... */
3233
erts_smp_activity_change(ERTS_ACTIVITY_IO,
3238
dispatcher_waiting = 1;
3263
if (!sys_message_queue) {
3264
erts_smp_mtx_unlock(&smq_mtx);
3266
erts_thr_progress_active(NULL, 0);
3267
erts_thr_progress_prepare_wait(NULL);
3268
erts_smp_mtx_lock(&smq_mtx);
3239
3271
while (!sys_message_queue)
3240
3272
erts_smp_cnd_wait(&smq_cnd, &smq_mtx);
3241
dispatcher_waiting = 0;
3242
erts_smp_activity_change(ERTS_ACTIVITY_WAIT,
3248
3274
local_sys_message_queue = sys_message_queue;
3249
3275
sys_message_queue = NULL;
3252
3278
erts_smp_mtx_unlock(&smq_mtx);
3281
erts_thr_progress_finalize_wait(NULL);
3282
erts_thr_progress_active(NULL, 1);
3254
3285
/* Send trace messages ... */
3256
3287
ASSERT(local_sys_message_queue);
3424
3457
sys_message_queue_end = NULL;
3425
3458
erts_smp_cnd_init(&smq_cnd);
3426
3459
erts_smp_mtx_init(&smq_mtx, "sys_msg_q");
3427
dispatcher_waiting = 0;
3428
3460
erts_smp_thr_create(&sys_msg_dispatcher_tid,
3429
3461
sys_msg_dispatcher_func,