Example #1
0
File: time.c Project: 1153/otp
/* this routine links the time cells into a free list at the start
   and sets the time queue as empty */
void
erts_init_time(void)
{
    int i, itime;

    /* system dependent init; must be done before do_time_init()
       if timer thread is enabled */
    itime = erts_init_time_sup();
#ifdef TIW_ITIME_IS_CONSTANT 
    if (itime != TIW_ITIME) {
	erl_exit(ERTS_ABORT_EXIT, "timer resolution mismatch %d != %d", itime, TIW_ITIME);
    }
#else
    tiw_itime = itime;
#endif

    erts_smp_mtx_init(&tiw_lock, "timer_wheel");

    tiw = (ErlTimer**) erts_alloc(ERTS_ALC_T_TIMER_WHEEL,
				  TIW_SIZE * sizeof(ErlTimer*));
    for(i = 0; i < TIW_SIZE; i++)
	tiw[i] = NULL;
    do_time_init();
    tiw_pos = tiw_nto = 0;
    tiw_min_ptr = NULL;
    tiw_min = 0;
}
Example #2
0
int 
erts_init_time_sup(void)
{
    erts_smp_mtx_init(&erts_timeofday_mtx, "timeofday");

    last_emu_time.tv_sec = 0;
    last_emu_time.tv_usec = 0;

#ifndef SYS_CLOCK_RESOLUTION
    clock_resolution = sys_init_time();
#else
    (void) sys_init_time();
#endif
    sys_gettimeofday(&inittv);
    
#ifdef HAVE_GETHRTIME
    sys_init_hrtime();
#endif
    init_tolerant_timeofday();

    init_erts_deliver_time(&inittv);
    gtv = inittv;
    then.tv_sec = then.tv_usec = 0;

    erts_get_emu_time(&erts_first_emu_time);

    return CLOCK_RESOLUTION;
}    
Example #3
0
void 
erts_bp_init(void) {
    erts_smp_atomic32_init_nob(&erts_active_bp_index, 0);
    erts_smp_atomic32_init_nob(&erts_staging_bp_index, 1);
#ifdef ERTS_DIRTY_SCHEDULERS
    erts_smp_mtx_init(&erts_dirty_bp_ix_mtx, "dirty_break_point_index", NIL,
        ERTS_LOCK_FLAGS_PROPERTY_STATIC | ERTS_LOCK_FLAGS_CATEGORY_DEBUG);
#endif
}
Example #4
0
void
erts_beam_bif_load_init(void)
{
    erts_smp_mtx_init(&release_literal_areas.mtx, "release_literal_areas");
    release_literal_areas.first = NULL;
    release_literal_areas.last = NULL;
    erts_smp_atomic_init_nob(&erts_copy_literal_area__,
			     (erts_aint_t) NULL);

    init_purge_state();
}
Example #5
0
void erts_code_ix_init(void)
{
    /* We start emulator by initializing preloaded modules
     * single threaded with active and staging set both to zero.
     * Preloading is finished by a commit that will set things straight.
     */
    erts_smp_atomic32_init_nob(&the_active_code_index, 0);
    erts_smp_atomic32_init_nob(&the_staging_code_index, 0);
    erts_smp_mtx_init(&the_code_ix_queue_lock, "code_ix_queue");
    CIX_TRACE("init");
}
Example #6
0
File: code_ix.c Project: AugHu/otp
void erts_code_ix_init(void)
{
    /* We start emulator by initializing preloaded modules
     * single threaded with active and staging set both to zero.
     * Preloading is finished by a commit that will set things straight.
     */
    erts_smp_atomic32_init_nob(&the_active_code_index, 0);
    erts_smp_atomic32_init_nob(&the_staging_code_index, 0);
    erts_smp_mtx_init(&code_write_permission_mtx, "code_write_permission");
#ifdef ERTS_ENABLE_LOCK_CHECK
    erts_tsd_key_create(&has_code_write_permission,
			"erts_has_code_write_permission");
#endif
    CIX_TRACE("init");
}
Example #7
0
void
init_export_table(void)
{
    int i;

    erts_smp_mtx_init(&export_staging_lock, "export_tab");
    erts_smp_atomic_init_nob(&total_entries_bytes, 0);

    export_tables = erts_alloc(ERTS_ALC_T_EXPORT_TABLE,
			       sizeof(IndexTable)*ERTS_NUM_CODE_IX);

    for (i=0; i<ERTS_NUM_CODE_IX; i++) {
	erts_index_init(ERTS_ALC_T_EXPORT_TABLE, &export_tables[i], "export_list",
			EXPORT_INITIAL_SIZE, EXPORT_LIMIT, fun);
    }
}
Example #8
0
/*
** Init a pre allocated or static hash structure
** and allocate buckets. NOT SAFE
*/
SafeHash* safe_hash_init(ErtsAlcType_t type, SafeHash* h, char* name, int size, SafeHashFunctions fun)
{
    int i, bytes;

    size = align_up_pow2(size);
    bytes = size * sizeof(SafeHashBucket*);
    h->type = type;
    h->tab = (SafeHashBucket**) erts_alloc(h->type, bytes);
    sys_memzero(h->tab, bytes);
    h->name = name;
    h->fun = fun;
    set_size(h,size);
    erts_smp_atomic_init(&h->is_rehashing, 0);
    erts_smp_atomic_init(&h->nitems, 0);
    for (i=0; i<SAFE_HASH_LOCK_CNT; i++) {
	erts_smp_mtx_init(&h->lock_vec[i].mtx,"safe_hash");
    }
    return h;
}
Example #9
0
File: time.c Project: a5an0/otp
/* this routine links the time cells into a free list at the start
   and sets the time queue as empty */
void
erts_init_time(void)
{
    int i;

    /* system dependent init; must be done before do_time_init()
       if timer thread is enabled */
    itime = erts_init_time_sup();

    erts_smp_mtx_init(&tiw_lock, "timer_wheel");

    tiw = (ErlTimer**) erts_alloc(ERTS_ALC_T_TIMER_WHEEL,
				  TIW_SIZE * sizeof(ErlTimer*));
    for(i = 0; i < TIW_SIZE; i++)
	tiw[i] = NULL;
    do_time_init();
    tiw_pos = tiw_nto = 0;
    tiw_min_ptr = NULL;
    tiw_min = 0;
}
Example #10
0
static void
init_purge_state(void)
{
    purge_state.module = THE_NON_VALUE;

    erts_smp_mtx_init(&purge_state.mtx, "purge_state");

    purge_state.pending_purge_lambda =
	erts_export_put(am_erts_code_purger, am_pending_purge_lambda, 3);

    purge_state.sprocs = &purge_state.def_sprocs[0];
    purge_state.sp_size = sizeof(purge_state.def_sprocs);
    purge_state.sp_size /= sizeof(purge_state.def_sprocs[0]);
    purge_state.sp_ix = 0;

    purge_state.funs = &purge_state.def_funs[0];
    purge_state.fe_size = sizeof(purge_state.def_funs);
    purge_state.fe_size /= sizeof(purge_state.def_funs[0]);
    purge_state.fe_ix = 0;

    purge_state.saved_old.code_hdr = 0;
}
Example #11
0
void erts_init_node_tables(void)
{
    HashFunctions f;

    f.hash  = (H_FUN)			dist_table_hash;
    f.cmp   = (HCMP_FUN)		dist_table_cmp;
    f.alloc = (HALLOC_FUN)		dist_table_alloc;
    f.free  = (HFREE_FUN)		dist_table_free;

    erts_this_dist_entry = erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry));
    dist_entries = 1;

    hash_init(ERTS_ALC_T_DIST_TABLE, &erts_dist_table, "dist_table", 11, f);

    erts_hidden_dist_entries			= NULL;
    erts_visible_dist_entries			= NULL;
    erts_not_connected_dist_entries		= NULL;
    erts_no_of_hidden_dist_entries		= 0;
    erts_no_of_visible_dist_entries		= 0;
    erts_no_of_not_connected_dist_entries	= 0;

    erts_this_dist_entry->next			= NULL;
    erts_this_dist_entry->prev			= NULL;
    erts_refc_init(&erts_this_dist_entry->refc, 1); /* erts_this_node */
    erts_this_dist_entry->sysname		= am_Noname;
    erts_this_dist_entry->cid			= NIL;
    erts_this_dist_entry->node_links		= NULL;
    erts_this_dist_entry->nlinks		= NULL;
    erts_this_dist_entry->monitors		= NULL;
    erts_this_dist_entry->status		= 0;
    erts_this_dist_entry->flags			= 0;
    erts_this_dist_entry->cache			= NULL;
    erts_this_dist_entry->version		= 0;

    (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry);

    f.hash  = (H_FUN)      			node_table_hash;
    f.cmp   = (HCMP_FUN)   			node_table_cmp;
    f.alloc = (HALLOC_FUN) 			node_table_alloc;
    f.free  = (HFREE_FUN)  			node_table_free;

    hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f);

    erts_this_node = erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode));
    node_entries = 1;

    erts_refc_init(&erts_this_node->refc, 1); /* The system itself */
    erts_this_node->sysname			= am_Noname;
    erts_this_node->creation			= 0;
    erts_this_node->dist_entry			= erts_this_dist_entry;

    (void) hash_put(&erts_node_table, (void *) erts_this_node);

#ifdef ERTS_SMP
    {
	int i;
	for (i = 0; i < ERTS_NO_OF_DIST_ENTRY_MUTEXES; i++) {
#ifdef ERTS_ENABLE_LOCK_COUNT
	    erts_smp_mtx_init_x(&dist_entry_mutexes[i], "dist_entry", make_small(i));
#else
	    erts_smp_mtx_init(&dist_entry_mutexes[i], "dist_entry");
#endif /*ERTS_ENABLE_LOCK_COUNT*/
	}
	erts_this_dist_entry->mtxp = &dist_entry_mutexes[0];
	erts_smp_mtx_init(&erts_node_table_mtx, "node_table");
	erts_smp_mtx_init(&erts_dist_table_mtx, "dist_table");
    }
#endif

    references_atoms_need_init = 1;
}
Example #12
0
void
sys_init_time(ErtsSysInitTimeResult *init_resp)
{
#if defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT)
    int major, minor, build, vsn;
#endif
#if defined(ERTS_MACH_CLOCKS)
    mach_clocks_init();
#endif
#if !defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT)

    init_resp->have_os_monotonic_time = 0;

#else /* defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) */

#ifdef ERTS_HAVE_CORRECTED_OS_MONOTONIC_TIME
    init_resp->have_corrected_os_monotonic_time = 1;
#else
    init_resp->have_corrected_os_monotonic_time = 0;
#endif

    init_resp->os_monotonic_time_info.resolution = (Uint64) 1000*1000*1000;
#if defined(HAVE_CLOCK_GETRES) && defined(MONOTONIC_CLOCK_ID)
    {
	struct timespec ts;
	if (clock_getres(MONOTONIC_CLOCK_ID, &ts) == 0) {
	    if (ts.tv_sec == 0 && ts.tv_nsec != 0)
		init_resp->os_monotonic_time_info.resolution /= ts.tv_nsec;
	    else if (ts.tv_sec >= 1)
		init_resp->os_monotonic_time_info.resolution = 1;
	}
    }
#elif defined(ERTS_HAVE_MACH_CLOCK_GETRES) && defined(MONOTONIC_CLOCK_ID)
    init_resp->os_monotonic_time_info.resolution
	= mach_clock_getres(&internal_state.r.o.mach.clock.monotonic);
#endif

#ifdef MONOTONIC_CLOCK_ID_STR
    init_resp->os_monotonic_time_info.clock_id = MONOTONIC_CLOCK_ID_STR;
#else
    init_resp->os_monotonic_time_info.clock_id = NULL;
#endif

    init_resp->os_monotonic_time_info.locked_use = 0;

#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
    init_resp->os_monotonic_time_info.func = "clock_gettime";
#elif defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
    init_resp->os_monotonic_time_info.func = "clock_get_time";
#elif defined(OS_MONOTONIC_TIME_USING_GETHRTIME)
    init_resp->os_monotonic_time_info.func = "gethrtime";
#elif defined(OS_MONOTONIC_TIME_USING_TIMES)
    init_resp->os_monotonic_time_info.func = "times";
#else
# error Unknown erts_os_monotonic_time() implementation
#endif

    init_resp->have_os_monotonic_time = 1;

    os_version(&major, &minor, &build);

    vsn = ERTS_MK_VSN_INT(major, minor, build);


#if defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
    if (vsn >= ERTS_MK_VSN_INT(2, 6, 33)) {
	erts_sys_time_data__.r.o.os_monotonic_time =
	    clock_gettime_monotonic;
#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
	erts_sys_time_data__.r.o.os_times =
	    clock_gettime_times;
#endif
    }
    else {
	/*
	 * Linux versions prior to 2.6.33 have a
	 * known bug that sometimes cause the NTP
	 * adjusted monotonic clock to take small
	 * steps backwards. Use raw monotonic clock
	 * if it is present; otherwise, fall back
	 * on locked verification of values.
	 */
	init_resp->have_corrected_os_monotonic_time = 0;
#if defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
	/* We know that CLOCK_MONOTONIC_RAW is defined,
	   but we don't know if we got a kernel that
	   supports it. Support for CLOCK_MONOTONIC_RAW
	   appeared in kernel 2.6.28... */
	if (vsn >= ERTS_MK_VSN_INT(2, 6, 28)) {
	    erts_sys_time_data__.r.o.os_monotonic_time =
		clock_gettime_monotonic_raw;
#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
	    erts_sys_time_data__.r.o.os_times =
		clock_gettime_times_raw;
#endif
	    init_resp->os_monotonic_time_info.clock_id =
		"CLOCK_MONOTONIC_RAW";
	}
	else
#endif /* defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW) */
	{
	    erts_sys_time_data__.r.o.os_monotonic_time =
		clock_gettime_monotonic_verified;
#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
	    erts_sys_time_data__.r.o.os_times =
		clock_gettime_times_verified;
#endif
	    erts_smp_mtx_init(&internal_state.w.f.mtx,
			      "os_monotonic_time");
	    internal_state.w.f.last_delivered
		= clock_gettime_monotonic();
	    init_resp->os_monotonic_time_info.locked_use = 1;
	}
    }
#else /* !(defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)) */
    {
	char flavor[1024];

	os_flavor(flavor, sizeof(flavor));

	if (sys_strcmp(flavor, "sunos") == 0) {
	    /*
	     * Don't trust hrtime on multi processors
	     * on SunOS prior to SunOS 5.8
	     */
	    if (vsn < ERTS_MK_VSN_INT(5, 8, 0)) {
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
		if (sysconf(_SC_NPROCESSORS_CONF) > 1)
#endif
		    init_resp->have_os_monotonic_time = 0;
	    }
	}
    }
#endif /* !(defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)) */

#endif /* defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) */

#ifdef ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
    init_resp->os_monotonic_time_unit = ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT;
#endif
    init_resp->sys_clock_resolution = SYS_CLOCK_RESOLUTION;

    /* 
     * This (erts_sys_time_data__.r.o.ticks_per_sec) is only for
     * times() (CLK_TCK), the resolution is always one millisecond..
     */
    if ((erts_sys_time_data__.r.o.ticks_per_sec = TICKS_PER_SEC()) < 0)
	erl_exit(ERTS_ABORT_EXIT, "Can't get clock ticks/sec\n");
    
#if defined(OS_MONOTONIC_TIME_USING_TIMES)
#if ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
#  error Time unit is supposed to be determined at runtime...
#endif
    {
	ErtsMonotonicTime resolution = erts_sys_time_data__.r.o.ticks_per_sec;
	ErtsMonotonicTime time_unit = resolution;
	int shift = 0;

	while (time_unit < 1000*1000) {
	    time_unit <<= 1;
	    shift++;
	}

	init_resp->os_monotonic_time_info.resolution = resolution;
	init_resp->os_monotonic_time_unit = time_unit;
	init_resp->os_monotonic_time_info.extended = 1;
	internal_state.r.o.times_shift = shift;

	erts_init_os_monotonic_time_extender(&internal_state.wr.m.os_mtime_xtnd,
					     get_tick_count,
					     (1 << 29) / resolution);
    }
#endif /* defined(OS_MONOTONIC_TIME_USING_TIMES) */

#ifdef WALL_CLOCK_ID_STR
    init_resp->os_system_time_info.clock_id = WALL_CLOCK_ID_STR;
#else
    init_resp->os_system_time_info.clock_id = NULL;
#endif

    init_resp->os_system_time_info.locked_use = 0;
    init_resp->os_system_time_info.resolution = (Uint64) 1000*1000*1000;
#if defined(HAVE_CLOCK_GETRES) && defined(WALL_CLOCK_ID)
    {
	struct timespec ts;
	if (clock_getres(WALL_CLOCK_ID, &ts) == 0) {
	    if (ts.tv_sec == 0 && ts.tv_nsec != 0)
		init_resp->os_system_time_info.resolution /= ts.tv_nsec;
	    else if (ts.tv_sec >= 1)
		init_resp->os_system_time_info.resolution = 1;
	}
    }
#elif defined(ERTS_HAVE_MACH_CLOCK_GETRES) && defined(WALL_CLOCK_ID)
    init_resp->os_system_time_info.resolution
	= mach_clock_getres(&internal_state.r.o.mach.clock.wall);
#endif

#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
    init_resp->os_system_time_info.func = "clock_gettime";
#elif defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
    init_resp->os_system_time_info.func = "clock_get_time";
#elif defined(OS_SYSTEM_TIME_GETTIMEOFDAY)
    init_resp->os_system_time_info.func = "gettimeofday";    
    init_resp->os_system_time_info.resolution = 1000*1000;
    init_resp->os_system_time_info.clock_id = NULL;
#else
#  error Missing erts_os_system_time() implementation
#endif

}