~ubuntu-branches/ubuntu/trusty/erlang/trusty

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum
  • Date: 2011-05-05 15:48:43 UTC
  • mfrom: (3.5.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110505154843-0om6ekzg6m7ugj27
Tags: 1:14.b.2-dfsg-3ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to.
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
  - debian/patches/series: Do what I meant, and enable build-options.patch
    instead.
* Additional changes:
  - Drop erlang-wx from -et
* Dropped Changes:
  - patches/pcre-crash.patch: CVE-2008-2371: outer level option with
    alternatives caused crash. (Applied Upstream)
  - fix for ssl certificate verification in newSSL: 
    ssl_cacertfile_fix.patch (Applied Upstream)
  - debian/patches/series: Enable native.patch again, to get stripped beam
    files and reduce the package size again. (build-options is what
    actually accomplished this)
  - Remove build-options.patch on advice from upstream and because it caused
    odd build failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * %CopyrightBegin%
3
 
 * 
4
 
 * Copyright Ericsson AB 1997-2009. All Rights Reserved.
5
 
 * 
 
3
 *
 
4
 * Copyright Ericsson AB 1997-2010. All Rights Reserved.
 
5
 *
6
6
 * The contents of this file are subject to the Erlang Public License,
7
7
 * Version 1.1, (the "License"); you may not use this file except in
8
8
 * compliance with the License. You should have received a copy of the
9
9
 * Erlang Public License along with this software. If not, it can be
10
10
 * retrieved online at http://www.erlang.org/.
11
 
 * 
 
11
 *
12
12
 * Software distributed under the License is distributed on an "AS IS"
13
13
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
 * the License for the specific language governing rights and limitations
15
15
 * under the License.
16
 
 * 
 
16
 *
17
17
 * %CopyrightEnd%
18
18
 */
19
19
 
41
41
#include "erl_printf_term.h"
42
42
#include "erl_misc_utils.h"
43
43
#include "packet_parser.h"
 
44
#include "erl_cpu_topology.h"
44
45
 
45
46
#ifdef HIPE
46
47
#include "hipe_mode_switch.h"   /* for hipe_mode_switch_init() */
63
64
extern void ConWaitForExit(void);
64
65
#endif
65
66
 
 
67
static void erl_init(int ncpu);
 
68
 
66
69
#define ERTS_MIN_COMPAT_REL 7
67
70
 
68
71
#ifdef ERTS_SMP
76
79
static erts_tid_t main_thread;
77
80
#endif
78
81
 
79
 
erts_cpu_info_t *erts_cpuinfo;
80
 
 
81
82
int erts_use_sender_punish;
82
83
 
83
84
/*
84
85
 * Configurable parameters.
85
86
 */
86
87
 
87
 
Uint display_items;         /* no of items to display in traces etc */
 
88
Uint display_items;             /* no of items to display in traces etc */
88
89
Uint display_loads;             /* print info about loaded modules */
89
90
int H_MIN_SIZE;                 /* The minimum heap grain */
 
91
int BIN_VH_MIN_SIZE;            /* The minimum binary virtual*/
90
92
 
91
93
Uint32 erts_debug_flags;        /* Debug flags. */
92
94
#ifdef ERTS_OPCODE_COUNTER_SUPPORT
98
100
 
99
101
int erts_async_max_threads;  /* number of threads for async support */
100
102
int erts_async_thread_suggested_stack_size;
101
 
erts_smp_atomic_t erts_max_gen_gcs;
 
103
erts_smp_atomic32_t erts_max_gen_gcs;
102
104
 
103
105
Eterm erts_error_logger_warnings; /* What to map warning logs to, am_error, 
104
106
                                     am_info or am_warning, am_error is 
118
120
                                      * not and/or it is too slow.
119
121
                                      */
120
122
 
 
123
int erts_atom_table_size = ATOM_LIMIT;  /* Maximum number of atoms */
 
124
 
121
125
int erts_modified_timing_level;
122
126
 
123
127
int erts_no_crash_dump = 0;     /* Use -d to suppress crash dump. */
225
229
    erts_vfprintf(stderr, fmt, args);
226
230
}
227
231
 
228
 
static void early_init(int *argc, char **argv);
 
232
static int early_init(int *argc, char **argv);
229
233
 
230
234
void
231
235
erts_short_init(void)
232
236
{
233
 
    early_init(NULL, NULL);
234
 
    erl_init();
 
237
    int ncpu = early_init(NULL, NULL);
 
238
    erl_init(ncpu);
235
239
    erts_initialized = 1;
236
240
}
237
241
 
238
 
void
239
 
erl_init(void)
 
242
static void
 
243
erl_init(int ncpu)
240
244
{
241
245
    init_benchmarking();
242
246
 
246
250
 
247
251
    erts_init_monitors();
248
252
    erts_init_gc();
249
 
    init_time();
250
 
    erts_init_process();
 
253
    erts_init_time();
 
254
    erts_init_sys_common_misc();
 
255
    erts_init_process(ncpu);
251
256
    erts_init_scheduling(use_multi_run_queue,
252
257
                         no_schedulers,
253
258
                         no_schedulers_online);
254
 
 
255
 
    H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0);
 
259
    erts_init_cpu_topology(); /* Must be after init_scheduling */
 
260
    H_MIN_SIZE      = erts_next_heap_size(H_MIN_SIZE, 0);
 
261
    BIN_VH_MIN_SIZE = erts_next_heap_size(BIN_VH_MIN_SIZE, 0);
256
262
 
257
263
    erts_init_trace();
258
264
    erts_init_binary();
277
283
    init_load();
278
284
    erts_init_bif();
279
285
    erts_init_bif_chksum();
 
286
    erts_init_bif_binary();
280
287
    erts_init_bif_re();
281
288
    erts_init_unicode(); /* after RE to get access to PCRE unicode */
282
289
    erts_delay_trap = erts_export_put(am_erlang, am_delay_trap, 2);
283
290
    erts_late_init_process();
284
291
#if HAVE_ERTS_MSEG
285
 
    erts_mseg_late_init(); /* Must be after timer (init_time()) and thread
 
292
    erts_mseg_late_init(); /* Must be after timer (erts_init_time()) and thread
286
293
                              initializations */
287
294
#endif
288
295
#ifdef HIPE
289
296
    hipe_mode_switch_init(); /* Must be after init_load/beam_catches/init */
290
297
#endif
291
 
#ifdef _OSE_
292
 
    erl_sys_init_final();
293
 
#endif
294
298
    packet_parser_init();
 
299
    erl_nif_init();
295
300
}
296
301
 
297
302
static void
318
323
#endif
319
324
 
320
325
    global_gen_gcs = 0;
321
 
    global_max_gen_gcs = erts_smp_atomic_read(&erts_max_gen_gcs);
 
326
    global_max_gen_gcs = (Uint16) erts_smp_atomic32_read(&erts_max_gen_gcs);
322
327
    global_gc_flags = erts_default_process_flags;
323
328
 
324
329
    erts_global_offheap.mso = NULL;
333
338
#endif
334
339
}
335
340
 
336
 
 
337
 
/*
338
 
 * Create the very first process.
339
 
 */
340
 
 
341
 
void
342
 
erts_first_process(Eterm modname, void* code, unsigned size, int argc, char** argv)
343
 
{
344
 
    int i;
345
 
    Eterm args;
346
 
    Eterm pid;
347
 
    Eterm* hp;
348
 
    Process parent;
349
 
    Process* p;
350
 
    ErlSpawnOpts so;
351
 
    
352
 
    if (erts_find_function(modname, am_start, 1) == NULL) {
353
 
        char sbuf[256];
354
 
        Atom* ap;
355
 
 
356
 
        ap = atom_tab(atom_val(modname));
357
 
        memcpy(sbuf, ap->name, ap->len);
358
 
        sbuf[ap->len] = '\0';
359
 
        erl_exit(5, "No function %s:start/1\n", sbuf);
360
 
    }
361
 
 
362
 
    /*
363
 
     * We need a dummy parent process to be able to call erl_create_process().
364
 
     */
365
 
    erts_init_empty_process(&parent);
366
 
    hp = HAlloc(&parent, argc*2 + 4);
367
 
    args = NIL;
368
 
    for (i = argc-1; i >= 0; i--) {
369
 
        int len = sys_strlen(argv[i]);
370
 
        args = CONS(hp, new_binary(&parent, (byte*)argv[i], len), args);
371
 
        hp += 2;
372
 
    }
373
 
    args = CONS(hp, new_binary(&parent, code, size), args);
374
 
    hp += 2;
375
 
    args = CONS(hp, args, NIL);
376
 
 
377
 
    so.flags = 0;
378
 
    pid = erl_create_process(&parent, modname, am_start, args, &so);
379
 
    p = process_tab[internal_pid_index(pid)];
380
 
    p->group_leader = pid;
381
 
 
382
 
    erts_cleanup_empty_process(&parent);
383
 
}
384
 
 
385
 
/*
386
 
 * XXX Old way of starting. Hopefully soon obsolete.
387
 
 */
388
 
 
389
341
static void
390
342
erl_first_process_otp(char* modname, void* code, unsigned size, int argc, char** argv)
391
343
{
513
465
 
514
466
    /*    erts_fprintf(stderr, "-# number  set the number of items to be used in traces etc\n"); */
515
467
 
516
 
    erts_fprintf(stderr, "-a size    suggested stack size in kilo words for threads\n");
517
 
    erts_fprintf(stderr, "           in the async-thread pool, valid range is [%d-%d]\n",
 
468
    erts_fprintf(stderr, "-a size     suggested stack size in kilo words for threads\n");
 
469
    erts_fprintf(stderr, "            in the async-thread pool, valid range is [%d-%d]\n",
518
470
                 ERTS_ASYNC_THREAD_MIN_STACK_SIZE,
519
471
                 ERTS_ASYNC_THREAD_MAX_STACK_SIZE);
520
 
    erts_fprintf(stderr, "-A number  set number of threads in async thread pool,\n");
521
 
    erts_fprintf(stderr, "           valid range is [0-%d]\n",
 
472
    erts_fprintf(stderr, "-A number   set number of threads in async thread pool,\n");
 
473
    erts_fprintf(stderr, "            valid range is [0-%d]\n",
522
474
                 ERTS_MAX_NO_OF_ASYNC_THREADS);
523
475
 
524
 
    erts_fprintf(stderr, "-B[c|d|i]  c to have Ctrl-c interrupt the Erlang shell,\n");
525
 
    erts_fprintf(stderr, "           d (or no extra option) to disable the break\n");
526
 
    erts_fprintf(stderr, "           handler, i to ignore break signals\n");
 
476
    erts_fprintf(stderr, "-B[c|d|i]   c to have Ctrl-c interrupt the Erlang shell,\n");
 
477
    erts_fprintf(stderr, "            d (or no extra option) to disable the break\n");
 
478
    erts_fprintf(stderr, "            handler, i to ignore break signals\n");
527
479
 
528
480
    /*    erts_fprintf(stderr, "-b func    set the boot function (default boot)\n"); */
529
481
 
530
 
    erts_fprintf(stderr, "-c         disable continuous date/time correction with\n");
531
 
    erts_fprintf(stderr, "           respect to uptime\n");
532
 
 
533
 
    erts_fprintf(stderr, "-d         don't write a crash dump for internally detected errors\n");
534
 
    erts_fprintf(stderr, "           (halt(String) will still produce a crash dump)\n");
535
 
 
536
 
    erts_fprintf(stderr, "-h number  set minimum heap size in words (default %d)\n",
 
482
    erts_fprintf(stderr, "-c          disable continuous date/time correction with\n");
 
483
    erts_fprintf(stderr, "            respect to uptime\n");
 
484
 
 
485
    erts_fprintf(stderr, "-d          don't write a crash dump for internally detected errors\n");
 
486
    erts_fprintf(stderr, "            (halt(String) will still produce a crash dump)\n");
 
487
 
 
488
    erts_fprintf(stderr, "-hms size   set minimum heap size in words (default %d)\n",
537
489
               H_DEFAULT_SIZE);
 
490
    erts_fprintf(stderr, "-hmbs size  set minimum binary virtual heap size in words (default %d)\n",
 
491
               VH_DEFAULT_SIZE);
538
492
 
539
493
    /*    erts_fprintf(stderr, "-i module  set the boot module (default init)\n"); */
540
494
 
541
 
    erts_fprintf(stderr, "-K boolean enable or disable kernel poll\n");
542
 
 
543
 
    erts_fprintf(stderr, "-l         turn on auto load tracing\n");
544
 
 
545
 
    erts_fprintf(stderr, "-M<X> <Y>  memory allocator switches,\n");
546
 
    erts_fprintf(stderr, "           see the erts_alloc(3) documentation for more info.\n");
547
 
 
548
 
    erts_fprintf(stderr, "-P number  set maximum number of processes on this node,\n");
549
 
    erts_fprintf(stderr, "           valid range is [%d-%d]\n",
 
495
    erts_fprintf(stderr, "-K boolean  enable or disable kernel poll\n");
 
496
 
 
497
    erts_fprintf(stderr, "-l          turn on auto load tracing\n");
 
498
 
 
499
    erts_fprintf(stderr, "-M<X> <Y>   memory allocator switches,\n");
 
500
    erts_fprintf(stderr, "            see the erts_alloc(3) documentation for more info.\n");
 
501
 
 
502
    erts_fprintf(stderr, "-P number   set maximum number of processes on this node,\n");
 
503
    erts_fprintf(stderr, "            valid range is [%d-%d]\n",
550
504
               ERTS_MIN_PROCESSES, ERTS_MAX_PROCESSES);
551
 
    erts_fprintf(stderr, "-R number  set compatibility release number,\n");
552
 
    erts_fprintf(stderr, "           valid range [%d-%d]\n",
 
505
    erts_fprintf(stderr, "-R number   set compatibility release number,\n");
 
506
    erts_fprintf(stderr, "            valid range [%d-%d]\n",
553
507
               ERTS_MIN_COMPAT_REL, this_rel_num());
554
508
 
555
 
    erts_fprintf(stderr, "-r         force ets memory block to be moved on realloc\n");
556
 
    erts_fprintf(stderr, "-sbt type  set scheduler bind type, valid types are:\n");
557
 
    erts_fprintf(stderr, "           u|ns|ts|ps|s|nnts|nnps|tnnps|db\n");
558
 
    erts_fprintf(stderr, "-sct cput  set cpu topology,\n");
559
 
    erts_fprintf(stderr, "           see the erl(1) documentation for more info.\n");
560
 
    erts_fprintf(stderr, "-sss size  suggested stack size in kilo words for scheduler threads,\n");
561
 
    erts_fprintf(stderr, "           valid range is [%d-%d]\n",
 
509
    erts_fprintf(stderr, "-r          force ets memory block to be moved on realloc\n");
 
510
    erts_fprintf(stderr, "-rg amount  set reader groups limit\n");
 
511
    erts_fprintf(stderr, "-sbt type   set scheduler bind type, valid types are:\n");
 
512
    erts_fprintf(stderr, "            u|ns|ts|ps|s|nnts|nnps|tnnps|db\n");
 
513
    erts_fprintf(stderr, "-sct cput   set cpu topology,\n");
 
514
    erts_fprintf(stderr, "            see the erl(1) documentation for more info.\n");
 
515
    erts_fprintf(stderr, "-swt val    set scheduler wakeup threshold, valid values are:\n");
 
516
    erts_fprintf(stderr, "            very_low|low|medium|high|very_high.\n");
 
517
    erts_fprintf(stderr, "-sss size   suggested stack size in kilo words for scheduler threads,\n");
 
518
    erts_fprintf(stderr, "            valid range is [%d-%d]\n",
562
519
                 ERTS_SCHED_THREAD_MIN_STACK_SIZE,
563
520
                 ERTS_SCHED_THREAD_MAX_STACK_SIZE);
564
 
    erts_fprintf(stderr, "-S n1:n2   set number of schedulers (n1), and number of\n");
565
 
    erts_fprintf(stderr, "           schedulers online (n2), valid range for both\n");
566
 
    erts_fprintf(stderr, "           numbers are [1-%d]\n",
 
521
    erts_fprintf(stderr, "-S n1:n2    set number of schedulers (n1), and number of\n");
 
522
    erts_fprintf(stderr, "            schedulers online (n2), valid range for both\n");
 
523
    erts_fprintf(stderr, "            numbers are [1-%d]\n",
567
524
                 ERTS_MAX_NO_OF_SCHEDULERS);
568
 
    erts_fprintf(stderr, "-T number  set modified timing level,\n");
569
 
    erts_fprintf(stderr, "           valid range is [0-%d]\n",
 
525
    erts_fprintf(stderr, "-t size     set the maximum number of atoms the "
 
526
                         "emulator can handle\n");
 
527
    erts_fprintf(stderr, "            valid range is [%d-%d]\n",
 
528
                 MIN_ATOM_TABLE_SIZE, MAX_ATOM_TABLE_SIZE);
 
529
    erts_fprintf(stderr, "-T number   set modified timing level,\n");
 
530
    erts_fprintf(stderr, "            valid range is [0-%d]\n",
570
531
                 ERTS_MODIFIED_TIMING_LEVELS-1);
571
 
    erts_fprintf(stderr, "-V         print Erlang version\n");
572
 
 
573
 
    erts_fprintf(stderr, "-v         turn on chatty mode (GCs will be reported etc)\n");
574
 
 
575
 
    erts_fprintf(stderr, "-W<i|w>    set error logger warnings mapping,\n");
576
 
    erts_fprintf(stderr, "           see error_logger documentation for details\n");
577
 
 
 
532
    erts_fprintf(stderr, "-V          print Erlang version\n");
 
533
 
 
534
    erts_fprintf(stderr, "-v          turn on chatty mode (GCs will be reported etc)\n");
 
535
 
 
536
    erts_fprintf(stderr, "-W<i|w>     set error logger warnings mapping,\n");
 
537
    erts_fprintf(stderr, "            see error_logger documentation for details\n");
 
538
    erts_fprintf(stderr, "-zdbbl size set the distribution buffer busy limit in kilobytes\n");
 
539
    erts_fprintf(stderr, "            valid range is [1-%d]\n", INT_MAX/1024);
578
540
    erts_fprintf(stderr, "\n");
579
541
    erts_fprintf(stderr, "Note that if the emulator is started with erlexec (typically\n");
580
542
    erts_fprintf(stderr, "from the erl script), these flags should be specified with +.\n");
582
544
    erl_exit(-1, "");
583
545
}
584
546
 
585
 
static void
 
547
#ifdef USE_THREADS
 
548
/*
 
549
 * allocators for thread lib
 
550
 */
 
551
 
 
552
static void *ethr_std_alloc(size_t size)
 
553
{
 
554
    return erts_alloc_fnf(ERTS_ALC_T_ETHR_STD, (Uint) size);
 
555
}
 
556
static void *ethr_std_realloc(void *ptr, size_t size)
 
557
{
 
558
    return erts_realloc_fnf(ERTS_ALC_T_ETHR_STD, ptr, (Uint) size);
 
559
}
 
560
static void ethr_std_free(void *ptr)
 
561
{
 
562
    erts_free(ERTS_ALC_T_ETHR_STD, ptr);
 
563
}
 
564
static void *ethr_sl_alloc(size_t size)
 
565
{
 
566
    return erts_alloc_fnf(ERTS_ALC_T_ETHR_SL, (Uint) size);
 
567
}
 
568
static void *ethr_sl_realloc(void *ptr, size_t size)
 
569
{
 
570
    return erts_realloc_fnf(ERTS_ALC_T_ETHR_SL, ptr, (Uint) size);
 
571
}
 
572
static void ethr_sl_free(void *ptr)
 
573
{
 
574
    erts_free(ERTS_ALC_T_ETHR_SL, ptr);
 
575
}
 
576
static void *ethr_ll_alloc(size_t size)
 
577
{
 
578
    return erts_alloc_fnf(ERTS_ALC_T_ETHR_LL, (Uint) size);
 
579
}
 
580
static void *ethr_ll_realloc(void *ptr, size_t size)
 
581
{
 
582
    return erts_realloc_fnf(ERTS_ALC_T_ETHR_LL, ptr, (Uint) size);
 
583
}
 
584
static void ethr_ll_free(void *ptr)
 
585
{
 
586
    erts_free(ERTS_ALC_T_ETHR_LL, ptr);
 
587
}
 
588
 
 
589
#endif
 
590
 
 
591
static int
586
592
early_init(int *argc, char **argv) /*
587
593
                                   * Only put things here which are
588
594
                                   * really important initialize
595
601
    int ncpuavail;
596
602
    int schdlrs;
597
603
    int schdlrs_onln;
 
604
    int max_main_threads;
 
605
    int max_reader_groups;
 
606
    int reader_groups;
 
607
 
598
608
    use_multi_run_queue = 1;
599
609
    erts_printf_eterm_func = erts_printf_term;
600
610
    erts_disable_tolerant_timeofday = 0;
604
614
    erts_async_max_threads = 0;
605
615
    erts_async_thread_suggested_stack_size = ERTS_ASYNC_THREAD_MIN_STACK_SIZE;
606
616
    H_MIN_SIZE = H_DEFAULT_SIZE;
 
617
    BIN_VH_MIN_SIZE = VH_DEFAULT_SIZE;
607
618
 
608
619
    erts_initialized = 0;
609
620
 
610
621
    erts_use_sender_punish = 1;
611
622
 
612
 
    erts_cpuinfo = erts_cpu_info_create();
613
 
 
614
 
#ifdef ERTS_SMP
615
 
    ncpu = erts_get_cpu_configured(erts_cpuinfo);
616
 
    ncpuonln = erts_get_cpu_online(erts_cpuinfo);
617
 
    ncpuavail = erts_get_cpu_available(erts_cpuinfo);
618
 
#else
 
623
    erts_pre_early_init_cpu_topology(&max_reader_groups,
 
624
                                     &ncpu,
 
625
                                     &ncpuonln,
 
626
                                     &ncpuavail);
 
627
#ifndef ERTS_SMP
619
628
    ncpu = 1;
620
629
    ncpuonln = 1;
621
630
    ncpuavail = 1;
642
651
    erts_writing_erl_crash_dump = 0;
643
652
#endif
644
653
 
645
 
    erts_smp_atomic_init(&erts_max_gen_gcs, (long)((Uint16) -1));
 
654
    erts_smp_atomic32_init(&erts_max_gen_gcs, (erts_aint32_t) ((Uint16) -1));
646
655
 
647
656
    erts_pre_init_process();
648
657
#if defined(USE_THREADS) && !defined(ERTS_SMP)
670
679
            }
671
680
            if (argv[i][0] == '-') {
672
681
                switch (argv[i][1]) {
 
682
                case 'r': {
 
683
                    char *sub_param = argv[i]+2;
 
684
                    if (has_prefix("g", sub_param)) {
 
685
                        char *arg = get_arg(sub_param+1, argv[i+1], &i);
 
686
                        if (sscanf(arg, "%d", &max_reader_groups) != 1) {
 
687
                            erts_fprintf(stderr,
 
688
                                         "bad reader groups limit: %s\n", arg);
 
689
                            erts_usage();
 
690
                        }
 
691
                        if (max_reader_groups < 0) {
 
692
                            erts_fprintf(stderr,
 
693
                                         "bad reader groups limit: %d\n",
 
694
                                         max_reader_groups);
 
695
                            erts_usage();
 
696
                        }
 
697
                    }
 
698
                    break;
 
699
                }
673
700
                case 'S' : {
674
701
                    int tot, onln;
675
702
                    char *arg = get_arg(argv[i]+2, argv[i+1], &i);
738
765
 
739
766
    erts_alloc_init(argc, argv, &alloc_opts); /* Handles (and removes)
740
767
                                                 -M flags. */
741
 
 
742
 
    erts_early_init_scheduling(); /* Require allocators */
743
 
    erts_init_utils(); /* Require allocators */
 
768
    /* Require allocators */
 
769
    erts_early_init_scheduling();
 
770
    erts_init_utils();
 
771
    erts_early_init_cpu_topology(no_schedulers,
 
772
                                 &max_main_threads,
 
773
                                 max_reader_groups,
 
774
                                 &reader_groups);
 
775
 
 
776
#ifdef USE_THREADS
 
777
    {
 
778
        erts_thr_late_init_data_t elid = ERTS_THR_LATE_INIT_DATA_DEF_INITER;
 
779
        elid.mem.std.alloc = ethr_std_alloc;
 
780
        elid.mem.std.realloc = ethr_std_realloc;
 
781
        elid.mem.std.free = ethr_std_free;
 
782
        elid.mem.sl.alloc = ethr_sl_alloc;
 
783
        elid.mem.sl.realloc = ethr_sl_realloc;
 
784
        elid.mem.sl.free = ethr_sl_free;
 
785
        elid.mem.ll.alloc = ethr_ll_alloc;
 
786
        elid.mem.ll.realloc = ethr_ll_realloc;
 
787
        elid.mem.ll.free = ethr_ll_free;
 
788
        elid.main_threads = max_main_threads;
 
789
        elid.reader_groups = reader_groups;
 
790
 
 
791
        erts_thr_late_init(&elid);
 
792
    }
 
793
#endif
744
794
 
745
795
#ifdef ERTS_ENABLE_LOCK_CHECK
746
796
    erts_lc_late_init();
747
797
#endif
 
798
    
 
799
#ifdef ERTS_ENABLE_LOCK_COUNT
 
800
    erts_lcnt_late_init();
 
801
#endif
748
802
 
749
803
#if defined(HIPE)
750
804
    hipe_signal_init(); /* must be done very early */
754
808
    erl_sys_args(argc, argv);
755
809
 
756
810
    erts_ets_realloc_always_moves = 0;
 
811
    erts_ets_always_compress = 0;
 
812
    erts_dist_buf_busy_limit = ERTS_DE_BUSY_LIMIT;
757
813
 
 
814
    return ncpu;
758
815
}
759
816
 
760
817
#ifndef ERTS_SMP
788
845
    char envbuf[21]; /* enough for any 64-bit integer */
789
846
    size_t envbufsz;
790
847
    int async_max_threads = erts_async_max_threads;
791
 
 
792
 
    early_init(&argc, argv);
 
848
    int ncpu = early_init(&argc, argv);
793
849
 
794
850
    envbufsz = sizeof(envbuf);
795
851
    if (erts_sys_getenv(ERL_MAX_ETS_TABLES_ENV, envbuf, &envbufsz) == 0)
800
856
    envbufsz = sizeof(envbuf);
801
857
    if (erts_sys_getenv("ERL_FULLSWEEP_AFTER", envbuf, &envbufsz) == 0) {
802
858
        Uint16 max_gen_gcs = atoi(envbuf);
803
 
        erts_smp_atomic_set(&erts_max_gen_gcs, (long) max_gen_gcs);
 
859
        erts_smp_atomic32_set(&erts_max_gen_gcs, (erts_aint32_t) max_gen_gcs);
804
860
    }
805
861
 
806
862
    envbufsz = sizeof(envbuf);
807
863
    if (erts_sys_getenv("ERL_THREAD_POOL_SIZE", envbuf, &envbufsz) == 0) {
808
864
        async_max_threads = atoi(envbuf);
809
865
    }
810
 
    
 
866
 
 
867
#if (defined(__APPLE__) && defined(__MACH__)) || defined(__DARWIN__)
 
868
    /*
 
869
     * The default stack size on MacOS X is too small for pcre.
 
870
     */
 
871
    erts_sched_thread_suggested_stack_size = 256;
 
872
#endif
811
873
 
812
874
#ifdef DEBUG
813
875
    verbose = DEBUG_DEFAULT;
846
908
            VERBOSE(DEBUG_SYSTEM,
847
909
                    ("using display items %d\n",display_items));
848
910
            break;
849
 
 
 
911
        case 'f':
 
912
            if (!strncmp(argv[i],"-fn",3)) {
 
913
                arg = get_arg(argv[i]+3, argv[i+1], &i);
 
914
                switch (*arg) {
 
915
                case 'u':
 
916
                    erts_set_user_requested_filename_encoding(ERL_FILENAME_UTF8);
 
917
                    break;
 
918
                case 'l':
 
919
                    erts_set_user_requested_filename_encoding(ERL_FILENAME_LATIN1);
 
920
                    break;
 
921
                case 'a':
 
922
                    erts_set_user_requested_filename_encoding(ERL_FILENAME_UNKNOWN);
 
923
                default:
 
924
                    erts_fprintf(stderr, "bad filename encoding %s, can be (l,u or a)\n", arg);
 
925
                    erts_usage();
 
926
                }
 
927
                break;
 
928
            } else {
 
929
                erts_fprintf(stderr, "%s unknown flag %s\n", argv[0], argv[i]);
 
930
                erts_usage();
 
931
            }
850
932
        case 'l':
851
933
            display_loads++;
852
934
            break;
922
1004
            fprintf(stderr, "The undocumented +H option has been removed (R10B-6).\n\n");
923
1005
            break;
924
1006
 
925
 
        case 'h':
926
 
            /* set default heap size */
927
 
            arg = get_arg(argv[i]+2, argv[i+1], &i);
928
 
            if ((H_MIN_SIZE = atoi(arg)) <= 0) {
929
 
                erts_fprintf(stderr, "bad heap size %s\n", arg);
930
 
                erts_usage();
 
1007
        case 'h': {
 
1008
            char *sub_param = argv[i]+2;
 
1009
            /* set default heap size
 
1010
             *
 
1011
             * h|ms  - min_heap_size
 
1012
             * h|mbs - min_bin_vheap_size
 
1013
             *
 
1014
             */
 
1015
            if (has_prefix("mbs", sub_param)) {
 
1016
                arg = get_arg(sub_param+3, argv[i+1], &i);
 
1017
                if ((BIN_VH_MIN_SIZE = atoi(arg)) <= 0) {
 
1018
                    erts_fprintf(stderr, "bad heap size %s\n", arg);
 
1019
                    erts_usage();
 
1020
                }
 
1021
                VERBOSE(DEBUG_SYSTEM, ("using minimum binary virtual heap size %d\n", BIN_VH_MIN_SIZE));
 
1022
 
 
1023
            } else if (has_prefix("ms", sub_param)) {
 
1024
                arg = get_arg(sub_param+2, argv[i+1], &i);
 
1025
                if ((H_MIN_SIZE = atoi(arg)) <= 0) {
 
1026
                    erts_fprintf(stderr, "bad heap size %s\n", arg);
 
1027
                    erts_usage();
 
1028
                }
 
1029
                VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n", H_MIN_SIZE));
 
1030
            } else {
 
1031
                /* backward compatibility */
 
1032
                arg = get_arg(argv[i]+2, argv[i+1], &i);
 
1033
                if ((H_MIN_SIZE = atoi(arg)) <= 0) {
 
1034
                    erts_fprintf(stderr, "bad heap size %s\n", arg);
 
1035
                    erts_usage();
 
1036
                }
 
1037
                VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n", H_MIN_SIZE));
931
1038
            }
932
 
            VERBOSE(DEBUG_SYSTEM,
933
 
                    ("using minimum heap size %d\n",H_MIN_SIZE));
934
1039
            break;
935
 
 
 
1040
        }
936
1041
        case 'd':
937
1042
            /*
938
1043
             * Never produce crash dumps for internally detected
945
1050
            break;
946
1051
 
947
1052
        case 'e':
948
 
            /* set maximum number of ets tables */
949
 
            arg = get_arg(argv[i]+2, argv[i+1], &i);
950
 
            if (( user_requested_db_max_tabs = atoi(arg) ) < 0) {
951
 
                erts_fprintf(stderr, "bad maximum number of ets tables %s\n", arg);
952
 
                erts_usage();
953
 
            }
954
 
            VERBOSE(DEBUG_SYSTEM,
955
 
                    ("using maximum number of ets tables %d\n",
956
 
                     user_requested_db_max_tabs));
 
1053
            if (sys_strcmp("c", argv[i]+2) == 0) {
 
1054
                erts_ets_always_compress = 1;
 
1055
            }
 
1056
            else {
 
1057
                /* set maximum number of ets tables */
 
1058
                arg = get_arg(argv[i]+2, argv[i+1], &i);
 
1059
                if (( user_requested_db_max_tabs = atoi(arg) ) < 0) {
 
1060
                    erts_fprintf(stderr, "bad maximum number of ets tables %s\n", arg);
 
1061
                    erts_usage();
 
1062
                }
 
1063
                VERBOSE(DEBUG_SYSTEM,
 
1064
                        ("using maximum number of ets tables %d\n",
 
1065
                         user_requested_db_max_tabs));
 
1066
            }
957
1067
            break;
958
1068
 
959
1069
        case 'i':
1017
1127
            char *sub_param = argv[i]+2;
1018
1128
            if (has_prefix("bt", sub_param)) {
1019
1129
                arg = get_arg(sub_param+2, argv[i+1], &i);
1020
 
                res = erts_init_scheduler_bind_type(arg);
 
1130
                res = erts_init_scheduler_bind_type_string(arg);
1021
1131
                if (res != ERTS_INIT_SCHED_BIND_TYPE_SUCCESS) {
1022
1132
                    switch (res) {
1023
1133
                    case ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED:
1042
1152
            }
1043
1153
            else if (has_prefix("ct", sub_param)) {
1044
1154
                arg = get_arg(sub_param+2, argv[i+1], &i);
1045
 
                res = erts_init_cpu_topology(arg);
 
1155
                res = erts_init_cpu_topology_string(arg);
1046
1156
                if (res != ERTS_INIT_CPU_TOPOLOGY_OK) {
1047
1157
                    switch (res) {
1048
1158
                    case ERTS_INIT_CPU_TOPOLOGY_INVALID_ID:
1085
1195
            }
1086
1196
            else if (sys_strcmp("mrq", sub_param) == 0)
1087
1197
                use_multi_run_queue = 1;
 
1198
            else if (sys_strcmp("nsp", sub_param) == 0)
 
1199
                erts_use_sender_punish = 0;
1088
1200
            else if (sys_strcmp("srq", sub_param) == 0)
1089
1201
                use_multi_run_queue = 0;
1090
 
            else if (sys_strcmp("nsp", sub_param) == 0)
1091
 
                erts_use_sender_punish = 0;
 
1202
            else if (sys_strcmp("wt", sub_param) == 0) {
 
1203
                arg = get_arg(sub_param+2, argv[i+1], &i);
 
1204
                if (erts_sched_set_wakeup_limit(arg) != 0) {
 
1205
                    erts_fprintf(stderr, "scheduler wakeup threshold: %s\n",
 
1206
                                 arg);
 
1207
                    erts_usage();
 
1208
                }
 
1209
                VERBOSE(DEBUG_SYSTEM,
 
1210
                        ("scheduler wakup threshold: %s\n", arg));
 
1211
            }
1092
1212
            else if (has_prefix("ss", sub_param)) {
1093
1213
                /* suggested stack size (Kilo Words) for scheduler threads */
1094
1214
                arg = get_arg(sub_param+2, argv[i+1], &i);
1112
1232
            }
1113
1233
            break;
1114
1234
        }
 
1235
        case 't':
 
1236
            /* set atom table size */
 
1237
            arg = get_arg(argv[i]+2, argv[i+1], &i);
 
1238
            errno = 0;
 
1239
            erts_atom_table_size = strtol(arg, NULL, 10);
 
1240
            if (errno != 0 ||
 
1241
                erts_atom_table_size < MIN_ATOM_TABLE_SIZE ||
 
1242
                erts_atom_table_size > MAX_ATOM_TABLE_SIZE) {
 
1243
                erts_fprintf(stderr, "bad atom table size %s\n", arg);
 
1244
                erts_usage();
 
1245
            }
 
1246
            VERBOSE(DEBUG_SYSTEM,
 
1247
                    ("setting maximum number of atoms to %d\n",
 
1248
                     erts_atom_table_size));
 
1249
            break;
 
1250
 
1115
1251
        case 'T' :
1116
1252
            arg = get_arg(argv[i]+2, argv[i+1], &i);
1117
1253
            errno = 0;
1187
1323
                     erts_async_thread_suggested_stack_size));
1188
1324
            break;
1189
1325
 
1190
 
        case 'r':
1191
 
            erts_ets_realloc_always_moves = 1;
 
1326
        case 'r': {
 
1327
            char *sub_param = argv[i]+2;
 
1328
            if (has_prefix("g", sub_param)) {
 
1329
                get_arg(sub_param+1, argv[i+1], &i);
 
1330
                /* already handled */
 
1331
            }
 
1332
            else {
 
1333
                erts_ets_realloc_always_moves = 1;
 
1334
            }
1192
1335
            break;
 
1336
        }
1193
1337
        case 'n':   /* XXX obsolete */
1194
1338
            break;
1195
1339
        case 'c':
1219
1363
            }
1220
1364
            break;
1221
1365
 
 
1366
        case 'z': {
 
1367
            char *sub_param = argv[i]+2;
 
1368
            int new_limit;
 
1369
 
 
1370
            if (has_prefix("dbbl", sub_param)) {
 
1371
                arg = get_arg(sub_param+4, argv[i+1], &i);
 
1372
                new_limit = atoi(arg);
 
1373
                if (new_limit < 1 || INT_MAX/1024 < new_limit) {
 
1374
                    erts_fprintf(stderr, "Invalid dbbl limit: %d\n", new_limit);
 
1375
                    erts_usage();
 
1376
                } else {
 
1377
                    erts_dist_buf_busy_limit = new_limit*1024;
 
1378
                }
 
1379
            } else {
 
1380
                erts_fprintf(stderr, "bad -z option %s\n", argv[i]);
 
1381
                erts_usage();
 
1382
            }
 
1383
            break;
 
1384
        }
 
1385
 
1222
1386
        default:
1223
1387
            erts_fprintf(stderr, "%s unknown flag %s\n", argv[0], argv[i]);
1224
1388
            erts_usage();
1259
1423
    boot_argc = argc - i;  /* Number of arguments to init */
1260
1424
    boot_argv = &argv[i];
1261
1425
 
1262
 
    erl_init();
 
1426
    erl_init(ncpu);
1263
1427
 
1264
1428
    init_shared_memory(boot_argc, boot_argv);
1265
1429
    load_preloaded();
1274
1438
 
1275
1439
    erts_sys_main_thread(); /* May or may not return! */
1276
1440
#else
 
1441
    erts_thr_set_main_status(1, 1);
1277
1442
    set_main_stack_size();
1278
1443
    process_main();
1279
1444
#endif
1347
1512
    erts_cleanup_incgc();
1348
1513
#endif
1349
1514
 
1350
 
#if defined(USE_THREADS) && !defined(ERTS_SMP)
 
1515
#if defined(USE_THREADS)
1351
1516
    exit_async();
1352
1517
#endif
1353
1518
#if HAVE_ERTS_MSEG
1396
1561
    if (fmt != NULL && *fmt != '\0')
1397
1562
          erl_error(fmt, args); /* Print error message. */
1398
1563
    va_end(args);
1399
 
#ifdef __WIN32__
1400
 
    if(n > 0) ConWaitForExit();
1401
 
    else ConNormalExit();
1402
 
#endif
1403
 
#if !defined(__WIN32__) && !defined(VXWORKS) && !defined(_OSE_)
1404
 
    sys_tty_reset();
1405
 
#endif
 
1564
    sys_tty_reset(n);
1406
1565
 
1407
1566
    if (n == ERTS_INTR_EXIT)
1408
1567
        exit(0);
1442
1601
    if (fmt != NULL && *fmt != '\0')
1443
1602
          erl_error(fmt, args); /* Print error message. */
1444
1603
    va_end(args);
1445
 
#ifdef __WIN32__
1446
 
    if(n > 0) ConWaitForExit();
1447
 
    else ConNormalExit();
1448
 
#endif
1449
 
#if !defined(__WIN32__) && !defined(VXWORKS) && !defined(_OSE_)
1450
 
    sys_tty_reset();
1451
 
#endif
 
1604
    sys_tty_reset(n);
1452
1605
 
1453
1606
    if (n == ERTS_INTR_EXIT)
1454
1607
        exit(0);