diff options
Diffstat (limited to 'erts/emulator')
38 files changed, 247 insertions, 154 deletions
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 1ecda6bfa2..6cd9be5680 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -600,11 +600,6 @@ INCLUDES += -I$(ERL_TOP)/erts/etc/vxworks endif ifeq ($(TARGET),win32) -# Usually the same as the default rule, but certain platforms (i.e. win32) mix -# different compilers -$(OBJDIR)/beam_emu.o: beam/beam_emu.c - $(EMU_CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@ - $(OBJDIR)/dll_sys.o: sys/$(ERLANG_OSTYPE)/sys.c $(CC) $(CFLAGS) -DERL_RUN_SHARED_LIB=1 $(INCLUDES) -c $< -o $@ @@ -618,6 +613,11 @@ $(OBJDIR)/beam_emu.o: beam/beam_emu.c $(CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) \ -OPT:Olimit=0 -WOPT:lpre=off:spre=off:epre=off \ $(INCLUDES) -c $< -o $@ +else +# Usually the same as the default rule, but certain platforms (e.g. win32) mix +# different compilers +$(OBJDIR)/beam_emu.o: beam/beam_emu.c + $(EMU_CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@ endif diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index afdbd65bb5..4b5b5cbdaa 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1145,26 +1145,11 @@ void process_main(void) Eterm *tmp_big; /* Temporary buffer for small bignums if !HEAP_ON_C_STACK. */ #endif -#ifndef ERTS_SMP -#if !HALFWORD_HEAP - static Eterm save_reg[ERTS_X_REGS_ALLOCATED]; - /* X registers -- not used directly, but - * through 'reg', because using it directly - * needs two instructions on a SPARC, - * while using it through reg needs only - * one. - */ -#endif /* - * Floating point registers. - */ - static FloatDef freg[MAX_REG]; -#else - /* X regisers and floating point registers are located in + * X registers and floating point registers are located in * scheduler specific data. */ register FloatDef *freg; -#endif /* * For keeping the negative old value of 'reds' when call saving is active. @@ -1201,14 +1186,6 @@ void process_main(void) init_done = 1; goto init_emulator; } -#ifndef ERTS_SMP -#if !HALFWORD_HEAP - reg = save_reg; /* XXX: probably wastes a register on x86 */ -#else - /* Registers need to be heap allocated (correct memory range) for tracing to work */ - reg = erts_alloc(ERTS_ALC_T_BEAM_REGISTER, ERTS_X_REGS_ALLOCATED * sizeof(Eterm)); -#endif -#endif c_p = NULL; reds_used = 0; goto do_schedule1; @@ -1229,10 +1206,8 @@ void process_main(void) #endif ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p); PROCESS_MAIN_CHK_LOCKS(c_p); -#ifdef ERTS_SMP - reg = c_p->scheduler_data->save_reg; - freg = c_p->scheduler_data->freg; -#endif + reg = ERTS_PROC_GET_SCHDATA(c_p)->x_reg_array; + freg = ERTS_PROC_GET_SCHDATA(c_p)->f_reg_array; #if !HEAP_ON_C_STACK tmp_big = ERTS_PROC_GET_SCHDATA(c_p)->beam_emu_tmp_heap; #endif @@ -5151,10 +5126,8 @@ void process_main(void) c_p->def_arg_reg[4] = -neg_o_reds; reg[0] = r(0); c_p = hipe_mode_switch(c_p, cmd, reg); -#ifdef ERTS_SMP - reg = c_p->scheduler_data->save_reg; - freg = c_p->scheduler_data->freg; -#endif + reg = ERTS_PROC_GET_SCHDATA(c_p)->x_reg_array; + freg = ERTS_PROC_GET_SCHDATA(c_p)->f_reg_array; ERL_BITS_RELOAD_STATEP(c_p); neg_o_reds = -c_p->def_arg_reg[4]; FCALLS = c_p->fcalls; diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index fad81e24d6..16dd5795c7 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -683,6 +683,25 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks, } /* + * Initialize code area. + */ + state.code_buffer_size = erts_next_heap_size(2048 + state.num_functions, 0); + state.code = (BeamInstr *) erts_alloc(ERTS_ALC_T_CODE, + sizeof(BeamInstr) * state.code_buffer_size); + + state.code[MI_NUM_FUNCTIONS] = state.num_functions; + state.ci = MI_FUNCTIONS + state.num_functions + 1; + + state.code[MI_ATTR_PTR] = 0; + state.code[MI_ATTR_SIZE] = 0; + state.code[MI_ATTR_SIZE_ON_HEAP] = 0; + state.code[MI_COMPILE_PTR] = 0; + state.code[MI_COMPILE_SIZE] = 0; + state.code[MI_COMPILE_SIZE_ON_HEAP] = 0; + state.code[MI_NUM_BREAKPOINTS] = 0; + + + /* * Read the atom table. */ @@ -1575,24 +1594,6 @@ read_code_header(LoaderState* stp) #endif } - /* - * Initialize code area. - */ - stp->code_buffer_size = erts_next_heap_size(2048 + stp->num_functions, 0); - stp->code = (BeamInstr *) erts_alloc(ERTS_ALC_T_CODE, - sizeof(BeamInstr) * stp->code_buffer_size); - - stp->code[MI_NUM_FUNCTIONS] = stp->num_functions; - stp->ci = MI_FUNCTIONS + stp->num_functions + 1; - - stp->code[MI_ATTR_PTR] = 0; - stp->code[MI_ATTR_SIZE] = 0; - stp->code[MI_ATTR_SIZE_ON_HEAP] = 0; - stp->code[MI_COMPILE_PTR] = 0; - stp->code[MI_COMPILE_SIZE] = 0; - stp->code[MI_COMPILE_SIZE_ON_HEAP] = 0; - stp->code[MI_NUM_BREAKPOINTS] = 0; - stp->new_bs_put_strings = 0; stp->catches = 0; return 1; diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index b171e99e03..ba30fa85b8 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2010. All Rights Reserved. +# Copyright Ericsson AB 1996-2011. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -87,6 +87,8 @@ bif erlang:exit/2 bif 'erl.lang.proc':signal/2 ebif_signal_2 exit_2 bif erlang:external_size/1 bif 'erl.lang.term':external_size/1 ebif_external_size_1 +bif erlang:external_size/2 +bif 'erl.lang.term':external_size/2 ebif_external_size_2 ubif erlang:float/1 ubif 'erl.lang.number':to_float/1 ebif_to_float_1 float_1 bif erlang:float_to_list/1 diff --git a/erts/emulator/beam/erl_afit_alloc.c b/erts/emulator/beam/erl_afit_alloc.c index d397cd8848..bcc7ea04ae 100644 --- a/erts/emulator/beam/erl_afit_alloc.c +++ b/erts/emulator/beam/erl_afit_alloc.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * Copyright Ericsson AB 2003-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index bbc8a445a7..9af80dd7a9 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -2960,6 +2960,29 @@ erts_allocator_options(void *proc) return res; } +void *erts_alloc_permanent_cache_aligned(ErtsAlcType_t type, Uint size) +{ + UWord v = (UWord) erts_alloc(type, size + (ERTS_CACHE_LINE_SIZE-1)); + +#ifdef VALGRIND + { /* Avoid Leak_PossiblyLost */ + static UWord vg_root_set[10]; + static unsigned ix = 0; + if (ix >= sizeof(vg_root_set) / sizeof(*vg_root_set)) { + erl_exit(ERTS_ABORT_EXIT, "Too many erts_alloc_permanent_cache_aligned's\n"); + } + vg_root_set[ix++] = v; /* not thread safe */ + } +#endif + + if (v & ERTS_CACHE_LINE_MASK) { + v = (v & ~ERTS_CACHE_LINE_MASK) + ERTS_CACHE_LINE_SIZE; + } + ASSERT((v & ERTS_CACHE_LINE_MASK) == 0); + return (void*)v; +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Deprecated functions * * * @@ -3583,6 +3606,4 @@ install_debug_functions(void) return FENCE_SZ; } - - #endif /* #ifdef DEBUG */ diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h index c35a60da22..80cb82c393 100644 --- a/erts/emulator/beam/erl_alloc.h +++ b/erts/emulator/beam/erl_alloc.h @@ -180,11 +180,11 @@ void *erts_realloc(ErtsAlcType_t type, void *ptr, Uint size); void erts_free(ErtsAlcType_t type, void *ptr); void *erts_alloc_fnf(ErtsAlcType_t type, Uint size); void *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size); -void *erts_alloc_permanent_cache_aligned(ErtsAlcType_t type, Uint size); - #endif /* #if !ERTS_ALC_DO_INLINE */ +void *erts_alloc_permanent_cache_aligned(ErtsAlcType_t type, Uint size); + #ifndef ERTS_CACHE_LINE_SIZE /* Assume a cache line size of 64 bytes */ # define ERTS_CACHE_LINE_SIZE ((UWord) 64) @@ -250,18 +250,6 @@ void *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size) size); } -ERTS_ALC_INLINE -void *erts_alloc_permanent_cache_aligned(ErtsAlcType_t type, Uint size) -{ - UWord v = (UWord) erts_alloc(type, size + (ERTS_CACHE_LINE_SIZE-1)); - - if (v & ERTS_CACHE_LINE_MASK) { - v = (v & ~ERTS_CACHE_LINE_MASK) + ERTS_CACHE_LINE_SIZE; - } - ASSERT((v & ERTS_CACHE_LINE_MASK) == 0); - return (void*)v; -} - #endif /* #if ERTS_ALC_DO_INLINE || defined(ERTS_ALC_INTERNAL__) */ typedef void (*erts_alloc_verify_func_t)(Allctr_t *); diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c index 002852cdad..90d8ea7300 100644 --- a/erts/emulator/beam/erl_ao_firstfit_alloc.c +++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * Copyright Ericsson AB 2003-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.h b/erts/emulator/beam/erl_ao_firstfit_alloc.h index 0bf0ec8cee..6fa626f723 100644 --- a/erts/emulator/beam/erl_ao_firstfit_alloc.h +++ b/erts/emulator/beam/erl_ao_firstfit_alloc.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * Copyright Ericsson AB 2003-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/beam/erl_bestfit_alloc.c b/erts/emulator/beam/erl_bestfit_alloc.c index 5e3032ddaa..f2199d41a1 100644 --- a/erts/emulator/beam/erl_bestfit_alloc.c +++ b/erts/emulator/beam/erl_bestfit_alloc.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * Copyright Ericsson AB 2003-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/beam/erl_bestfit_alloc.h b/erts/emulator/beam/erl_bestfit_alloc.h index faa2d9742e..0c29662852 100644 --- a/erts/emulator/beam/erl_bestfit_alloc.h +++ b/erts/emulator/beam/erl_bestfit_alloc.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * Copyright Ericsson AB 2003-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 0509e51a6f..7a08182e18 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1999-2010. All Rights Reserved. + * Copyright Ericsson AB 1999-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -679,7 +679,7 @@ trace_3(Process* p, Eterm pid_spec, Eterm how, Eterm list) } else if (tracer != NIL) { tracee_port->tracer_proc = tracer; } - /* matches are not counted for ports since it would violate compability */ + /* matches are not counted for ports since it would violate compatibility */ /* This could be a reason to modify this function or make a new one. */ } } diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h index 3309ea706b..388d943755 100644 --- a/erts/emulator/beam/erl_bits.h +++ b/erts/emulator/beam/erl_bits.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1999-2010. All Rights Reserved. + * Copyright Ericsson AB 1999-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 59ef8fc3ea..0327850cb9 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -3659,9 +3659,6 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) ret = am_true; else ret = am_false; - } else if (What == am_atom_put("kept_objects",12)) { - ret = make_small(IS_HASH_TABLE(tb->common.status) - ? db_kept_items_hash(&tb->hash) : 0); } else if (What == am_atom_put("safe_fixed",10)) { #ifdef ERTS_SMP erts_smp_mtx_lock(&tb->common.fixlock); @@ -3703,7 +3700,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) Eterm* hp; db_calc_stats_hash(&tb->hash, &stats); - hp = HAlloc(p, 1 + 6 + FLOAT_SIZE_OBJECT*3); + hp = HAlloc(p, 1 + 7 + FLOAT_SIZE_OBJECT*3); f.fd = stats.avg_chain_len; avg = make_float(hp); PUT_DOUBLE(f, hp); @@ -3718,10 +3715,11 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) std_dev_exp = make_float(hp); PUT_DOUBLE(f, hp); hp += FLOAT_SIZE_OBJECT; - ret = TUPLE6(hp, make_small(erts_smp_atomic_read_nob(&tb->hash.nactive)), + ret = TUPLE7(hp, make_small(erts_smp_atomic_read_nob(&tb->hash.nactive)), avg, std_dev_real, std_dev_exp, make_small(stats.min_chain_len), - make_small(stats.max_chain_len)); + make_small(stats.max_chain_len), + make_small(db_kept_items_hash(&tb->hash))); } else { ret = am_false; diff --git a/erts/emulator/beam/erl_goodfit_alloc.c b/erts/emulator/beam/erl_goodfit_alloc.c index 1cc508ac5a..8322b233ac 100644 --- a/erts/emulator/beam/erl_goodfit_alloc.c +++ b/erts/emulator/beam/erl_goodfit_alloc.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2010. All Rights Reserved. + * Copyright Ericsson AB 2003-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 286fe9ff1e..8a297cded0 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -808,10 +808,12 @@ early_init(int *argc, char **argv) /* #if defined(HIPE) hipe_signal_init(); /* must be done very early */ #endif - erl_sys_init(); erl_sys_args(argc, argv); + /* Creates threads on Windows that depend on the arguments, so has to be after erl_sys_args */ + erl_sys_init(); + erts_ets_realloc_always_moves = 0; erts_ets_always_compress = 0; erts_dist_buf_busy_limit = ERTS_DE_BUSY_LIMIT; diff --git a/erts/emulator/beam/erl_instrument.c b/erts/emulator/beam/erl_instrument.c index 04ea004ef7..963c8b3c58 100644 --- a/erts/emulator/beam/erl_instrument.c +++ b/erts/emulator/beam/erl_instrument.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2010. All Rights Reserved. + * Copyright Ericsson AB 2003-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index ea781a6cd0..f3db3f9326 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -578,7 +578,15 @@ int enif_is_identical(Eterm lhs, Eterm rhs) int enif_compare(Eterm lhs, Eterm rhs) { - return CMP(lhs,rhs); + Sint result = CMP(lhs,rhs); + + if (result < 0) { + return -1; + } else if (result > 0) { + return 1; + } + + return result; } int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, const Eterm** array) diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index bbdcf79d00..5ceb4ce9a8 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -1152,13 +1152,6 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) ASSERT(!(flgs & ERTS_SSI_FLG_SLEEPING)); goto sys_woken; } - if (!(flgs & ERTS_SSI_FLG_SLEEPING)) { - flgs = sched_prep_cont_spin_wait(ssi); - if (!(flgs & ERTS_SSI_FLG_WAITING)) { - ASSERT(!(flgs & ERTS_SSI_FLG_SLEEPING)); - goto sys_woken; - } - } /* * If we got new I/O tasks we aren't allowed to @@ -2723,11 +2716,14 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) esdp->match_pseudo_process = NULL; esdp->ssi = ERTS_SCHED_SLEEP_INFO_IX(ix); esdp->free_process = NULL; -#if HALFWORD_HEAP - /* Registers need to be heap allocated (correct memory range) for tracing to work */ - esdp->save_reg = erts_alloc(ERTS_ALC_T_BEAM_REGISTER, ERTS_X_REGS_ALLOCATED * sizeof(Eterm)); -#endif #endif + esdp->x_reg_array = + erts_alloc_permanent_cache_aligned(ERTS_ALC_T_BEAM_REGISTER, + ERTS_X_REGS_ALLOCATED * + sizeof(Eterm)); + esdp->f_reg_array = + erts_alloc_permanent_cache_aligned(ERTS_ALC_T_BEAM_REGISTER, + MAX_REG * sizeof(FloatDef)); #if !HEAP_ON_C_STACK esdp->num_tmp_heap_used = 0; #endif @@ -5785,10 +5781,13 @@ erts_sched_stat_term(Process *p, int total) void erts_schedule_misc_op(void (*func)(void *), void *arg) { - ErtsRunQueue *rq = erts_get_runq_current(NULL); + ErtsRunQueue *rq; ErtsMiscOpList *molp = misc_op_list_alloc(); + ErtsSchedulerData *esdp = erts_get_scheduler_data(); - if (!rq) { + if (esdp) { + rq = esdp->run_queue; + } else { /* * This can only happen when the sys msg dispatcher * thread schedules misc ops (this happens *very* diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 739aef3130..627f10b142 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -387,19 +387,15 @@ do { \ } while (0) struct ErtsSchedulerData_ { - -#ifdef ERTS_SMP /* * Keep X registers first (so we get as many low * numbered registers as possible in the same cache * line). */ -#if !HALFWORD_HEAP - Eterm save_reg[ERTS_X_REGS_ALLOCATED]; /* X registers */ -#else - Eterm *save_reg; -#endif - FloatDef freg[MAX_REG]; /* Floating point registers. */ + Eterm* x_reg_array; /* X registers */ + FloatDef* f_reg_array; /* Floating point registers. */ + +#ifdef ERTS_SMP ethr_tid tid; /* Thread id */ struct erl_bits_state erl_bits_state; /* erl_bits.c state */ void *match_pseudo_process; /* erl_db_util.c:db_prog_match() */ diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h index 9b897ffd24..12eaf39ec7 100644 --- a/erts/emulator/beam/erl_threads.h +++ b/erts/emulator/beam/erl_threads.h @@ -990,8 +990,9 @@ erts_mtx_destroy(erts_mtx_t *mtx) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy mutex"); + erts_thr_fatal_error(res, "destroy mutex"); } #endif } @@ -1094,8 +1095,9 @@ erts_cnd_destroy(erts_cnd_t *cnd) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy condition variable"); + erts_thr_fatal_error(res, "destroy condition variable"); } #endif } @@ -1229,8 +1231,9 @@ erts_rwmtx_destroy(erts_rwmtx_t *rwmtx) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy rwmutex"); + erts_thr_fatal_error(res, "destroy rwmutex"); } #endif } @@ -1693,8 +1696,9 @@ erts_spinlock_destroy(erts_spinlock_t *lock) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy rwlock"); + erts_thr_fatal_error(res, "destroy rwlock"); } #else (void)lock; @@ -1811,8 +1815,9 @@ erts_rwlock_destroy(erts_rwlock_t *lock) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy rwlock"); + erts_thr_fatal_error(res, "destroy rwlock"); } #else (void)lock; diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 1a102f7187..6953e7fe7d 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -459,6 +459,12 @@ Uint erts_encode_ext_size(Eterm term) + 1 /* VERSION_MAGIC */; } +Uint erts_encode_ext_size_2(Eterm term, unsigned dflags) +{ + return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|dflags) + + 1 /* VERSION_MAGIC */; +} + Uint erts_encode_ext_size_ets(Eterm term) { return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS); @@ -1262,6 +1268,49 @@ external_size_1(Process* p, Eterm Term) } Eterm +external_size_2(Process* p, Eterm Term, Eterm Flags) +{ + Uint size; + Uint flags = TERM_TO_BINARY_DFLAGS; + + while (is_list(Flags)) { + Eterm arg = CAR(list_val(Flags)); + Eterm* tp; + + if (is_tuple(arg) && *(tp = tuple_val(arg)) == make_arityval(2)) { + if (tp[1] == am_minor_version && is_small(tp[2])) { + switch (signed_val(tp[2])) { + case 0: + break; + case 1: + flags |= DFLAG_NEW_FLOATS; + break; + default: + goto error; + } + } else { + goto error; + } + } else { + error: + BIF_ERROR(p, BADARG); + } + Flags = CDR(list_val(Flags)); + } + if (is_not_nil(Flags)) { + goto error; + } + + size = erts_encode_ext_size_2(Term, flags); + if (IS_USMALL(0, size)) { + BIF_RET(make_small(size)); + } else { + Eterm* hp = HAlloc(p, BIG_UINT_HEAP_SIZE); + BIF_RET(uint_to_big(size, hp)); + } +} + +Eterm erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags) { Uint size; diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h index d8287b96a4..671b8b8781 100644 --- a/erts/emulator/beam/external.h +++ b/erts/emulator/beam/external.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2010. All Rights Reserved. + * Copyright Ericsson AB 1996-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -160,6 +160,7 @@ Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *); void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *); Uint erts_encode_ext_size(Eterm); +Uint erts_encode_ext_size_2(Eterm, unsigned); Uint erts_encode_ext_size_ets(Eterm); void erts_encode_ext(Eterm, byte **); byte* erts_encode_ext_ets(Eterm, byte *, struct erl_off_heap_header** ext_off_heap); diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index df1f19c482..426917bd2c 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -6539,7 +6539,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, struct linger lg; unsigned int sz = sizeof(lg); - if (sock_getopt(desc->s, IPPROTO_SCTP, SO_LINGER, + if (sock_getopt(desc->s, SOL_SOCKET, SO_LINGER, &lg, &sz) < 0) continue; /* Fill in the response: */ PLACE_FOR(spec, i, @@ -6575,7 +6575,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, { case INET_OPT_RCVBUF : { - proto = IPPROTO_SCTP; + proto = SOL_SOCKET; type = SO_RCVBUF; is_int = 1; tag = am_recbuf; @@ -6583,7 +6583,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, } case INET_OPT_SNDBUF : { - proto = IPPROTO_SCTP; + proto = SOL_SOCKET; type = SO_SNDBUF; is_int = 1; tag = am_sndbuf; @@ -7012,7 +7012,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, default: RETURN_ERROR(spec, -EINVAL); /* No more valid options */ } - /* If we get here one result has been succesfully loaded */ + /* If we get here one result has been successfully loaded */ length ++; } if (buflen != 0) RETURN_ERROR(spec, -EINVAL); /* Optparam mismatch */ @@ -7029,8 +7029,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, i = LOAD_TUPLE(spec, i, 3); /* Now, convert "spec" into the returnable term: */ - /* desc->caller = 0; What does it mean? */ - driver_output_term(desc->port, spec, i); + driver_send_term(desc->port, driver_caller(desc->port), spec, i); FREE(spec); (*dest)[0] = INET_REP_SCTP; diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c index 3d59564f7b..931bb196f1 100755 --- a/erts/emulator/drivers/win32/win_efile.c +++ b/erts/emulator/drivers/win32/win_efile.c @@ -127,6 +127,8 @@ static int errno_map(DWORD last_error) { return EBUSY; case ERROR_NO_PROC_SLOTS: return EAGAIN; + case ERROR_CANT_RESOLVE_FILENAME: + return EMLINK; case ERROR_ARENA_TRASHED: case ERROR_INVALID_BLOCK: case ERROR_BAD_ENVIRONMENT: @@ -1405,7 +1407,7 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size) DWORD fileAttributes = GetFileAttributesW(wname); if ((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { BOOLEAN success = 0; - HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, 0, NULL); + HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); int len; if(h != INVALID_HANDLE_VALUE) { success = pGetFinalPathNameByHandle(h, wbuffer, size,0); @@ -1421,7 +1423,7 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size) if (*wbuffer == L'\\') *wbuffer = L'/'; CloseHandle(h); - } + } FreeLibrary(hModule); if (success) { return 1; diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c index 0b35dbdf04..e5b8cf8a19 100644 --- a/erts/emulator/hipe/hipe_mode_switch.c +++ b/erts/emulator/hipe/hipe_mode_switch.c @@ -473,7 +473,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[]) p = schedule(p, reds_in - p->fcalls); #ifdef ERTS_SMP p->hipe_smp.have_receive_locks = 0; - reg = p->scheduler_data->save_reg; + reg = p->scheduler_data->x_reg_array; #endif } { diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index 81f1c95020..9bd64f5908 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -405,7 +405,7 @@ woke_up(ErtsPollSet ps) static ERTS_INLINE void wake_poller(ErtsPollSet ps, int interrupted) { - int wake; + int wake = 0; #ifdef ERTS_SMP erts_aint32_t wakeup_state; if (!interrupted) diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index fd15635168..82d2c64d81 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -527,7 +527,6 @@ erts_sys_pre_init(void) void erl_sys_init(void) { - erts_smp_rwmtx_init(&environ_rwmtx, "environ"); #if !DISABLE_VFORK { int res; @@ -3090,6 +3089,8 @@ erl_sys_args(int* argc, char** argv) { int i, j; + erts_smp_rwmtx_init(&environ_rwmtx, "environ"); + i = 1; ASSERT(argc && argv); @@ -3151,4 +3152,5 @@ erl_sys_args(int* argc, char** argv) argv[j++] = argv[i]; } *argc = j; + } diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c index ce1d376a54..3e151c26d5 100644 --- a/erts/emulator/sys/win32/sys.c +++ b/erts/emulator/sys/win32/sys.c @@ -2772,7 +2772,7 @@ ready_output(ErlDrvData drv_data, ErlDrvEvent ready_event) DEBUGF(("ready_output(%d, 0x%x)\n", drv_data, ready_event)); set_busy_port(dp->port_num, 0); if (!(dp->outbuf)) { - /* Happens because event sometimes get signalled during a succesful + /* Happens because event sometimes get signalled during a successful write... */ return; } @@ -3283,6 +3283,7 @@ erts_sys_pre_init(void) } #endif erts_smp_atomic_init_nob(&sys_misc_mem_sz, 0); + erts_sys_env_init(); } void noinherit_std_handle(DWORD type) @@ -3298,8 +3299,6 @@ void erl_sys_init(void) { HANDLE handle; - erts_sys_env_init(); - noinherit_std_handle(STD_OUTPUT_HANDLE); noinherit_std_handle(STD_INPUT_HANDLE); noinherit_std_handle(STD_ERROR_HANDLE); diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl index 459dc84565..d9fc876482 100644 --- a/erts/emulator/test/binary_SUITE.erl +++ b/erts/emulator/test/binary_SUITE.erl @@ -441,6 +441,11 @@ terms(Config) when is_list(Config) -> Sz when is_integer(Sz), size(Bin) =< Sz -> ok end, + Bin1 = term_to_binary(Term, [{minor_version, 1}]), + case erlang:external_size(Bin1, [{minor_version, 1}]) of + Sz1 when is_integer(Sz1), size(Bin1) =< Sz1 -> + ok + end, Term = binary_to_term(Bin), Term = binary_to_term(Bin, [safe]), Unaligned = make_unaligned_sub_binary(Bin), @@ -473,7 +478,12 @@ terms_float(Config) when is_list(Config) -> Term = binary_to_term(Bin0), Bin1 = term_to_binary(Term, [{minor_version,1}]), Term = binary_to_term(Bin1), - true = size(Bin1) < size(Bin0) + true = size(Bin1) < size(Bin0), + Size0 = erlang:external_size(Term), + Size00 = erlang:external_size(Term, [{minor_version, 0}]), + Size1 = erlang:external_size(Term, [{minor_version, 1}]), + true = (Size0 =:= Size00), + true = Size1 < Size0 end). external_size(Config) when is_list(Config) -> @@ -489,7 +499,9 @@ external_size(Config) when is_list(Config) -> io:format(" Aligned size: ~p\n", [Sz1]), io:format("Unaligned size: ~p\n", [Sz2]), ?line ?t:fail() - end. + end, + ?line erlang:external_size(Bin) =:= erlang:external_size(Bin, [{minor_version, 1}]), + ?line erlang:external_size(Unaligned) =:= erlang:external_size(Unaligned, [{minor_version, 1}]). external_size_1(Term, Size0, Limit) when Size0 < Limit -> case erlang:external_size(Term) of diff --git a/erts/emulator/test/busy_port_SUITE.erl b/erts/emulator/test/busy_port_SUITE.erl index 8365e1c540..3a29fd4d68 100644 --- a/erts/emulator/test/busy_port_SUITE.erl +++ b/erts/emulator/test/busy_port_SUITE.erl @@ -20,7 +20,7 @@ -module(busy_port_SUITE). -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, + init_per_group/2,end_per_group/2,end_per_testcase/2, io_to_busy/1, message_order/1, send_3/1, system_monitor/1, no_trap_exit/1, no_trap_exit_unlinked/1, trap_exit/1, multiple_writers/1, @@ -53,6 +53,20 @@ init_per_group(_GroupName, Config) -> end_per_group(_GroupName, Config) -> Config. +end_per_testcase(_Case, Config) when is_list(Config) -> + case whereis(busy_drv_server) of + undefined -> + ok; + Pid when is_pid(Pid) -> + Ref = monitor(process, Pid), + unlink(Pid), + exit(Pid, kill), + receive + {'DOWN',Ref,process,Pid,_} -> + ok + end + end, + Config. %% Tests I/O operations to a busy port, to make sure a suspended send %% operation is correctly restarted. This used to crash Beam. @@ -495,12 +509,12 @@ hs_busy_pcmd(Prt, Opts, StartFun, EndFun) -> P = spawn_link(fun () -> erlang:yield(), Tester ! {self(), doing_port_command}, - Start = os:timestamp(), + Start = now(), Res = try {return, port_command(Prt, [], Opts)} catch Exception:Error -> {Exception, Error} end, - End = os:timestamp(), + End = now(), Time = round(timer:now_diff(End, Start)/1000), Tester ! {self(), port_command_result, Res, Time} end), diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl index 4bebae51cc..19281f6d58 100644 --- a/erts/emulator/test/distribution_SUITE.erl +++ b/erts/emulator/test/distribution_SUITE.erl @@ -173,15 +173,20 @@ bulk_sendsend(Terms, BinSize) -> Ratio = if MonitorCount2 == 0 -> MonitorCount1 / 1.0; true -> MonitorCount1 / MonitorCount2 end, - %% A somewhat arbitrary ratio, but hopefully one that will accomodate - %% a wide range of CPU speeds. - true = (Ratio > 8.0), - {comment, - integer_to_list(Rate1) ++ " K/s, " ++ - integer_to_list(Rate2) ++ " K/s, " ++ - integer_to_list(MonitorCount1) ++ " monitor msgs, " ++ - integer_to_list(MonitorCount2) ++ " monitor msgs, " ++ - float_to_list(Ratio) ++ " monitor ratio"}. + Comment = integer_to_list(Rate1) ++ " K/s, " ++ + integer_to_list(Rate2) ++ " K/s, " ++ + integer_to_list(MonitorCount1) ++ " monitor msgs, " ++ + integer_to_list(MonitorCount2) ++ " monitor msgs, " ++ + float_to_list(Ratio) ++ " monitor ratio", + if + %% A somewhat arbitrary ratio, but hopefully one that will + %% accommodate a wide range of CPU speeds. + Ratio > 8.0 -> + {comment,Comment}; + true -> + io:put_chars(Comment), + ?line ?t:fail(ratio_too_low) + end. bulk_sendsend2(Terms, BinSize, BusyBufSize) -> ?line Dog = test_server:timetrap(test_server:seconds(30)), @@ -331,7 +336,7 @@ receiver2(Num, TotSize) -> link_to_busy(doc) -> "Test that link/1 to a busy distribution port works."; link_to_busy(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(30)), + ?line Dog = test_server:timetrap(test_server:seconds(60)), ?line {ok, Node} = start_node(link_to_busy), ?line Recv = spawn(Node, erlang, apply, [fun sink/1, [link_to_busy_sink]]), @@ -378,7 +383,7 @@ tail_applied_linker(Pid) -> exit_to_busy(doc) -> "Test that exit/2 to a busy distribution port works."; exit_to_busy(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(30)), + ?line Dog = test_server:timetrap(test_server:seconds(60)), ?line {ok, Node} = start_node(exit_to_busy), Tracer = case os:getenv("TRACE_BUSY_DIST_PORT") of @@ -1597,8 +1602,8 @@ bad_dist_ext_control(Config) when is_list(Config) -> ?line stop_node(Victim). bad_dist_ext_connection_id(Config) when is_list(Config) -> - ?line {ok, Offender} = start_node(bad_dist_ext_receive_offender), - ?line {ok, Victim} = start_node(bad_dist_ext_receive_victim), + ?line {ok, Offender} = start_node(bad_dist_ext_connection_id_offender), + ?line {ok, Victim} = start_node(bad_dist_ext_connection_id_victim), ?line start_node_monitors([Offender,Victim]), ?line Parent = self(), diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl index f6cf01ce16..a77ea4f3be 100644 --- a/erts/emulator/test/driver_SUITE.erl +++ b/erts/emulator/test/driver_SUITE.erl @@ -1590,7 +1590,7 @@ otp_6879(Config) when is_list(Config) -> end end, Procs), - %% Also try it when input exeeds default buffer (256 bytes) + %% Also try it when input exceeds default buffer (256 bytes) ?line Data = lists:seq(1, 1000), ?line case open_port({spawn, Drv}, []) of Port when is_port(Port) -> diff --git a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c index 0e4065c26b..7c8137dc83 100644 --- a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c +++ b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2010. All Rights Reserved. + * Copyright Ericsson AB 2010-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index 9c31b7f78d..d95789fa6e 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -281,6 +281,12 @@ types(Config) when is_list(Config) -> end, int_list()), ?line verify_tmpmem(TmpMem), + ?line true = (compare(-1294536544000, -1178704800000) < 0), + ?line true = (compare(-1178704800000, -1294536544000) > 0), + ?line true = (compare(-295147905179352825856, -36893488147419103232) < 0), + ?line true = (compare(-36893488147419103232, -295147905179352825856) > 0), + ?line true = (compare(-29514790517935282585612345678, -36893488147419103232) < 0), + ?line true = (compare(-36893488147419103232, -29514790517935282585612345678) > 0), ok. int_list() -> diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index eac56a867d..0a1ef5a78f 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_SUITE.erl @@ -724,6 +724,8 @@ open_ports(Name, Settings) -> []; system_limit -> []; + enomem -> + []; Other -> ?line test_server:fail({open_ports, Other}) end; diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl index f16d0ea429..debb54579b 100644 --- a/erts/emulator/test/scheduler_SUITE.erl +++ b/erts/emulator/test/scheduler_SUITE.erl @@ -87,8 +87,17 @@ init_per_group(_GroupName, Config) -> end_per_group(_GroupName, Config) -> Config. - +init_per_testcase(update_cpu_info, Config) -> + case os:find_executable("taskset") of + false -> + {skip,"Could not find 'taskset' in path"}; + _ -> + init_per_tc(update_cpu_info, Config) + end; init_per_testcase(Case, Config) when is_list(Config) -> + init_per_tc(Case, Config). + +init_per_tc(Case, Config) -> Dog = ?t:timetrap(?DEFAULT_TIMEOUT), process_flag(priority, max), erlang:display({'------------', ?MODULE, Case, '------------'}), @@ -1030,7 +1039,7 @@ sbt_test(Config, CpuTCmd, ClBt, Bt, LP) -> ?line ok. scheduler_suspend(Config) when is_list(Config) -> - ?line Dog = ?t:timetrap(?t:minutes(2)), + ?line Dog = ?t:timetrap(?t:minutes(5)), ?line lists:foreach(fun (S) -> scheduler_suspend_test(Config, S) end, [64, 32, 16, default]), ?line ?t:timetrap_cancel(Dog), diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops index 354439b5e3..ebf7db3277 100755 --- a/erts/emulator/utils/beam_makeops +++ b/erts/emulator/utils/beam_makeops @@ -2,7 +2,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1998-2010. All Rights Reserved. +# Copyright Ericsson AB 1998-2011. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in |