~clint-fewbar/ubuntu/precise/erlang/merge-15b

« back to all changes in this revision

Viewing changes to erts/emulator/beam/erl_trace.c

  • Committer: Package Import Robot
  • Author(s): Sergei Golovan
  • Date: 2011-12-15 19:20:10 UTC
  • mfrom: (1.1.18) (3.5.15 sid)
  • mto: (3.5.16 sid)
  • mto: This revision was merged to the branch mainline in revision 33.
  • Revision ID: package-import@ubuntu.com-20111215192010-jnxcfe3tbrpp0big
Tags: 1:15.b-dfsg-1
* New upstream release.
* Upload to experimental because this release breaks external drivers
  API along with ABI, so several applications are to be fixed.
* Removed SSL patch because the old SSL implementation is removed from
  the upstream distribution.
* Removed never used patch which added native code to erlang beam files.
* Removed the erlang-docbuilder binary package because the docbuilder
  application was dropped by upstream.
* Documented dropping ${erlang-docbuilder:Depends} substvar in
  erlang-depends(1) manpage.
* Made erlang-base and erlang-base-hipe provide virtual package
  erlang-abi-15.b (the number means the first erlang version, which
  provides current ABI).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * %CopyrightBegin%
3
3
 *
4
 
 * Copyright Ericsson AB 1999-2010. All Rights Reserved.
 
4
 * Copyright Ericsson AB 1999-2011. All Rights Reserved.
5
5
 *
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
36
36
#include "error.h"
37
37
#include "erl_binary.h"
38
38
#include "erl_bits.h"
 
39
#include "erl_thr_progress.h"
39
40
 
40
41
#if 0
41
42
#define DEBUG_PRINTOUTS
159
160
void
160
161
erts_system_profile_setup_active_schedulers(void)
161
162
{
162
 
    ERTS_SMP_LC_ASSERT(erts_is_system_blocked(0));
 
163
    ERTS_SMP_LC_ASSERT(erts_thr_progress_is_blocking());
163
164
    active_sched = erts_active_schedulers();
164
165
}
165
166
 
1538
1539
    Eterm tracee;
1539
1540
#endif
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);
1543
1543
 
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;
1604
1603
            Uint bit_size;
1605
1604
 
1606
1605
            ASSERT(sub_bin_heap->thing_word == 0); /* At most one of match context */
1607
1606
 
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;
1616
1615
 
1617
 
            arg = make_binary(sb);
 
1616
            arg = make_binary(sub_bin_heap);
1618
1617
        }
1619
1618
        transformed_args[i] = arg;
1620
1619
    }
1668
1667
        return_flags = 0;
1669
1668
        if (match_spec) {
1670
1669
            pam_result = erts_match_set_run(p, match_spec, args, arity,
1671
 
                                            &return_flags);
 
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,
1818
 
                                            &return_flags);
 
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);
1942
1941
    Eterm* hp;
1943
1942
    int need;
1944
1943
 
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.
2095
2095
 */
2096
2096
Eterm
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)
2099
2098
{
2100
2099
    Eterm result;
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.
2111
2110
         */
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);
2114
2113
    } else {
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;
2126
2125
        
2127
 
        Eterm args[3] = {arg1, arg2, arg3};
2128
 
        
2129
2126
        /* 
2130
2127
         * Make continuation pointer OK, it is not during direct BIF calls,
2131
2128
         * but it is correct during apply of bif.
2157
2154
        
2158
2155
        func = bif_table[bif_index].f;
2159
2156
 
2160
 
        result = func(p, arg1, arg2, arg3, I);
 
2157
        result = func(p, args, I);
2161
2158
        
2162
2159
        if (applying && (flags & MATCH_SET_RETURN_TO_TRACE)) {
2163
2160
            BeamInstr i_return_trace      = beam_return_trace[0];
2747
2744
    Eterm mess;
2748
2745
    Eterm* hp;
2749
2746
 
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());
2751
2749
 
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;
3025
3023
 
3026
 
static int dispatcher_waiting;
3027
 
 
3028
3024
ERTS_QUALLOC_IMPL(smq_element, ErtsSysMsgQ, 20, ERTS_ALC_T_SYS_MSG_Q)
3029
3025
 
3030
3026
static void
3068
3064
    erts_smp_mtx_unlock(&smq_mtx);
3069
3065
}
3070
3066
 
3071
 
static void
3072
 
prepare_for_block(void *unused)
3073
 
{
3074
 
    erts_smp_mtx_unlock(&smq_mtx);
3075
 
}
3076
 
 
3077
 
static void
3078
 
resume_after_block(void *unused)
3079
 
{
3080
 
    erts_smp_mtx_lock(&smq_mtx);
3081
 
}
3082
 
 
3083
3067
void
3084
3068
erts_queue_error_logger_message(Eterm from, Eterm msg, ErlHeapFragment *bp)
3085
3069
{
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();
3152
3136
        break;
3153
3137
         case SYS_MSG_TYPE_SYSPROF:
3154
3138
        if (receiver == NIL
3158
3142
            && !erts_system_profile_flags.scheduler)
3159
3143
                 break;
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);
3164
3148
        }
3165
 
        erts_smp_release_system();
 
3149
        erts_smp_thr_progress_unblock();
3166
3150
        break;
3167
3151
    case SYS_MSG_TYPE_ERRLGR: {
3168
3152
        char *no_elgger = "(no error logger present)";
3203
3187
    }
3204
3188
}
3205
3189
 
 
3190
static void
 
3191
sys_msg_dispatcher_wakeup(void *vwait_p)
 
3192
{
 
3193
    int *wait_p = (int *) vwait_p;
 
3194
    erts_smp_mtx_lock(&smq_mtx);
 
3195
    *wait_p = 0;
 
3196
    erts_smp_cnd_signal(&smq_cnd);
 
3197
    erts_smp_mtx_unlock(&smq_mtx);
 
3198
}
 
3199
 
 
3200
static void
 
3201
sys_msg_dispatcher_prep_wait(void *vwait_p)
 
3202
{
 
3203
    int *wait_p = (int *) vwait_p;
 
3204
    erts_smp_mtx_lock(&smq_mtx);
 
3205
    *wait_p = 1;
 
3206
    erts_smp_mtx_unlock(&smq_mtx);
 
3207
}
 
3208
 
 
3209
static void
 
3210
sys_msg_dispatcher_fin_wait(void *vwait_p)
 
3211
{
 
3212
    int *wait_p = (int *) vwait_p;
 
3213
    erts_smp_mtx_lock(&smq_mtx);
 
3214
    *wait_p = 0;
 
3215
    erts_smp_mtx_unlock(&smq_mtx);
 
3216
}
 
3217
 
 
3218
static void
 
3219
sys_msg_dispatcher_wait(void *vwait_p)
 
3220
{
 
3221
    int *wait_p = (int *) vwait_p;
 
3222
    erts_smp_mtx_lock(&smq_mtx);
 
3223
    while (*wait_p)
 
3224
        erts_smp_cnd_wait(&smq_cnd, &smq_mtx);
 
3225
    erts_smp_mtx_unlock(&smq_mtx);
 
3226
}
 
3227
 
3206
3228
static void *
3207
3229
sys_msg_dispatcher_func(void *unused)
3208
3230
{
 
3231
    ErtsThrPrgrCallbacks callbacks;
3209
3232
    ErtsSysMsgQ *local_sys_message_queue = NULL;
 
3233
    int wait = 0;
3210
3234
 
3211
3235
#ifdef ERTS_ENABLE_LOCK_CHECK
3212
3236
    erts_lc_set_thread_name("system message dispatcher");
3213
3237
#endif
3214
3238
 
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;
 
3244
 
 
3245
    erts_thr_progress_register_managed_thread(NULL, &callbacks, 0);
3217
3246
 
3218
3247
    while (1) {
 
3248
        int end_wait = 0;
3219
3249
        ErtsSysMsgQ *smqp;
3220
3250
 
3221
 
        ERTS_SMP_LC_ASSERT(!ERTS_LC_IS_BLOCKING);
 
3251
        ERTS_SMP_LC_ASSERT(!erts_thr_progress_is_blocking());
3222
3252
 
3223
3253
        erts_smp_mtx_lock(&smq_mtx);
3224
3254
 
3230
3260
        }
3231
3261
 
3232
3262
        /* Fetch current trace message queue ... */
3233
 
        erts_smp_activity_change(ERTS_ACTIVITY_IO,
3234
 
                                 ERTS_ACTIVITY_WAIT,
3235
 
                                 prepare_for_block,
3236
 
                                 resume_after_block,
3237
 
                                 NULL);
3238
 
        dispatcher_waiting = 1;
 
3263
        if (!sys_message_queue) {
 
3264
            erts_smp_mtx_unlock(&smq_mtx);
 
3265
            end_wait = 1;
 
3266
            erts_thr_progress_active(NULL, 0);
 
3267
            erts_thr_progress_prepare_wait(NULL);
 
3268
            erts_smp_mtx_lock(&smq_mtx);
 
3269
        }
 
3270
 
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,
3243
 
                                 ERTS_ACTIVITY_IO,
3244
 
                                 prepare_for_block,
3245
 
                                 resume_after_block,
3246
 
                                 NULL);
3247
3273
 
3248
3274
        local_sys_message_queue = sys_message_queue;
3249
3275
        sys_message_queue = NULL;
3251
3277
 
3252
3278
        erts_smp_mtx_unlock(&smq_mtx);
3253
3279
 
 
3280
        if (end_wait) {
 
3281
            erts_thr_progress_finalize_wait(NULL);
 
3282
            erts_thr_progress_active(NULL, 1);
 
3283
        }
 
3284
 
3254
3285
        /* Send trace messages ... */
3255
3286
 
3256
3287
        ASSERT(local_sys_message_queue);
3261
3292
            Process *proc = NULL;
3262
3293
            Port *port = NULL;
3263
3294
 
 
3295
            if (erts_thr_progress_update(NULL))
 
3296
                erts_thr_progress_leader_update(NULL);
 
3297
 
3264
3298
#ifdef DEBUG_PRINTOUTS
3265
3299
            print_msg_type(smqp);
3266
3300
#endif
3374
3408
        }
3375
3409
    }
3376
3410
 
3377
 
    erts_smp_activity_end(ERTS_ACTIVITY_IO, NULL, NULL, NULL);
3378
3411
    return NULL;
3379
3412
}
3380
3413
 
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,
3430
3462
                        NULL,