diff options
-rw-r--r-- | OTP_VERSION | 2 | ||||
-rw-r--r-- | erts/doc/src/erlang.xml | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_bif_info.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_hl_timer.c | 393 | ||||
-rw-r--r-- | erts/emulator/beam/erl_init.c | 2 | ||||
-rw-r--r-- | erts/etc/unix/Makefile | 3 | ||||
-rw-r--r-- | erts/etc/unix/cerl.src | 29 | ||||
-rw-r--r-- | erts/etc/unix/etp-commands.in | 32 | ||||
-rw-r--r-- | erts/etc/unix/etp-rr-run-until-beam.py | 45 | ||||
-rw-r--r-- | lib/erl_interface/src/Makefile.in | 3 | ||||
-rw-r--r-- | lib/inets/doc/src/notes.xml | 24 | ||||
-rw-r--r-- | lib/inets/src/http_client/httpc_handler.erl | 12 | ||||
-rw-r--r-- | lib/inets/vsn.mk | 2 | ||||
-rw-r--r-- | lib/kernel/src/erl_epmd.erl | 8 | ||||
-rw-r--r-- | make/otp_version_tickets_in_merge | 5 | ||||
-rw-r--r-- | otp_versions.table | 1 |
16 files changed, 141 insertions, 424 deletions
diff --git a/OTP_VERSION b/OTP_VERSION index 0f058b4809..ba92843422 100644 --- a/OTP_VERSION +++ b/OTP_VERSION @@ -1 +1 @@ -21.2.4 +21.2.5 diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 0536f4745f..6932b18571 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -8381,7 +8381,7 @@ Metadata = #{ pid => pid(), system time</seealso> that is used by the runtime system.</p> <p>The list contains two-tuples with <c>Key</c>s as first element, and <c>Value</c>s as second element. The - order if these tuples is undefined. The following + order of these tuples is undefined. The following tuples can be part of the list, but more tuples can be introduced in the future:</p> <taglist> diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 6137edef1b..f6a98c85fd 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -2967,7 +2967,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) } else if (ERTS_IS_ATOM_STR("context_reductions", BIF_ARG_1)) { BIF_RET(make_small(CONTEXT_REDS)); } else if (ERTS_IS_ATOM_STR("kernel_poll", BIF_ARG_1)) { -#ifdef ERTS_ENABLE_KERNEL_POLL +#if ERTS_ENABLE_KERNEL_POLL BIF_RET(am_true); #else BIF_RET(am_false); diff --git a/erts/emulator/beam/erl_hl_timer.c b/erts/emulator/beam/erl_hl_timer.c index ef7a55fa38..75ad6de2c9 100644 --- a/erts/emulator/beam/erl_hl_timer.c +++ b/erts/emulator/beam/erl_hl_timer.c @@ -29,8 +29,6 @@ # include "config.h" #endif -/* #define ERTS_MAGIC_REF_BIF_TIMERS */ - #include "sys.h" #include "global.h" #include "bif.h" @@ -39,9 +37,6 @@ #include "erl_time.h" #include "erl_hl_timer.h" #include "erl_proc_sig_queue.h" -#ifdef ERTS_MAGIC_REF_BIF_TIMERS -#include "erl_binary.h" -#endif #define ERTS_TMR_CHECK_CANCEL_ON_CREATE 0 @@ -195,14 +190,9 @@ struct ErtsBifTimer_ { } type; struct { erts_atomic32_t state; -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ErtsMagicBinary *mbin; - ErtsHLTimerList proc_list; -#else Uint32 refn[ERTS_REF_NUMBERS]; ErtsBifTimerTree proc_tree; ErtsBifTimerTree tree; -#endif Eterm message; ErlHeapFragment *bp; } btm; @@ -220,11 +210,7 @@ typedef ErtsTimer *(*ErtsCreateTimerFunc)(ErtsSchedulerData *esdp, int short_time, ErtsTmrType type, void *rcvrp, Eterm rcvr, Eterm msg, -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ErtsMagicBinary *mbin, -#else Uint32 *refn, -#endif void (*callback)(void *), void *arg); #ifdef SMALL_MEMORY @@ -303,16 +289,12 @@ typedef struct { struct ErtsHLTimerService_ { ErtsHLTCncldTmrQ canceled_queue; ErtsHLTimer *time_tree; -#ifndef ERTS_MAGIC_REF_BIF_TIMERS ErtsBifTimer *btm_tree; -#endif ErtsHLTimer *next_timeout; ErtsYieldingTimeoutState yield; ErtsTWheelTimer service_timer; }; -#ifndef ERTS_MAGIC_REF_BIF_TIMERS - static ERTS_INLINE int refn_is_lt(Uint32 *x, Uint32 *y) { @@ -334,8 +316,6 @@ refn_is_eq(Uint32 *x, Uint32 *y) return (x[0] == y[0]) & (x[1] == y[1]) & (x[2] == y[2]); } -#endif - #define ERTS_RBT_PREFIX time #define ERTS_RBT_T ErtsHLTimer #define ERTS_RBT_KEY_T ErtsMonotonicTime @@ -525,13 +505,7 @@ same_time_list_lookup(ErtsHLTimer *root, ErtsHLTimer *x) #endif /* ERTS_HLT_HARD_DEBUG */ -#ifdef ERTS_MAGIC_REF_BIF_TIMERS -#define ERTS_BTM_HLT2REFN(T) ((T)->btm.mbin->refn) -#else #define ERTS_BTM_HLT2REFN(T) ((T)->btm.refn) -#endif - -#ifndef ERTS_MAGIC_REF_BIF_TIMERS #define ERTS_RBT_PREFIX btm #define ERTS_RBT_T ErtsBifTimer @@ -576,87 +550,12 @@ same_time_list_lookup(ErtsHLTimer *root, ErtsHLTimer *x) #define ERTS_RBT_IS_EQ(KX, KY) refn_is_eq((KX), (KY)) #define ERTS_RBT_WANT_DELETE #define ERTS_RBT_WANT_INSERT -#ifndef ERTS_MAGIC_REF_BIF_TIMERS #define ERTS_RBT_WANT_LOOKUP -#endif #define ERTS_RBT_WANT_FOREACH #define ERTS_RBT_UNDEF #include "erl_rbtree.h" -#endif /* !ERTS_MAGIC_REF_BIF_TIMERS */ - -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - -static ERTS_INLINE void -proc_btm_list_insert(ErtsBifTimer **list, ErtsBifTimer *x) -{ - ErtsBifTimer *y = *list; - if (!y) { - x->btm.proc_list.next = x; - x->btm.proc_list.prev = x; - *list = x; - } - else { - ERTS_HLT_ASSERT(y->btm.proc_list.prev->btm.proc_list.next == y); - x->btm.proc_list.next = y; - x->btm.proc_list.prev = y->btm.proc_list.prev; - y->btm.proc_list.prev->btm.proc_list.next = x; - y->btm.proc_list.prev = x; - } -} - -static ERTS_INLINE void -proc_btm_list_delete(ErtsBifTimer **list, ErtsBifTimer *x) -{ - ErtsBifTimer *y = *list; - if (y == x && x->btm.proc_list.next == x) { - ERTS_HLT_ASSERT(x->btm.proc_list.prev == x); - *list = NULL; - } - else { - if (y == x) - *list = x->btm.proc_list.next; - ERTS_HLT_ASSERT(x->btm.proc_list.prev->btm.proc_list.next == x); - ERTS_HLT_ASSERT(x->btm.proc_list.next->btm.proc_list.prev == x); - x->btm.proc_list.prev->btm.proc_list.next = x->btm.proc_list.next; - x->btm.proc_list.next->btm.proc_list.prev = x->btm.proc_list.prev; - } - x->btm.proc_list.next = NULL; -} - -static ERTS_INLINE int -proc_btm_list_foreach_destroy_yielding(ErtsBifTimer **list, - void (*destroy)(ErtsBifTimer *, void *), - void *arg, - int limit) -{ - int i; - ErtsBifTimer *first, *last; - - first = *list; - if (!first) - return 0; - - last = first->btm.proc_list.prev; - for (i = 0; i < limit; i++) { - ErtsBifTimer *x = last; - last = last->btm.proc_list.prev; - (*destroy)(x, arg); - x->btm.proc_list.next = NULL; - if (x == first) { - *list = NULL; - return 0; - } - } - - last->btm.proc_list.next = first; - first->btm.proc_list.prev = last; - return 1; -} - -#else /* !ERTS_MAGIC_REF_BIF_TIMERS */ - #define ERTS_RBT_PREFIX proc_btm #define ERTS_RBT_T ErtsBifTimer #define ERTS_RBT_KEY_T Uint32 * @@ -700,16 +599,12 @@ proc_btm_list_foreach_destroy_yielding(ErtsBifTimer **list, #define ERTS_RBT_IS_EQ(KX, KY) refn_is_eq((KX), (KY)) #define ERTS_RBT_WANT_DELETE #define ERTS_RBT_WANT_INSERT -#ifndef ERTS_MAGIC_REF_BIF_TIMERS #define ERTS_RBT_WANT_LOOKUP -#endif #define ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING #define ERTS_RBT_UNDEF #include "erl_rbtree.h" -#endif /* !ERTS_MAGIC_REF_BIF_TIMERS */ - static void init_canceled_queue(ErtsHLTCncldTmrQ *cq); void @@ -728,9 +623,7 @@ erts_create_timer_service(void) srv = erts_alloc_permanent_cache_aligned(ERTS_ALC_T_TIMER_SERVICE, sizeof(ErtsHLTimerService)); srv->time_tree = NULL; -#ifndef ERTS_MAGIC_REF_BIF_TIMERS srv->btm_tree = NULL; -#endif srv->next_timeout = NULL; srv->yield = init_yield; erts_twheel_init_timer(&srv->service_timer); @@ -805,40 +698,10 @@ port_timeout_common(Port *port, void *tmr) return 0; } -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - -static erts_atomic_t * -mbin_to_btmref__(ErtsMagicBinary *mbin) -{ - return erts_binary_to_magic_indirection((Binary *) mbin); -} - -static ERTS_INLINE void -magic_binary_init(ErtsMagicBinary *mbin, ErtsBifTimer *tmr) -{ - erts_atomic_t *aptr = mbin_to_btmref__(mbin); - erts_atomic_init_nob(aptr, (erts_aint_t) tmr); -} - -static ERTS_INLINE ErtsBifTimer * -magic_binary_to_btm(ErtsMagicBinary *mbin) -{ - erts_atomic_t *aptr = mbin_to_btmref__(mbin); - ErtsBifTimer *tmr = (ErtsBifTimer *) erts_atomic_read_nob(aptr); - ERTS_HLT_ASSERT(!tmr || tmr->btm.mbin == mbin); - return tmr; -} - -#endif /* ERTS_MAGIC_REF_BIF_TIMERS */ - static ERTS_INLINE erts_aint_t init_btm_specifics(ErtsSchedulerData *esdp, ErtsBifTimer *tmr, Eterm msg, -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ErtsMagicBinary *mbin -#else Uint32 *refn -#endif ) { Uint hsz = is_immed(msg) ? ((Uint) 0) : size_object(msg); @@ -853,13 +716,6 @@ init_btm_specifics(ErtsSchedulerData *esdp, tmr->btm.message = copy_struct(msg, hsz, &hp, &bp->off_heap); tmr->btm.bp = bp; } -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - refc = 1; - tmr->btm.mbin = mbin; - erts_refc_inc(&mbin->refc, 1); - magic_binary_init(mbin, tmr); - tmr->btm.proc_list.next = NULL; -#else refc = 0; tmr->btm.refn[0] = refn[0]; tmr->btm.refn[1] = refn[1]; @@ -868,7 +724,6 @@ init_btm_specifics(ErtsSchedulerData *esdp, tmr->btm.proc_tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; btm_rbt_insert(&esdp->timer_service->btm_tree, tmr); -#endif erts_atomic32_init_nob(&tmr->btm.state, ERTS_TMR_STATE_ACTIVE); return refc; /* refc from magic binary... */ @@ -886,11 +741,6 @@ timer_destroy(ErtsTimer *tmr, int twt, int btm) erts_free(ERTS_ALC_T_HL_PTIMER, tmr); } else { -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - Binary *bp = (Binary *) tmr->btm.btm.mbin; - if (erts_refc_dectest(&bp->refc, 0) == 0) - erts_bin_free(bp); -#endif if (tmr->head.roflgs & ERTS_TMR_ROFLG_PRE_ALC) bif_timer_pre_free(&tmr->btm); else @@ -940,9 +790,6 @@ schedule_tw_timer_destroy(ErtsTWTimer *tmr) else { /* Message buffer already dropped... */ size = sizeof(ErtsBifTimer); -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - size += sizeof(ErtsMagicIndirectionWord); -#endif } erts_schedule_thr_prgr_later_cleanup_op( @@ -1006,11 +853,7 @@ create_tw_timer(ErtsSchedulerData *esdp, int short_time, ErtsTmrType type, void *rcvrp, Eterm rcvr, Eterm msg, -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ErtsMagicBinary *mbin, -#else Uint32 *refn, -#endif void (*callback)(void *), void *arg) { ErtsTWTimer *tmr; @@ -1087,11 +930,7 @@ create_tw_timer(ErtsSchedulerData *esdp, refc += init_btm_specifics(esdp, (ErtsBifTimer *) tmr, msg, -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - mbin -#else refn -#endif ); break; @@ -1152,9 +991,6 @@ schedule_hl_timer_destroy(ErtsHLTimer *tmr, Uint32 roflgs) else { /* Message buffer already dropped... */ size = sizeof(ErtsBifTimer); -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - size += sizeof(ErtsMagicIndirectionWord); -#endif } erts_schedule_thr_prgr_later_cleanup_op( @@ -1192,34 +1028,6 @@ check_canceled_queue(ErtsSchedulerData *esdp, ErtsHLTimerService *srv) #endif } -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - -static int -bif_timer_ref_destructor(Binary *unused) -{ - return 1; -} - -static ERTS_INLINE void -btm_clear_magic_binary(ErtsBifTimer *tmr) -{ - erts_atomic_t *aptr = mbin_to_btmref__(tmr->btm.mbin); - Uint32 roflgs = tmr->type.head.roflgs; -#ifdef ERTS_HLT_DEBUG - erts_aint_t tval = erts_atomic_xchg_nob(aptr, - (erts_aint_t) NULL); - ERTS_HLT_ASSERT(tval == (erts_aint_t) tmr); -#else - erts_atomic_set_nob(aptr, (erts_aint_t) NULL); -#endif - if (roflgs & ERTS_TMR_ROFLG_HLT) - hl_timer_dec_refc(&tmr->type.hlt, roflgs); - else - tw_timer_dec_refc(&tmr->type.twt); -} - -#endif /* ERTS_MAGIC_REF_BIF_TIMERS */ - static ERTS_INLINE void bif_timer_timeout(ErtsHLTimerService *srv, ErtsBifTimer *tmr, @@ -1240,10 +1048,6 @@ bif_timer_timeout(ErtsHLTimerService *srv, if (state == ERTS_TMR_STATE_ACTIVE) { Process *proc; -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - btm_clear_magic_binary(tmr); -#endif - if (roflgs & ERTS_TMR_ROFLG_REG_NAME) { Eterm term; term = tmr->type.head.receiver.name; @@ -1266,18 +1070,11 @@ bif_timer_timeout(ErtsHLTimerService *srv, erts_proc_lock(proc, ERTS_PROC_LOCK_BTM); /* If the process is exiting do not disturb the cleanup... */ if (!ERTS_PROC_IS_EXITING(proc)) { -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - if (tmr->btm.proc_list.next) { - proc_btm_list_delete(&proc->bif_timers, tmr); - dec_refc = 1; - } -#else if (tmr->btm.proc_tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) { proc_btm_rbt_delete(&proc->bif_timers, tmr); tmr->btm.proc_tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; dec_refc = 1; } -#endif } erts_proc_unlock(proc, ERTS_PROC_LOCK_BTM); if (dec_refc) @@ -1287,25 +1084,18 @@ bif_timer_timeout(ErtsHLTimerService *srv, free_message_buffer(tmr->btm.bp); } -#ifndef ERTS_MAGIC_REF_BIF_TIMERS if (tmr->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) { btm_rbt_delete(&srv->btm_tree, tmr); tmr->btm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; } -#endif - } static void tw_bif_timer_timeout(void *vbtmp) { -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ErtsHLTimerService *srv = NULL; -#else ErtsSchedulerData *esdp = erts_get_scheduler_data(); ErtsHLTimerService *srv = esdp->timer_service; -#endif ErtsBifTimer *btmp = (ErtsBifTimer *) vbtmp; bif_timer_timeout(srv, btmp, btmp->type.head.roflgs); tw_timer_dec_refc(&btmp->type.twt); @@ -1317,11 +1107,7 @@ create_hl_timer(ErtsSchedulerData *esdp, int short_time, ErtsTmrType type, void *rcvrp, Eterm rcvr, Eterm msg, -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ErtsMagicBinary *mbin, -#else Uint32 *refn, -#endif void (*callback)(void *), void *arg) { ErtsHLTimerService *srv = esdp->timer_service; @@ -1407,11 +1193,7 @@ create_hl_timer(ErtsSchedulerData *esdp, refc += init_btm_specifics(esdp, (ErtsBifTimer *) tmr, msg, -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - mbin -#else refn -#endif ); } @@ -1628,7 +1410,6 @@ cleanup_sched_local_canceled_timer(ErtsSchedulerData *esdp, ERTS_HLT_ASSERT((tmr->head.roflgs & ERTS_TMR_ROFLG_SID_MASK) == (Uint32) esdp->no); -#ifndef ERTS_MAGIC_REF_BIF_TIMERS if (roflgs & ERTS_TMR_ROFLG_BIF_TMR) { ErtsBifTimer *btm = (ErtsBifTimer *) tmr; if (btm->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) { @@ -1636,7 +1417,6 @@ cleanup_sched_local_canceled_timer(ErtsSchedulerData *esdp, btm->btm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; } } -#endif if (roflgs & ERTS_TMR_ROFLG_HLT) { hlt_delete_timer(esdp, &tmr->hlt); @@ -1909,9 +1689,6 @@ setup_bif_timer(Process *c_p, int twheel, ErtsMonotonicTime timeout_pos, Eterm ref, tmo_msg, *hp; ErtsBifTimer *tmr; ErtsSchedulerData *esdp; -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - Binary *mbin; -#endif Eterm tmp_hp[4]; ErtsCreateTimerFunc create_timer; @@ -1920,18 +1697,10 @@ setup_bif_timer(Process *c_p, int twheel, ErtsMonotonicTime timeout_pos, esdp = erts_proc_sched_data(c_p); -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - mbin = erts_create_magic_indirection(bif_timer_ref_destructor); - hp = HAlloc(c_p, ERTS_MAGIC_REF_THING_SIZE); - ref = erts_mk_magic_ref(&hp, &c_p->off_heap, mbin); - ASSERT(erts_get_ref_numbers_thr_id(((ErtsMagicBinary *)mbin)->refn) - == (Uint32) esdp->no); -#else hp = HAlloc(c_p, ERTS_REF_THING_SIZE); ref = erts_sched_make_ref_in_buffer(esdp, hp); ASSERT(erts_get_ref_numbers_thr_id(internal_ordinary_ref_numbers(ref)) == (Uint32) esdp->no); -#endif tmo_msg = wrap ? TUPLE3(tmp_hp, am_timeout, ref, msg) : msg; @@ -1939,11 +1708,7 @@ setup_bif_timer(Process *c_p, int twheel, ErtsMonotonicTime timeout_pos, tmr = (ErtsBifTimer *) create_timer(esdp, timeout_pos, short_time, ERTS_TMR_BIF, NULL, rcvr, tmo_msg, -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - (ErtsMagicBinary *) mbin, -#else internal_ordinary_ref_numbers(ref), -#endif NULL, NULL); if (is_internal_pid(rcvr)) { @@ -1951,14 +1716,10 @@ setup_bif_timer(Process *c_p, int twheel, ErtsMonotonicTime timeout_pos, rcvr, ERTS_PROC_LOCK_BTM, ERTS_P2P_FLG_INC_REFC); if (!proc) { -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - btm_clear_magic_binary(tmr); -#else if (tmr->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) { btm_rbt_delete(&esdp->timer_service->btm_tree, tmr); tmr->btm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; } -#endif if (tmr->btm.bp) free_message_buffer(tmr->btm.bp); if (twheel) @@ -1968,11 +1729,7 @@ setup_bif_timer(Process *c_p, int twheel, ErtsMonotonicTime timeout_pos, timer_destroy((ErtsTimer *) tmr, twheel, 1); } else { -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - proc_btm_list_insert(&proc->bif_timers, tmr); -#else proc_btm_rbt_insert(&proc->bif_timers, tmr); -#endif erts_proc_unlock(proc, ERTS_PROC_LOCK_BTM); tmr->type.head.receiver.proc = proc; } @@ -2000,10 +1757,6 @@ cancel_bif_timer(ErtsBifTimer *tmr) if (state != ERTS_TMR_STATE_ACTIVE) return 0; -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - btm_clear_magic_binary(tmr); -#endif - if (tmr->btm.bp) free_message_buffer(tmr->btm.bp); @@ -2022,19 +1775,12 @@ cancel_bif_timer(ErtsBifTimer *tmr) * the btm tree by itself (it may be in * the middle of tree destruction). */ -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - if (!ERTS_PROC_IS_EXITING(proc) && tmr->btm.proc_list.next) { - proc_btm_list_delete(&proc->bif_timers, tmr); - res = 1; - } -#else if (!ERTS_PROC_IS_EXITING(proc) && tmr->btm.proc_tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) { proc_btm_rbt_delete(&proc->bif_timers, tmr); tmr->btm.proc_tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; res = 1; } -#endif erts_proc_unlock(proc, ERTS_PROC_LOCK_BTM); } @@ -2075,12 +1821,10 @@ access_btm(ErtsBifTimer *tmr, Uint32 sid, ErtsSchedulerData *esdp, int cancel) queue_canceled_timer(esdp, sid, (ErtsTimer *) tmr); } else { -#ifndef ERTS_MAGIC_REF_BIF_TIMERS if (tmr->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) { btm_rbt_delete(&esdp->timer_service->btm_tree, tmr); tmr->btm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; } -#endif if (is_hlt) { if (cncl_res > 0) hl_timer_dec_refc(&tmr->type.hlt, tmr->type.hlt.head.roflgs); @@ -2157,52 +1901,6 @@ send_async_info(Process *proc, ErtsProcLocks initial_locks, return am_ok; } -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - -static BIF_RETTYPE -access_bif_timer(Process *c_p, Eterm tref, int cancel, int async, int info) -{ - BIF_RETTYPE ret; - Eterm res; - Sint64 time_left; - - if (!is_internal_magic_ref(tref)) { - if (is_not_ref(tref)) { - ERTS_BIF_PREP_ERROR(ret, c_p, BADARG); - return ret; - } - time_left = -1; - } - else { - ErtsMagicBinary *mbin; - mbin = (ErtsMagicBinary *) erts_magic_ref2bin(tref); - if (mbin->destructor != bif_timer_ref_destructor) - time_left = -1; - else { - ErtsBifTimer *tmr; - Uint32 sid; - tmr = magic_binary_to_btm(mbin); - sid = erts_get_ref_numbers_thr_id(internal_magic_ref_numbers(tref)); - ASSERT(1 <= sid && sid <= erts_no_schedulers); - time_left = access_btm(tmr, sid, erts_proc_sched_data(c_p), cancel); - } - } - - if (!info) - res = am_ok; - else if (!async) - res = return_info(c_p, time_left); - else - res = send_async_info(c_p, ERTS_PROC_LOCK_MAIN, - tref, cancel, time_left); - - ERTS_BIF_PREP_RET(ret, res); - - return ret; -} - -#else /* !ERTS_MAGIC_REF_BIF_TIMERS */ - static ERTS_INLINE Eterm send_sync_info(Process *proc, ErtsProcLocks initial_locks, Uint32 *refn, int cancel, Sint64 time_left) @@ -2505,8 +2203,6 @@ no_timer: return no_timer_result(c_p, tref, cancel, async, info); } -#endif /* !ERTS_MAGIC_REF_BIF_TIMERS */ - static ERTS_INLINE int bool_arg(Eterm val, int *argp) { @@ -2584,18 +2280,11 @@ exit_cancel_bif_timer(ErtsBifTimer *tmr, void *vesdp) is_hlt = !!(roflgs & ERTS_TMR_ROFLG_HLT); ERTS_HLT_ASSERT(sid == erts_get_ref_numbers_thr_id(ERTS_BTM_HLT2REFN(tmr))); -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ERTS_HLT_ASSERT(tmr->btm.proc_list.next); -#else ERTS_HLT_ASSERT(tmr->btm.proc_tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE); tmr->btm.proc_tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; -#endif if (state == ERTS_TMR_STATE_ACTIVE) { -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - btm_clear_magic_binary(tmr); -#endif if (tmr->btm.bp) free_message_buffer(tmr->btm.bp); @@ -2604,12 +2293,10 @@ exit_cancel_bif_timer(ErtsBifTimer *tmr, void *vesdp) return; } -#ifndef ERTS_MAGIC_REF_BIF_TIMERS if (tmr->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) { btm_rbt_delete(&esdp->timer_service->btm_tree, tmr); tmr->btm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE; } -#endif if (is_hlt) hlt_delete_timer(esdp, &tmr->type.hlt); else @@ -2627,28 +2314,17 @@ exit_cancel_bif_timer(ErtsBifTimer *tmr, void *vesdp) # define ERTS_BTM_MAX_DESTROY_LIMIT 50 #endif -#ifndef ERTS_MAGIC_REF_BIF_TIMERS typedef struct { ErtsBifTimers *bif_timers; union { proc_btm_rbt_yield_state_t proc_btm_yield_state; } u; } ErtsBifTimerYieldState; -#endif int erts_cancel_bif_timers(Process *p, ErtsBifTimers **btm, void **vyspp) { ErtsSchedulerData *esdp = erts_proc_sched_data(p); -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - - return proc_btm_list_foreach_destroy_yielding(btm, - exit_cancel_bif_timer, - (void *) esdp, - ERTS_BTM_MAX_DESTROY_LIMIT); - -#else /* !ERTS_MAGIC_REF_BIF_TIMERS */ - ErtsBifTimerYieldState ys = {*btm, {ERTS_RBT_YIELD_STAT_INITER}}; ErtsBifTimerYieldState *ysp; int res; @@ -2682,7 +2358,6 @@ int erts_cancel_bif_timers(Process *p, ErtsBifTimers **btm, void **vyspp) return res; -#endif /* !ERTS_MAGIC_REF_BIF_TIMERS */ } static ERTS_INLINE int @@ -3116,11 +2791,6 @@ btm_print(ErtsBifTimer *tmr, void *vbtmp, ErtsMonotonicTime tpos, int is_hlt) ErtsMonotonicTime left; Eterm receiver; -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - if (!(tmr->type.head.roflgs & ERTS_TMR_ROFLG_BIF_TMR)) - return; -#endif - if (is_hlt) { ERTS_HLT_ASSERT(tmr->type.head.roflgs & ERTS_TMR_ROFLG_HLT); if (tmr->type.hlt.timeout <= btmp->now) @@ -3149,22 +2819,6 @@ btm_print(ErtsBifTimer *tmr, void *vbtmp, ErtsMonotonicTime tpos, int is_hlt) (Sint64) left); } -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - -static void -hlt_btm_print(ErtsHLTimer *tmr, void *vbtmp) -{ - btm_print((ErtsBifTimer *) tmr, vbtmp, 0, 1); -} - -static void -twt_btm_print(void *vbtmp, ErtsMonotonicTime tpos, void *vtwtp) -{ - btm_print((ErtsBifTimer *) vtwtp, vbtmp, tpos, 0); -} - -#else - static void btm_tree_print(ErtsBifTimer *tmr, void *vbtmp) { @@ -3177,8 +2831,6 @@ btm_tree_print(ErtsBifTimer *tmr, void *vbtmp) btm_print(tmr, vbtmp, tpos, is_hlt); } -#endif - void erts_print_bif_timer_info(fmtfn_t to, void *to_arg) { @@ -3196,15 +2848,7 @@ erts_print_bif_timer_info(fmtfn_t to, void *to_arg) for (six = 0; six < erts_no_schedulers; six++) { ErtsHLTimerService *srv = erts_aligned_scheduler_data[six].esd.timer_service; -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ErtsTimerWheel *twheel = - erts_aligned_scheduler_data[six].esd.timer_wheel; - erts_twheel_debug_foreach(twheel, tw_bif_timer_timeout, - twt_btm_print, (void *) &btmp); - time_rbt_foreach(srv->time_tree, hlt_btm_print, (void *) &btmp); -#else btm_rbt_foreach(srv->btm_tree, btm_tree_print, (void *) &btmp); -#endif } } @@ -3219,10 +2863,6 @@ typedef struct { static void debug_btm_foreach(ErtsBifTimer *tmr, void *vbtmfd) { -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - if (!(tmr->type.head.roflgs & ERTS_TMR_ROFLG_BIF_TMR)) - return; -#endif if (erts_atomic32_read_nob(&tmr->btm.state) == ERTS_TMR_STATE_ACTIVE) { ErtsBTMForeachDebug *btmfd = (ErtsBTMForeachDebug *) vbtmfd; Eterm id = ((tmr->type.head.roflgs & ERTS_TMR_ROFLG_REG_NAME) @@ -3232,22 +2872,6 @@ debug_btm_foreach(ErtsBifTimer *tmr, void *vbtmfd) } } -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - -static void -hlt_debug_btm_foreach(ErtsHLTimer *tmr, void *vbtmfd) -{ - debug_btm_foreach((ErtsBifTimer *) tmr, vbtmfd); -} - -static void -twt_debug_btm_foreach(void *vbtmfd, ErtsMonotonicTime tpos, void *vtwtp) -{ - debug_btm_foreach((ErtsBifTimer *) vtwtp, vbtmfd); -} - -#endif - void erts_debug_bif_timer_foreach(void (*func)(Eterm, Eterm, @@ -3267,20 +2891,9 @@ erts_debug_bif_timer_foreach(void (*func)(Eterm, for (six = 0; six < erts_no_schedulers; six++) { ErtsHLTimerService *srv = erts_aligned_scheduler_data[six].esd.timer_service; -#ifdef ERTS_MAGIC_REF_BIF_TIMERS - ErtsTimerWheel *twheel = - erts_aligned_scheduler_data[six].esd.timer_wheel; - erts_twheel_debug_foreach(twheel, tw_bif_timer_timeout, - twt_debug_btm_foreach, - (void *) &btmfd); - time_rbt_foreach(srv->time_tree, - hlt_debug_btm_foreach, - (void *) &btmfd); -#else btm_rbt_foreach(srv->btm_tree, debug_btm_foreach, (void *) &btmfd); -#endif } } @@ -3403,9 +3016,7 @@ st_hdbg_func(ErtsHLTimer *tmr, void *vhdbg) } ERTS_HLT_ASSERT(tmr->time.tree.u.l.next->time.tree.u.l.prev == tmr); ERTS_HLT_ASSERT(tmr->time.tree.u.l.prev->time.tree.u.l.next == tmr); -#ifndef ERTS_MAGIC_REF_BIF_TIMERS ERTS_HLT_ASSERT(btm_rbt_lookup(hdbg->srv->btm_tree, ERTS_BTM_HLT2REFN(tmr)) == tmr); -#endif } static void @@ -3434,10 +3045,8 @@ tt_hdbg_func(ErtsHLTimer *tmr, void *vhdbg) & ~ERTS_HLT_PFLGS_MASK); ERTS_HLT_ASSERT(tmr == prnt); } -#ifndef ERTS_MAGIC_REF_BIF_TIMERS if (tmr->head.roflgs & ERTS_TMR_ROFLG_BIF_TMR) ERTS_HLT_ASSERT(btm_rbt_lookup(hdbg->srv->btm_tree, ERTS_BTM_HLT2REFN(tmr)) == tmr); -#endif if (tmr->time.tree.same_time) { ErtsHdbgHLT st_hdbg; st_hdbg.srv = hdbg->srv; @@ -3503,7 +3112,6 @@ hdbg_chk_srv(ErtsHLTimerService *srv) time_rbt_foreach(srv->time_tree, tt_hdbg_func, (void *) &hdbg); ERTS_HLT_ASSERT(hdbg.found_root); } -#ifndef ERTS_MAGIC_REF_BIF_TIMERS if (srv->btm_tree) { ErtsHdbgHLT hdbg; hdbg.srv = srv; @@ -3512,7 +3120,6 @@ hdbg_chk_srv(ErtsHLTimerService *srv) btm_rbt_foreach(srv->btm_tree, bt_hdbg_func, (void *) &hdbg); ERTS_HLT_ASSERT(hdbg.found_root); } -#endif } #endif /* ERTS_HLT_HARD_DEBUG */ diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 41bec17dfa..30da0c83e0 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -78,7 +78,7 @@ const char etp_erts_version[] = ERLANG_VERSION; const char etp_otp_release[] = ERLANG_OTP_RELEASE; const char etp_compile_date[] = ERLANG_COMPILE_DATE; const char etp_arch[] = ERLANG_ARCHITECTURE; -#ifdef ERTS_ENABLE_KERNEL_POLL +#if ERTS_ENABLE_KERNEL_POLL const int erts_use_kernel_poll = 1; const int etp_kernel_poll_support = 1; #else diff --git a/erts/etc/unix/Makefile b/erts/etc/unix/Makefile index 83c64d35fd..21a725cb88 100644 --- a/erts/etc/unix/Makefile +++ b/erts/etc/unix/Makefile @@ -30,7 +30,8 @@ opt debug lcnt: etc etc: etp-commands etp-commands: etp-commands.in - $(gen_verbose)sed 's:@ERL_TOP@:${ERL_TOP}:g' etp-commands.in > etp-commands + $(gen_verbose)sed -e 's:@ERL_TOP@:${ERL_TOP}:g' \ + etp-commands.in > etp-commands .PHONY: docs docs: diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 2e034513b0..bcd64d242e 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -224,7 +224,13 @@ while [ $# -gt 0 ]; do shift cargs="$cargs -rr" run_rr=yes - skip_erlexec=yes + case "$1" in + "replay"|"ps") + ;; + *) + skip_erlexec=yes + ;; + esac ;; *) break @@ -307,7 +313,26 @@ if [ "x$GDB" = "x" ]; then exec $taskset1 valgrind $valgrind_xml $valgrind_log $valgrind_misc_flags $BINDIR/$EMU_NAME $sched_arg $emu_xargs "$@" elif [ $run_rr = yes ]; then - exec rr record --ignore-nested $BINDIR/$EMU_NAME $emu_xargs "$@" + if [ $1 = replay ]; then + shift + cmdfile="/tmp/.cerlgdb.$$" + echo "set \$etp_beam_executable = \"$BINDIR/$EMU_NAME\"" > $cmdfile + if [ "$1" = "-p" ]; then + echo 'set $etp_rr_run_until_beam = 1' >> $cmdfile + fi + cat $ROOTDIR/erts/etc/unix/etp-commands.in >> $cmdfile + exec rr replay -x $cmdfile $* + elif [ $1 = ps ]; then + shift + rr ps $* | head -1 + ChildSetup=`rr ps $* | grep 'erl_child_setup' | awk '{ print $2 }'` + for CS in $ChildSetup; do + rr ps $* | grep -E "^$CS" + done + exit 0 + else + exec rr record --ignore-nested $BINDIR/$EMU_NAME $emu_xargs "$@" + fi else exec $EXEC $xargs ${1+"$@"} fi diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index b12a205ba7..54b7628137 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -149,7 +149,7 @@ define etp-1 else # (($arg0) & 0x3) == 0 if (($arg0) == etp_the_non_value) - printf "<the non-value>" + printf "<the-non-value>" else etp-cp-1 ($arg0) end @@ -1241,7 +1241,7 @@ define etp-sig-int if $etp_sig_tag != etp_the_non_value etp-1 $etp_sig_tag 0 else - print "!ENCODED-DIST-MSG" + printf "!ENCODED-DIST-MSG" end if ($arg0)->m[1] != $etp_nil printf " @token= " @@ -1251,7 +1251,7 @@ define etp-sig-int etp-1 ($arg0)->m[2] 0 else if ($etp_sig_tag & 0x3f) != 0x30 - print "!INVALID-SIGNAL" + printf "!INVALID-SIGNAL" else set $etp_sig_op = (($etp_sig_tag >> 6) & 0xff) set $etp_sig_type = (($etp_sig_tag >> 14) & 0xff) @@ -4326,6 +4326,20 @@ document etp-show %--------------------------------------------------------------------------- end +define etp-rr-run-until-beam + source @ERL_TOP@/erts/etc/unix/etp-rr-run-until-beam.py +end + +document etp-rr-run-until-beam +%--------------------------------------------------------------------------- +% etp-rr-run-until-beam +% +% Use this gdb macro to make cerl -rr replay -p PID walk until +% the correct execute has been made. You may have to change the +% file that is used to debug with. +%--------------------------------------------------------------------------- +end + ############################################################################ # Init # @@ -4359,11 +4373,19 @@ document etp-init %--------------------------------------------------------------------------- end +macro define offsetof(t, f) &((t *) 0)->f) + define hook-run set $_exitsignal = -1 end +handle SIGPIPE nostop + etp-init help etp-init -etp-show -etp-system-info +if $etp_rr_run_until_beam + help etp-rr-run-until-beam +else + etp-show + etp-system-info +end diff --git a/erts/etc/unix/etp-rr-run-until-beam.py b/erts/etc/unix/etp-rr-run-until-beam.py new file mode 100644 index 0000000000..078998b910 --- /dev/null +++ b/erts/etc/unix/etp-rr-run-until-beam.py @@ -0,0 +1,45 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2013-2016. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# %CopyrightEnd% +# + +has_exited = False + +def stop_handler (event): + global has_exited + if isinstance(event, gdb.SignalEvent): + print("exit code: %s" % (event.stop_signal)) + has_exited = True + +gdb.events.stop.connect (stop_handler) + +gdb.execute('continue') + +while not has_exited: + r = gdb.execute('when', to_string=True) + m = re.match("[^0-9]*([0-9]+)", r) + if m: + event = int(m.group(1)); + gdb.execute('start ' + str(event + 1)); + gdb.execute('continue') + +gdb.events.stop.disconnect (stop_handler) + +gdb.execute('file ' + str(gdb.parse_and_eval("$etp_beam_executable"))) +gdb.execute('break main') +gdb.execute('reverse-continue') diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in index 614e7325a9..24ead76afb 100644 --- a/lib/erl_interface/src/Makefile.in +++ b/lib/erl_interface/src/Makefile.in @@ -31,12 +31,11 @@ .PHONY : debug opt release clean distclean depend -TARGET = @TARGET@ - # ---------------------------------------------------- # Application version and release dir specification # ---------------------------------------------------- include ../vsn.mk +include $(ERL_TOP)/make/target.mk include $(TARGET)/eidefs.mk include $(ERL_TOP)/make/output.mk diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index cf39ab4796..3624c6e3d7 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,7 +33,29 @@ <file>notes.xml</file> </header> - <section><title>Inets 7.0.4</title> + <section><title>Inets 7.0.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed bug that causes a crash in http client when using + hostnames (e.g. localhost) with the the option + ipv6_host_with_brackets set to true.</p> + <p> + This change also fixes a regression: httpc:request fails + with connection error (nxdomain) if option + ipv6_host_with_brackets set to true and host component of + the URI is an IPv6 address.</p> + <p> + Own Id: OTP-15554 Aux Id: ERIERL-289 </p> + </item> + </list> + </section> + +</section> + +<section><title>Inets 7.0.4</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index 8b356d8026..8d443a1477 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -805,12 +805,11 @@ handle_unix_socket_options(#request{unix_socket = UnixSocket}, error({badarg, [{ipfamily, Else}, {unix_socket, UnixSocket}]}) end. -connect_and_send_first_request(Address, #request{ipv6_host_with_brackets = HasBrackets} = Request, - #state{options = Options0} = State) -> +connect_and_send_first_request(Address, Request, #state{options = Options0} = State) -> SocketType = socket_type(Request), ConnTimeout = (Request#request.settings)#http_options.connect_timeout, Options = handle_unix_socket_options(Request, Options0), - case connect(SocketType, format_address(Address, HasBrackets), Options, ConnTimeout) of + case connect(SocketType, format_address(Address), Options, ConnTimeout) of {ok, Socket} -> ClientClose = httpc_request:is_client_closing( @@ -1739,9 +1738,8 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) -> {stacktrace, Stacktrace}]}} end. - -format_address({Host, Port}, true) when is_list(Host)-> - {ok, Address} = inet:parse_address(string:strip(string:strip(Host, right, $]), left, $[)), +format_address({[$[|T], Port}) -> + {ok, Address} = inet:parse_address(string:strip(T, right, $])), {Address, Port}; -format_address(HostPort, _) -> +format_address(HostPort) -> HostPort. diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 1d1560213e..921161dce1 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 7.0.4 +INETS_VSN = 7.0.5 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/kernel/src/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl index b7e8868911..7a14e2635c 100644 --- a/lib/kernel/src/erl_epmd.erl +++ b/lib/kernel/src/erl_epmd.erl @@ -77,8 +77,8 @@ stop() -> %% -spec port_please(Name, Host) -> {ok, Port, Version} | noport when - Name :: string(), - Host :: inet:ip_address(), + Name :: atom() | string(), + Host :: atom() | string() | inet:ip_address(), Port :: non_neg_integer(), Version :: non_neg_integer(). @@ -86,8 +86,8 @@ port_please(Node, Host) -> port_please(Node, Host, infinity). -spec port_please(Name, Host, Timeout) -> {ok, Port, Version} | noport when - Name :: string(), - Host :: inet:ip_address(), + Name :: atom() | string(), + Host :: atom() | string() | inet:ip_address(), Timeout :: non_neg_integer() | infinity, Port :: non_neg_integer(), Version :: non_neg_integer(). diff --git a/make/otp_version_tickets_in_merge b/make/otp_version_tickets_in_merge index 4e6277bc58..921f8b53fe 100644 --- a/make/otp_version_tickets_in_merge +++ b/make/otp_version_tickets_in_merge @@ -1,4 +1 @@ -OTP-15536 -OTP-15537 -OTP-15538 -OTP-15544 +OTP-15554 diff --git a/otp_versions.table b/otp_versions.table index cd64800534..37b1e738f1 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,3 +1,4 @@ +OTP-21.2.5 : inets-7.0.5 # asn1-5.0.8 common_test-1.16.1 compiler-7.3.1 crypto-4.4 debugger-4.2.6 dialyzer-3.3.1 diameter-2.1.6 edoc-0.9.4 eldap-1.2.6 erl_docgen-0.8.1 erl_interface-3.10.4 erts-10.2.3 et-1.6.4 eunit-2.3.7 ftp-1.0.1 hipe-3.18.2 jinterface-1.9.1 kernel-6.2 megaco-3.18.4 mnesia-4.15.5 observer-2.8.2 odbc-2.12.2 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.4 reltool-0.7.8 runtime_tools-1.13.1 sasl-3.3 snmp-5.2.12 ssh-4.7.3 ssl-9.1.2 stdlib-3.7 syntax_tools-2.1.6 tftp-1.0.1 tools-3.0.2 wx-1.8.6 xmerl-1.3.19 : OTP-21.2.4 : erts-10.2.3 inets-7.0.4 # asn1-5.0.8 common_test-1.16.1 compiler-7.3.1 crypto-4.4 debugger-4.2.6 dialyzer-3.3.1 diameter-2.1.6 edoc-0.9.4 eldap-1.2.6 erl_docgen-0.8.1 erl_interface-3.10.4 et-1.6.4 eunit-2.3.7 ftp-1.0.1 hipe-3.18.2 jinterface-1.9.1 kernel-6.2 megaco-3.18.4 mnesia-4.15.5 observer-2.8.2 odbc-2.12.2 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.4 reltool-0.7.8 runtime_tools-1.13.1 sasl-3.3 snmp-5.2.12 ssh-4.7.3 ssl-9.1.2 stdlib-3.7 syntax_tools-2.1.6 tftp-1.0.1 tools-3.0.2 wx-1.8.6 xmerl-1.3.19 : OTP-21.2.3 : compiler-7.3.1 erts-10.2.2 ssl-9.1.2 xmerl-1.3.19 # asn1-5.0.8 common_test-1.16.1 crypto-4.4 debugger-4.2.6 dialyzer-3.3.1 diameter-2.1.6 edoc-0.9.4 eldap-1.2.6 erl_docgen-0.8.1 erl_interface-3.10.4 et-1.6.4 eunit-2.3.7 ftp-1.0.1 hipe-3.18.2 inets-7.0.3 jinterface-1.9.1 kernel-6.2 megaco-3.18.4 mnesia-4.15.5 observer-2.8.2 odbc-2.12.2 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.4 reltool-0.7.8 runtime_tools-1.13.1 sasl-3.3 snmp-5.2.12 ssh-4.7.3 stdlib-3.7 syntax_tools-2.1.6 tftp-1.0.1 tools-3.0.2 wx-1.8.6 : OTP-21.2.2 : ssh-4.7.3 # asn1-5.0.8 common_test-1.16.1 compiler-7.3 crypto-4.4 debugger-4.2.6 dialyzer-3.3.1 diameter-2.1.6 edoc-0.9.4 eldap-1.2.6 erl_docgen-0.8.1 erl_interface-3.10.4 erts-10.2.1 et-1.6.4 eunit-2.3.7 ftp-1.0.1 hipe-3.18.2 inets-7.0.3 jinterface-1.9.1 kernel-6.2 megaco-3.18.4 mnesia-4.15.5 observer-2.8.2 odbc-2.12.2 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.4 reltool-0.7.8 runtime_tools-1.13.1 sasl-3.3 snmp-5.2.12 ssl-9.1.1 stdlib-3.7 syntax_tools-2.1.6 tftp-1.0.1 tools-3.0.2 wx-1.8.6 xmerl-1.3.18 : |