⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_init.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ``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 * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ */#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include "sys.h"#include <ctype.h>#include "erl_vm.h"#include "global.h"#include "erl_process.h"#include "error.h"#include "erl_version.h"#include "erl_db.h"#include "beam_bp.h"#include "erl_bits.h"#include "erl_binary.h"#include "dist.h"#include "erl_mseg.h"#include "erl_nmgc.h"#include "erl_threads.h"#include "erl_bif_timer.h"#include "erl_instrument.h"#include "erl_printf_term.h"#include "erl_misc_utils.h"#ifdef HIPE#include "hipe_mode_switch.h"	/* for hipe_mode_switch_init() */#include "hipe_signal.h"	/* for hipe_signal_init() */#endif/* * Note about VxWorks: All variables must be initialized by executable code, * not by an initializer. Otherwise a new instance of the emulator will * inherit previous values. */extern void erl_crash_dump_v(char *, int, char *, va_list);#ifdef __WIN32__extern void ConNormalExit(void);extern void ConWaitForExit(void);#endif#define ERTS_MIN_COMPAT_REL 7#ifdef ERTS_SMPerts_smp_atomic_t erts_writing_erl_crash_dump;#elsevolatile int erts_writing_erl_crash_dump = 0;#endifint erts_initialized = 0;#if defined(USE_THREADS) && !defined(ERTS_SMP)static erts_tid_t main_thread;#endif/* * Configurable parameters. */Uint display_items;	    /* no of items to display in traces etc */Uint display_loads;		/* print info about loaded modules */int H_MIN_SIZE;			/* The minimum heap grain */Uint32 erts_debug_flags;	/* Debug flags. */#ifndef ERTS_SMP /* Not supported with smp emulator */int count_instructions;#endifint erts_backtrace_depth;	/* How many functions to show in a backtrace				 * in error codes.				 */int erts_async_max_threads;  /* number of threads for async support */int erts_async_thread_suggested_stack_size;erts_smp_atomic_t erts_max_gen_gcs;Eterm erts_error_logger_warnings; /* What to map warning logs to, am_error, 				     am_info or am_warning, am_error is 				     the default for BC */int erts_compat_rel;#ifdef DEBUGUint32 verbose;             /* See erl_debug.h for information about verbose */#endifint erts_disable_tolerant_timeofday; /* Time correction can be disabled it is				      * not and/or it is too slow.				      */#ifdef ERTS_SMPUint no_of_schedulers;#endifint erts_modified_timing_level;/* * Other global variables. */ErtsModifiedTimings erts_modified_timings[] = {    /* 0 */	{make_small(0), CONTEXT_REDS, INPUT_REDUCTIONS},    /* 1 */	{make_small(0), 2*CONTEXT_REDS, 2*INPUT_REDUCTIONS},    /* 2 */	{make_small(0), CONTEXT_REDS/2, INPUT_REDUCTIONS/2},    /* 3 */	{make_small(0), 3*CONTEXT_REDS, 3*INPUT_REDUCTIONS},    /* 4 */	{make_small(0), CONTEXT_REDS/3, 3*INPUT_REDUCTIONS},    /* 5 */	{make_small(0), 4*CONTEXT_REDS, INPUT_REDUCTIONS/2},    /* 6 */	{make_small(1), CONTEXT_REDS/4, 2*INPUT_REDUCTIONS},    /* 7 */	{make_small(1), 5*CONTEXT_REDS, INPUT_REDUCTIONS/3},    /* 8 */	{make_small(10), CONTEXT_REDS/5, 3*INPUT_REDUCTIONS},    /* 9 */	{make_small(10), 6*CONTEXT_REDS, INPUT_REDUCTIONS/4}};#define ERTS_MODIFIED_TIMING_LEVELS \  (sizeof(erts_modified_timings)/sizeof(ErtsModifiedTimings))Export *erts_delay_trap = NULL;int erts_use_r9_pids_ports;#ifdef HYBRIDEterm *global_heap;Eterm *global_hend;Eterm *global_htop;Eterm *global_saved_htop;Eterm *global_old_heap;Eterm *global_old_hend;ErlOffHeap erts_global_offheap;Uint   global_heap_sz = SH_DEFAULT_SIZE;#ifndef INCREMENTALEterm *global_high_water;Eterm *global_old_htop;#endifUint16 global_gen_gcs;Uint16 global_max_gen_gcs;Uint   global_gc_flags;Uint   global_heap_min_sz = SH_DEFAULT_SIZE;#endifint ignore_break;int replace_intr;static char*progname(char *fullname) {    int i;        i = strlen(fullname);    while (i >= 0) {	if ((fullname[i] != '/') && (fullname[i] != '\\')) 	    i--;	else 	    break;    }    return fullname+i+1;}static intthis_rel_num(void){    static int this_rel = -1;    if (this_rel < 1) {	int i;	char this_rel_str[] = ERLANG_OTP_RELEASE;	    	i = 0;	while (this_rel_str[i] && !isdigit((int) this_rel_str[i]))	    i++;	this_rel = atoi(&this_rel_str[i]); 	if (this_rel < 1)	    erl_exit(-1, "Unexpected ERLANG_OTP_RELEASE format\n");    }    return this_rel;}/* * Common error printout function, all error messages * that don't go to the error logger go through here. */void erl_error(char *fmt, va_list args){    erts_vfprintf(stderr, fmt, args);}static void early_init(int *argc, char **argv);voiderts_short_init(void){    early_init(NULL, NULL);    erl_init();    erts_initialized = 1;}voiderl_init(void){    init_benchmarking();#ifdef ERTS_SMP    erts_system_block_init();#endif    erts_init_monitors();    erts_init_gc();    erts_init_process();    H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0);    erts_init_trace();    erts_init_binary();    erts_init_bits();    erts_init_fun_table();    init_atom_table();    init_export_table();    init_module_table();    init_register_table();    init_message();    erts_bif_info_init();    erts_ddll_init();    init_emulator();    erts_bp_init();    init_db(); /* Must be after init_emulator */    init_time();    erts_bif_timer_init();    erts_init_node_tables();    init_dist();    init_io();    init_copy();    init_load();    erts_init_bif();    erts_init_obsolete();    erts_delay_trap = erts_export_put(am_erlang, am_delay_trap, 2);#if HAVE_ERTS_MSEG    erts_mseg_late_init(); /* Must be after timer (init_time()) and thread			      initializations */#endif#ifdef HIPE    hipe_mode_switch_init(); /* Must be after init_load/beam_catches/init */#endif#ifdef _OSE_    erl_sys_init_final();#endif}static voidinit_shared_memory(int argc, char **argv){#ifdef HYBRID    int arg_size = 0;    global_heap_sz = erts_next_heap_size(global_heap_sz,0);    /* Make sure arguments will fit on the heap, no one else will check! */    while (argc--)        arg_size += 2 + strlen(argv[argc]);    if (global_heap_sz < arg_size)        global_heap_sz = erts_next_heap_size(arg_size,1);#ifndef INCREMENTAL    global_heap = (Eterm *) ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP,					    sizeof(Eterm) * global_heap_sz);    global_hend = global_heap + global_heap_sz;    global_htop = global_heap;    global_high_water = global_heap;    global_old_hend = global_old_htop = global_old_heap = NULL;#endif    global_gen_gcs = 0;    global_max_gen_gcs = erts_smp_atomic_read(&erts_max_gen_gcs);    global_gc_flags = erts_default_process_flags;    erts_global_offheap.mso = NULL;#ifndef HYBRID /* FIND ME! */    erts_global_offheap.funs = NULL;#endif    erts_global_offheap.overhead = 0;#endif#ifdef INCREMENTAL    erts_init_incgc();#endif}/* * Create the very first process. */voiderts_first_process(Eterm modname, void* code, unsigned size, int argc, char** argv){    int i;    Eterm args;    Eterm pid;    Eterm* hp;    Process parent;    Process* p;    ErlSpawnOpts so;        if (erts_find_function(modname, am_start, 1) == NULL) {	char sbuf[256];	Atom* ap;	ap = atom_tab(atom_val(modname));	memcpy(sbuf, ap->name, ap->len);	sbuf[ap->len] = '\0';	erl_exit(5, "No function %s:start/1\n", sbuf);    }    /*     * We need a dummy parent process to be able to call erl_create_process().     */    erts_init_empty_process(&parent);    hp = HAlloc(&parent, argc*2 + 4);    args = NIL;    for (i = argc-1; i >= 0; i--) {	int len = sys_strlen(argv[i]);	args = CONS(hp, new_binary(&parent, (byte*)argv[i], len), args);	hp += 2;    }    args = CONS(hp, new_binary(&parent, code, size), args);    hp += 2;    args = CONS(hp, args, NIL);    so.flags = 0;    pid = erl_create_process(&parent, modname, am_start, args, &so);    p = process_tab[internal_pid_index(pid)];    p->group_leader = pid;    erts_cleanup_empty_process(&parent);}/* * XXX Old way of starting. Hopefully soon obsolete. */static voiderl_first_process_otp(char* modname, void* code, unsigned size, int argc, char** argv){    int i;    Eterm start_mod;    Eterm args;    Eterm* hp;    Process parent;    ErlSpawnOpts so;    Eterm env;        start_mod = am_atom_put(modname, sys_strlen(modname));    if (erts_find_function(start_mod, am_start, 2) == NULL) {	erl_exit(5, "No function %s:start/2\n", modname);    }    /*     * We need a dummy parent process to be able to call erl_create_process().     */    erts_init_empty_process(&parent);    hp = HAlloc(&parent, argc*2 + 4);    args = NIL;    for (i = argc-1; i >= 0; i--) {	int len = sys_strlen(argv[i]);	args = CONS(hp, new_binary(&parent, (byte*)argv[i], len), args);	hp += 2;    }    env = new_binary(&parent, code, size);    args = CONS(hp, args, NIL);    hp += 2;    args = CONS(hp, env, args);    so.flags = 0;    (void) erl_create_process(&parent, start_mod, am_start, args, &so);    erts_cleanup_empty_process(&parent);}Etermerts_preloaded(Process* p){    Eterm previous;    int j;    int need;    Eterm mod;    Eterm* hp;    char* name;    const Preload *preload = sys_preloaded();    j = 0;    while (preload[j].name != NULL) {	j++;    }    previous = NIL;    need = 2*j;    hp = HAlloc(p, need);    j = 0;    while ((name = preload[j].name) != NULL)  {	mod = am_atom_put(name, sys_strlen(name));	previous = CONS(hp, mod, previous);	hp += 2;	j++;    }    return previous;}/* static variables that must not change (use same values at restart) */static char* program;static char* init = "init";static char* boot = "boot";static int    boot_argc;static char** boot_argv;static char *get_arg(char* rest, char* next, int* ip){    if (*rest == '\0') {	if (next == NULL) {	    erts_fprintf(stderr, "too few arguments\n");	    erts_usage();	}	(*ip)++;	return next;    }    return rest;}static void load_preloaded(void){    int i;    int res;    Preload* preload_p;    Eterm module_name;    byte* code;    char* name;    int length;    if ((preload_p = sys_preloaded()) == NULL) {	return;    }    i = 0;    while ((name = preload_p[i].name) != NULL) {	length = preload_p[i].size;	module_name = am_atom_put(name, sys_strlen(name));	if ((code = sys_preload_begin(&preload_p[i])) == 0)	    erl_exit(1, "Failed to find preloaded code for module %s\n", 		     name);	res = erts_load_module(NULL, 0, NIL, &module_name, code, length);	sys_preload_end(&preload_p[i]);	if (res < 0)	    erl_exit(1,"Failed loading preloaded module %s\n", name);	i++;    }}/* be helpful (or maybe downright rude:-) */void erts_usage(void){    erts_fprintf(stderr, "Usage: %s [flags] [ -- [init_args] ]\n", progname(program));    erts_fprintf(stderr, "The flags are:\n\n");    /*    erts_fprintf(stderr, "-# number  set the number of items to be used in traces etc\n"); */    erts_fprintf(stderr, "-a size    suggested stack size in kilo words for threads\n");    erts_fprintf(stderr, "           in the async-thread pool, valid range is [%d-%d]\n",		 ERTS_ASYNC_THREAD_MIN_STACK_SIZE,		 ERTS_ASYNC_THREAD_MAX_STACK_SIZE);    erts_fprintf(stderr, "-A number  set number of threads in async thread pool,\n");    erts_fprintf(stderr, "           valid range is [0-%d]\n",		 ERTS_MAX_NO_OF_ASYNC_THREADS);    erts_fprintf(stderr, "-B[c|d|i]  c to have Ctrl-c interrupt the Erlang shell,\n");    erts_fprintf(stderr, "           d (or no extra option) to disable the break\n");    erts_fprintf(stderr, "           handler, i to ignore break signals\n");    /*    erts_fprintf(stderr, "-b func    set the boot function (default boot)\n"); */    erts_fprintf(stderr, "-c         disable continuous date/time correction with\n");    erts_fprintf(stderr, "           respect to uptime\n");    erts_fprintf(stderr, "-h number  set minimum heap size in words (default %d)\n",	       H_DEFAULT_SIZE);    /*    erts_fprintf(stderr, "-i module  set the boot module (default init)\n"); */    erts_fprintf(stderr, "-K boolean enable or disable kernel poll\n");    erts_fprintf(stderr, "-l         turn on auto load tracing\n");    erts_fprintf(stderr, "-M<X> <Y>  memory allocator switches,\n");    erts_fprintf(stderr, "           see the erts_alloc(3) man page for more info.\n");    erts_fprintf(stderr, "-P number  set maximum number of processes on this node,\n");    erts_fprintf(stderr, "           valid range is [%d-%d]\n",	       ERTS_MIN_PROCESSES, ERTS_MAX_PROCESSES);    erts_fprintf(stderr, "-R number  set compatibility release number,\n");    erts_fprintf(stderr, "           valid range [%d-%d]\n",	       ERTS_MIN_COMPAT_REL, this_rel_num());    erts_fprintf(stderr, "-r         force ets memory block to be moved on realloc\n");    erts_fprintf(stderr, "-S number  set number of schedulers on this node,\n");    erts_fprintf(stderr, "           valid range is [1-%d]\n",		 ERTS_MAX_NO_OF_SCHEDULERS);    erts_fprintf(stderr, "-T number  set modified timing level,\n");    erts_fprintf(stderr, "           valid range is [0-%d]\n",		 ERTS_MODIFIED_TIMING_LEVELS-1);    erts_fprintf(stderr, "-V         print Erlang version\n");    erts_fprintf(stderr, "-v         turn on chatty mode (GCs will be reported etc)\n");    erts_fprintf(stderr, "-W<i|w>    set error logger warnings mapping,\n");    erts_fprintf(stderr, "           see error_logger documentation for details\n");    erts_fprintf(stderr, "\n");    erts_fprintf(stderr, "Note that if the emulator is started with erlexec (typically\n");    erts_fprintf(stderr, "from the erl script), these flags should be specified with +.\n");    erts_fprintf(stderr, "\n\n");    erl_exit(-1, "");}static voidearly_init(int *argc, char **argv) /*				   * Only put things here which are				   * really important initialize				   * early!				   */{    erts_printf_eterm_func = erts_printf_term;    erts_disable_tolerant_timeofday = 0;    display_items = 200;    display_loads = 0;    erts_backtrace_depth = DEFAULT_BACKTRACE_SIZE;    erts_async_max_threads = 0;    erts_async_thread_suggested_stack_size = ERTS_ASYNC_THREAD_MIN_STACK_SIZE;    H_MIN_SIZE = H_DEFAULT_SIZE;    erts_initialized = 0;    ignore_break = 0;    replace_intr = 0;    program = argv[0];    erts_modified_timing_level = -1;    erts_compat_rel = this_rel_num();    erts_use_r9_pids_ports = 0;    erts_sys_pre_init();#ifdef ERTS_ENABLE_LOCK_CHECK    erts_lc_init();#endif#ifdef ERTS_SMP    erts_smp_atomic_init(&erts_writing_erl_crash_dump, 0L);#else    erts_writing_erl_crash_dump = 0;#endif    erts_smp_atomic_init(&erts_max_gen_gcs, (long)((Uint16) -1));    erts_pre_init_process();#if defined(USE_THREADS) && !defined(ERTS_SMP)    main_thread = erts_thr_self();#endif    erts_init_utils();    erts_alloc_init(argc, argv); /* Handles (and removes) -M flags */#ifdef ERTS_ENABLE_LOCK_CHECK    erts_lc_late_init();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -