aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/erl.xml18
-rw-r--r--erts/emulator/beam/erl_init.c72
-rw-r--r--erts/emulator/beam/erl_process.c7
-rw-r--r--erts/emulator/beam/erl_process.h6
-rw-r--r--erts/emulator/beam/time.c12
-rw-r--r--erts/emulator/beam/utils.c43
-rw-r--r--erts/etc/common/ct_run.c40
-rw-r--r--erts/etc/common/dialyzer.c39
-rw-r--r--erts/etc/common/erlc.c37
-rw-r--r--erts/etc/common/erlexec.c10
-rw-r--r--erts/etc/common/escript.c30
-rw-r--r--erts/etc/common/typer.c38
-rw-r--r--erts/lib_src/win/ethread.c4
13 files changed, 302 insertions, 54 deletions
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index 829acd1154..ef8126e86f 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -1318,8 +1318,22 @@
<c><![CDATA[+sss size]]></c></tag>
<item>
<p>Suggested stack size, in kilowords, for scheduler threads.
- Valid range is 4-8192 kilowords. The default stack size is
- OS-dependent.</p>
+ Valid range is 20-8192 kilowords. The default suggested
+ stack size is 128 kilowords.</p>
+ </item>
+ <tag><marker id="dcpu_sched_thread_stack_size"/>
+ <c><![CDATA[+sssdcpu size]]></c></tag>
+ <item>
+ <p>Suggested stack size, in kilowords, for dirty CPU scheduler
+ threads. Valid range is 20-8192 kilowords. The default
+ suggested stack size is 40 kilowords.</p>
+ </item>
+ <tag><marker id="dio_sched_thread_stack_size"/>
+ <c><![CDATA[+sssdio size]]></c></tag>
+ <item>
+ <p>Suggested stack size, in kilowords, for dirty IO scheduler
+ threads. Valid range is 20-8192 kilowords. The default
+ suggested stack size is 40 kilowords.</p>
</item>
<tag><marker id="+stbt"/><c>+stbt BindType</c></tag>
<item>
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index ac0324d846..eaaf5c911a 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -61,8 +61,9 @@
#define ERTS_DEFAULT_NO_ASYNC_THREADS 10
-#define ERTS_DEFAULT_SCHED_STACK_SIZE 256
-#define ERTS_MIN_SCHED_STACK_SIZE 20
+#define ERTS_DEFAULT_SCHED_STACK_SIZE 128
+#define ERTS_DEFAULT_DCPU_SCHED_STACK_SIZE 40
+#define ERTS_DEFAULT_DIO_SCHED_STACK_SIZE 40
/*
* The variables below (prefixed with etp_) are for erts/etc/unix/etp-commands
@@ -641,9 +642,22 @@ void erts_usage(void)
erts_fprintf(stderr, "-swt val set scheduler wakeup threshold, valid values are:\n");
erts_fprintf(stderr, " very_low|low|medium|high|very_high.\n");
erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n");
- erts_fprintf(stderr, " valid range is [%d-%d]\n",
+ erts_fprintf(stderr, " valid range is [%d-%d] (default %d)\n",
+ ERTS_SCHED_THREAD_MIN_STACK_SIZE,
+ ERTS_SCHED_THREAD_MAX_STACK_SIZE,
+ ERTS_DEFAULT_SCHED_STACK_SIZE);
+#ifdef ERTS_DIRTY_SCHEDULERS
+ erts_fprintf(stderr, "-sssdcpu size suggested stack size in kilo words for dirty CPU scheduler\n");
+ erts_fprintf(stderr, " threads, valid range is [%d-%d] (default %d)\n",
+ ERTS_SCHED_THREAD_MIN_STACK_SIZE,
+ ERTS_SCHED_THREAD_MAX_STACK_SIZE,
+ ERTS_DEFAULT_DCPU_SCHED_STACK_SIZE);
+ erts_fprintf(stderr, "-sssdio size suggested stack size in kilo words for dirty IO scheduler\n");
+ erts_fprintf(stderr, " threads, valid range is [%d-%d] (default %d)\n",
ERTS_SCHED_THREAD_MIN_STACK_SIZE,
- ERTS_SCHED_THREAD_MAX_STACK_SIZE);
+ ERTS_SCHED_THREAD_MAX_STACK_SIZE,
+ ERTS_DEFAULT_DIO_SCHED_STACK_SIZE);
+#endif
erts_fprintf(stderr, "-spp Bool set port parallelism scheduling hint\n");
erts_fprintf(stderr, "-S n1:n2 set number of schedulers (n1), and number of\n");
erts_fprintf(stderr, " schedulers online (n2), maximum for both\n");
@@ -1327,6 +1341,10 @@ erl_start(int argc, char **argv)
* a lot of stack.
*/
erts_sched_thread_suggested_stack_size = ERTS_DEFAULT_SCHED_STACK_SIZE;
+#ifdef ERTS_DIRTY_SCHEDULERS
+ erts_dcpu_sched_thread_suggested_stack_size = ERTS_DEFAULT_DCPU_SCHED_STACK_SIZE;
+ erts_dio_sched_thread_suggested_stack_size = ERTS_DEFAULT_DIO_SCHED_STACK_SIZE;
+#endif
#ifdef DEBUG
verbose = DEBUG_DEFAULT;
@@ -1945,6 +1963,42 @@ erl_start(int argc, char **argv)
VERBOSE(DEBUG_SYSTEM,
("scheduler wakeup threshold: %s\n", arg));
}
+#ifdef ERTS_DIRTY_SCHEDULERS
+ else if (has_prefix("ssdcpu", sub_param)) {
+ /* suggested stack size (Kilo Words) for dirty CPU scheduler threads */
+ arg = get_arg(sub_param+6, argv[i+1], &i);
+ erts_dcpu_sched_thread_suggested_stack_size = atoi(arg);
+
+ if ((erts_dcpu_sched_thread_suggested_stack_size
+ < ERTS_SCHED_THREAD_MIN_STACK_SIZE)
+ || (erts_dcpu_sched_thread_suggested_stack_size >
+ ERTS_SCHED_THREAD_MAX_STACK_SIZE)) {
+ erts_fprintf(stderr, "bad stack size for dirty CPU scheduler threads %s\n",
+ arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM,
+ ("suggested dirty CPU scheduler thread stack size %d kilo words\n",
+ erts_dcpu_sched_thread_suggested_stack_size));
+ }
+ else if (has_prefix("ssdio", sub_param)) {
+ /* suggested stack size (Kilo Words) for dirty IO scheduler threads */
+ arg = get_arg(sub_param+5, argv[i+1], &i);
+ erts_dio_sched_thread_suggested_stack_size = atoi(arg);
+
+ if ((erts_dio_sched_thread_suggested_stack_size
+ < ERTS_SCHED_THREAD_MIN_STACK_SIZE)
+ || (erts_dio_sched_thread_suggested_stack_size >
+ ERTS_SCHED_THREAD_MAX_STACK_SIZE)) {
+ erts_fprintf(stderr, "bad stack size for dirty IO scheduler threads %s\n",
+ arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM,
+ ("suggested dirty IO scheduler thread stack size %d kilo words\n",
+ erts_dio_sched_thread_suggested_stack_size));
+ }
+#endif
else if (has_prefix("ss", sub_param)) {
/* suggested stack size (Kilo Words) for scheduler threads */
arg = get_arg(sub_param+2, argv[i+1], &i);
@@ -2259,8 +2313,14 @@ erl_start(int argc, char **argv)
boot_argc = argc - i; /* Number of arguments to init */
boot_argv = &argv[i];
- if (erts_sched_thread_suggested_stack_size < ERTS_MIN_SCHED_STACK_SIZE)
- erts_sched_thread_suggested_stack_size = ERTS_MIN_SCHED_STACK_SIZE;
+ if (erts_sched_thread_suggested_stack_size < ERTS_SCHED_THREAD_MIN_STACK_SIZE)
+ erts_sched_thread_suggested_stack_size = ERTS_SCHED_THREAD_MIN_STACK_SIZE;
+#ifdef ERTS_DIRTY_SCHEDULERS
+ if (erts_dcpu_sched_thread_suggested_stack_size < ERTS_SCHED_THREAD_MIN_STACK_SIZE)
+ erts_dcpu_sched_thread_suggested_stack_size = ERTS_SCHED_THREAD_MIN_STACK_SIZE;
+ if (erts_dio_sched_thread_suggested_stack_size < ERTS_SCHED_THREAD_MIN_STACK_SIZE)
+ erts_dio_sched_thread_suggested_stack_size = ERTS_SCHED_THREAD_MIN_STACK_SIZE;
+#endif
erl_init(ncpu,
proc_tab_sz,
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index f35c5e04a2..9947e33f47 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -194,7 +194,10 @@ static UWord thr_prgr_later_cleanup_op_threshold = ERTS_THR_PRGR_LATER_CLEANUP_O
ErtsPTab erts_proc erts_align_attribute(ERTS_CACHE_LINE_SIZE);
int erts_sched_thread_suggested_stack_size = -1;
-
+#ifdef ERTS_DIRTY_SCHEDULERS
+int erts_dcpu_sched_thread_suggested_stack_size = -1;
+int erts_dio_sched_thread_suggested_stack_size = -1;
+#endif
#ifdef ERTS_ENABLE_LOCK_CHECK
ErtsLcPSDLocks erts_psd_required_locks[ERTS_PSD_SIZE];
#endif
@@ -8999,6 +9002,7 @@ erts_start_schedulers(void)
for (ix = 0; ix < erts_no_dirty_cpu_schedulers; ix++) {
ErtsSchedulerData *esdp = ERTS_DIRTY_CPU_SCHEDULER_IX(ix);
erts_snprintf(opts.name, 16, "%d_dirty_cpu_scheduler", ix + 1);
+ opts.suggested_stack_size = erts_dcpu_sched_thread_suggested_stack_size;
res = ethr_thr_create(&esdp->tid,sched_dirty_cpu_thread_func,(void*)esdp,&opts);
if (res != 0)
erts_exit(ERTS_ERROR_EXIT, "Failed to create dirty cpu scheduler thread %d\n", ix);
@@ -9006,6 +9010,7 @@ erts_start_schedulers(void)
for (ix = 0; ix < erts_no_dirty_io_schedulers; ix++) {
ErtsSchedulerData *esdp = ERTS_DIRTY_IO_SCHEDULER_IX(ix);
erts_snprintf(opts.name, 16, "%d_dirty_io_scheduler", ix + 1);
+ opts.suggested_stack_size = erts_dio_sched_thread_suggested_stack_size;
res = ethr_thr_create(&esdp->tid,sched_dirty_io_thread_func,(void*)esdp,&opts);
if (res != 0)
erts_exit(ERTS_ERROR_EXIT, "Failed to create dirty io scheduler thread %d\n", ix);
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index b21597d63b..5b35dc3c78 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -117,7 +117,11 @@ extern Uint erts_no_dirty_io_schedulers;
#endif
extern Uint erts_no_run_queues;
extern int erts_sched_thread_suggested_stack_size;
-#define ERTS_SCHED_THREAD_MIN_STACK_SIZE 4 /* Kilo words */
+#ifdef ERTS_DIRTY_SCHEDULERS
+extern int erts_dcpu_sched_thread_suggested_stack_size;
+extern int erts_dio_sched_thread_suggested_stack_size;
+#endif
+#define ERTS_SCHED_THREAD_MIN_STACK_SIZE 20 /* Kilo words */
#define ERTS_SCHED_THREAD_MAX_STACK_SIZE 8192 /* Kilo words */
#ifdef ERTS_SMP
diff --git a/erts/emulator/beam/time.c b/erts/emulator/beam/time.c
index cee3cb619f..a7e5a64b22 100644
--- a/erts/emulator/beam/time.c
+++ b/erts/emulator/beam/time.c
@@ -1364,21 +1364,29 @@ dbg_verify_empty_later_slots(ErtsTimerWheel *tiw, ErtsMonotonicTime to_pos)
tmp = to_pos;
tmp &= ERTS_TW_LATER_WHEEL_POS_MASK;
if (tmp > tiw->later.pos) {
+ ErtsMonotonicTime pos_min;
int slots;
tmp -= tiw->later.pos;
tmp /= ERTS_TW_LATER_WHEEL_SLOT_SIZE;
ERTS_TW_ASSERT(tmp > 0);
+
+ pos_min = tiw->later.pos;
+
if (tmp < (ErtsMonotonicTime) ERTS_TW_LATER_WHEEL_SIZE)
slots = (int) tmp;
- else
+ else {
+ pos_min += ((tmp / ERTS_TW_LATER_WHEEL_SIZE)
+ * ERTS_TW_LATER_WHEEL_SLOT_SIZE);
slots = ERTS_TW_LATER_WHEEL_SIZE;
+ }
while (slots > 0) {
ErtsTWheelTimer *tmr = tiw->w[ix];
+ pos_min += ERTS_TW_LATER_WHEEL_SLOT_SIZE;
if (tmr) {
ErtsTWheelTimer *end = tmr;
do {
- ERTS_TW_ASSERT(tmr->timeout_pos > to_pos);
+ ERTS_TW_ASSERT(tmr->timeout_pos >= pos_min);
tmr = tmr->next;
} while (tmr != end);
}
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 9263798a28..cdf766b206 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -1581,9 +1581,6 @@ Uint32
make_internal_hash(Eterm term)
{
Uint32 hash;
- Uint32 hash_xor_pairs;
-
- ERTS_UNDEF(hash_xor_pairs, 0);
/* Optimization. Simple cases before declaration of estack. */
if (primary_tag(term) == TAG_PRIMARY_IMMED1) {
@@ -1664,6 +1661,11 @@ make_internal_hash(Eterm term)
Eterm* ptr = boxed_val(term) + 1;
Uint size;
int i;
+
+ /*
+ * We rely on key-value iteration order being constant
+ * for identical maps (in this VM instance).
+ */
switch (hdr & _HEADER_MAP_SUBTAG_MASK) {
case HAMT_SUBTAG_HEAD_FLATMAP:
{
@@ -1675,26 +1677,10 @@ make_internal_hash(Eterm term)
if (size == 0)
goto pop_next;
- /* We want a hash function that is *independent* of
- * the order in which keys and values are encountered.
- * We therefore calculate context independent hashes for all .
- * key-value pairs and then xor them together.
- *
- * We *do* need to use an initial seed for each pair, i.e. the
- * hash value, so the hash value is reset for each pair with 'hash'.
- * If we don't, no additional entropy is given to the system and the
- * hash collision resolution in maps:from_list/1 would fail.
- */
- ESTACK_PUSH(s, hash_xor_pairs);
- ESTACK_PUSH(s, hash);
- ESTACK_PUSH(s, HASH_MAP_TAIL);
for (i = size - 1; i >= 0; i--) {
- ESTACK_PUSH(s, hash); /* initial seed for all pairs */
- ESTACK_PUSH(s, HASH_MAP_PAIR);
ESTACK_PUSH(s, vs[i]);
ESTACK_PUSH(s, ks[i]);
}
- hash_xor_pairs = 0;
goto pop_next;
}
case HAMT_SUBTAG_HEAD_ARRAY:
@@ -1703,10 +1689,6 @@ make_internal_hash(Eterm term)
UINT32_HASH(size, HCONST_16);
if (size == 0)
goto pop_next;
- ESTACK_PUSH(s, hash_xor_pairs);
- ESTACK_PUSH(s, hash);
- ESTACK_PUSH(s, HASH_MAP_TAIL);
- hash_xor_pairs = 0;
}
switch (hdr & _HEADER_MAP_SUBTAG_MASK) {
case HAMT_SUBTAG_HEAD_ARRAY:
@@ -1722,8 +1704,6 @@ make_internal_hash(Eterm term)
while (i) {
if (is_list(*ptr)) {
Eterm* cons = list_val(*ptr);
- ESTACK_PUSH(s, hash); /* initial seed for all pairs */
- ESTACK_PUSH(s, HASH_MAP_PAIR);
ESTACK_PUSH(s, CDR(cons));
ESTACK_PUSH(s, CAR(cons));
}
@@ -1739,7 +1719,7 @@ make_internal_hash(Eterm term)
case EXPORT_SUBTAG:
{
Export* ep = *((Export **) (export_val(term) + 1));
- /* Assumes Export entries never moves */
+ /* Assumes Export entries never move */
POINTER_HASH(ep, HCONST_14);
goto pop_next;
}
@@ -1919,17 +1899,6 @@ make_internal_hash(Eterm term)
term = ESTACK_POP(s);
switch (term) {
- case HASH_MAP_TAIL: {
- hash = (Uint32) ESTACK_POP(s);
- UINT32_HASH(hash_xor_pairs, HCONST_19);
- hash_xor_pairs = (Uint32) ESTACK_POP(s);
- goto pop_next;
- }
- case HASH_MAP_PAIR:
- hash_xor_pairs ^= hash;
- hash = (Uint32) ESTACK_POP(s); /* initial seed for all pairs */
- goto pop_next;
-
case HASH_CDR:
CONST_HASH(HCONST_18); /* Hash CDR i cons cell */
goto pop_next;
diff --git a/erts/etc/common/ct_run.c b/erts/etc/common/ct_run.c
index acdfa8c8b8..898c8ccde0 100644
--- a/erts/etc/common/ct_run.c
+++ b/erts/etc/common/ct_run.c
@@ -82,6 +82,9 @@ static int eargc; /* Number of arguments in eargv. */
static void error(char* format, ...);
static void* emalloc(size_t size);
+#ifdef HAVE_COPYING_PUTENV
+static void efree(void *p);
+#endif
static char* strsave(char* string);
static void push_words(char* src);
static int run_erlang(char* name, char** argv);
@@ -119,6 +122,30 @@ char *strerror(int errnum)
}
#endif /* !HAVE_STRERROR */
+
+static void
+set_env(char *key, char *value)
+{
+#ifdef __WIN32__
+ WCHAR wkey[MAXPATHLEN];
+ WCHAR wvalue[MAXPATHLEN];
+ MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, MAXPATHLEN);
+ MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, MAXPATHLEN);
+ if (!SetEnvironmentVariableW(wkey, wvalue))
+ error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value);
+#else
+ size_t size = strlen(key) + 1 + strlen(value) + 1;
+ char *str = emalloc(size);
+ sprintf(str, "%s=%s", key, value);
+ if (putenv(str) != 0)
+ error("putenv(\"%s\") failed!", str);
+#ifdef HAVE_COPYING_PUTENV
+ efree(str);
+#endif
+#endif
+}
+
+
#ifdef __WIN32__
int wmain(int argc, wchar_t **wcargv)
{
@@ -155,6 +182,11 @@ int main(int argc, char** argv)
emulator = get_default_emulator(argv[0]);
/*
+ * Add scriptname to env
+ */
+ set_env("ESCRIPT_NAME", argv[0]);
+
+ /*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
* the array, to allow easy addition of commands in the beginning.
@@ -458,6 +490,14 @@ erealloc(void *p, size_t size)
}
#endif
+#ifdef HAVE_COPYING_PUTENV
+static void
+efree(void *p)
+{
+ free(p);
+}
+#endif
+
static char*
strsave(char* string)
{
diff --git a/erts/etc/common/dialyzer.c b/erts/etc/common/dialyzer.c
index 6ba3605422..829984ef3f 100644
--- a/erts/etc/common/dialyzer.c
+++ b/erts/etc/common/dialyzer.c
@@ -64,6 +64,9 @@ static int eargc; /* Number of arguments in eargv. */
static void error(char* format, ...);
static void* emalloc(size_t size);
+#ifdef HAVE_COPYING_PUTENV
+static void efree(void *p);
+#endif
static char* strsave(char* string);
static void push_words(char* src);
static int run_erlang(char* name, char** argv);
@@ -147,6 +150,29 @@ free_env_val(char *value)
#endif
}
+static void
+set_env(char *key, char *value)
+{
+#ifdef __WIN32__
+ WCHAR wkey[MAXPATHLEN];
+ WCHAR wvalue[MAXPATHLEN];
+ MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, MAXPATHLEN);
+ MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, MAXPATHLEN);
+ if (!SetEnvironmentVariableW(wkey, wvalue))
+ error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value);
+#else
+ size_t size = strlen(key) + 1 + strlen(value) + 1;
+ char *str = emalloc(size);
+ sprintf(str, "%s=%s", key, value);
+ if (putenv(str) != 0)
+ error("putenv(\"%s\") failed!", str);
+#ifdef HAVE_COPYING_PUTENV
+ efree(str);
+#endif
+#endif
+}
+
+
#ifdef __WIN32__
int wmain(int argc, wchar_t **wcargv)
{
@@ -181,6 +207,11 @@ int main(int argc, char** argv)
error("Value of environment variable DIALYZER_EMULATOR is too large");
/*
+ * Add scriptname to env
+ */
+ set_env("ESCRIPT_NAME", argv[0]);
+
+ /*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
* the array, to allow easy addition of commands in the beginning.
@@ -434,6 +465,14 @@ erealloc(void *p, size_t size)
}
#endif
+#ifdef HAVE_COPYING_PUTENV
+static void
+efree(void *p)
+{
+ free(p);
+}
+#endif
+
static char*
strsave(char* string)
{
diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c
index b54cb31bef..2abeff33a3 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -72,6 +72,9 @@ static int pause_after_execution = 0;
static char* process_opt(int* pArgc, char*** pArgv, int offset);
static void error(char* format, ...);
static void* emalloc(size_t size);
+#ifdef HAVE_COPYING_PUTENV
+static void efree(void *p);
+#endif
static char* strsave(char* string);
static void push_words(char* src);
static int run_erlang(char* name, char** argv);
@@ -147,6 +150,28 @@ get_env(char *key)
}
static void
+set_env(char *key, char *value)
+{
+#ifdef __WIN32__
+ WCHAR wkey[MAXPATHLEN];
+ WCHAR wvalue[MAXPATHLEN];
+ MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, MAXPATHLEN);
+ MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, MAXPATHLEN);
+ if (!SetEnvironmentVariableW(wkey, wvalue))
+ error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value);
+#else
+ size_t size = strlen(key) + 1 + strlen(value) + 1;
+ char *str = emalloc(size);
+ sprintf(str, "%s=%s", key, value);
+ if (putenv(str) != 0)
+ error("putenv(\"%s\") failed!", str);
+#ifdef HAVE_COPYING_PUTENV
+ efree(str);
+#endif
+#endif
+}
+
+static void
free_env_val(char *value)
{
#ifdef __WIN32__
@@ -188,6 +213,11 @@ int main(int argc, char** argv)
error("Value of environment variable ERLC_EMULATOR is too large");
/*
+ * Add scriptname to env
+ */
+ set_env("ESCRIPT_NAME", argv[0]);
+
+ /*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
* the array, to allow easy adding of emulator options (like -pa)
@@ -499,6 +529,13 @@ erealloc(void *p, size_t size)
}
#endif
+#ifdef HAVE_COPYING_PUTENV
+static void
+efree(void *p)
+{
+ free(p);
+}
+#endif
static char*
strsave(char* string)
{
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index b29190e4d9..f11ec2320a 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -141,6 +141,8 @@ static char *pluss_val_switches[] = {
"wt",
"ws",
"ss",
+ "ssdcpu",
+ "ssdio",
"pp",
"ub",
NULL
@@ -585,8 +587,12 @@ int main(int argc, char **argv)
erts_snprintf(tmpStr, sizeof(tmpStr), "%s" DIRSEP "%s" BINARY_EXT, bindir, emu);
emu = strsave(tmpStr);
- add_Eargs(emu); /* Will be argv[0] -- necessary! */
-
+ s = get_env("ESCRIPT_NAME");
+ if(s) {
+ add_Eargs(s); /* argv[0] = scriptname*/
+ } else {
+ add_Eargs(progname); /* argv[0] = erl or cerl */
+ }
/*
* Add the bindir to the path (unless it is there already).
*/
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 4134a3ff36..c28e45a044 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -155,6 +155,29 @@ free_env_val(char *value)
efree(value);
#endif
}
+
+static void
+set_env(char *key, char *value)
+{
+#ifdef __WIN32__
+ WCHAR wkey[MAXPATHLEN];
+ WCHAR wvalue[MAXPATHLEN];
+ MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, MAXPATHLEN);
+ MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, MAXPATHLEN);
+ if (!SetEnvironmentVariableW(wkey, wvalue))
+ error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value);
+#else
+ size_t size = strlen(key) + 1 + strlen(value) + 1;
+ char *str = emalloc(size);
+ sprintf(str, "%s=%s", key, value);
+ if (putenv(str) != 0)
+ error("putenv(\"%s\") failed!", str);
+#ifdef HAVE_COPYING_PUTENV
+ efree(str);
+#endif
+#endif
+}
+
/*
* Find absolute path to this program
*/
@@ -548,7 +571,12 @@ main(int argc, char** argv)
while (--eargc_base >= 0) {
UNSHIFT(eargv_base[eargc_base]);
}
-
+
+ /*
+ * Add scriptname to env
+ */
+ set_env("ESCRIPT_NAME", scriptname);
+
/*
* Invoke Erlang with the collected options.
*/
diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c
index 77a95ccded..644c90a795 100644
--- a/erts/etc/common/typer.c
+++ b/erts/etc/common/typer.c
@@ -64,6 +64,9 @@ static int eargc; /* Number of arguments in eargv. */
static void error(char* format, ...);
static void* emalloc(size_t size);
+#ifdef HAVE_COPYING_PUTENV
+static void efree(void *p);
+#endif
static char* strsave(char* string);
static void push_words(char* src);
static int run_erlang(char* name, char** argv);
@@ -101,6 +104,29 @@ char *strerror(int errnum)
}
#endif /* !HAVE_STRERROR */
+static void
+set_env(char *key, char *value)
+{
+#ifdef __WIN32__
+ WCHAR wkey[MAXPATHLEN];
+ WCHAR wvalue[MAXPATHLEN];
+ MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, MAXPATHLEN);
+ MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, MAXPATHLEN);
+ if (!SetEnvironmentVariableW(wkey, wvalue))
+ error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value);
+#else
+ size_t size = strlen(key) + 1 + strlen(value) + 1;
+ char *str = emalloc(size);
+ sprintf(str, "%s=%s", key, value);
+ if (putenv(str) != 0)
+ error("putenv(\"%s\") failed!", str);
+#ifdef HAVE_COPYING_PUTENV
+ efree(str);
+#endif
+#endif
+}
+
+
#ifdef __WIN32__
int wmain(int argc, wchar_t **wcargv)
{
@@ -129,6 +155,10 @@ main(int argc, char** argv)
#endif
emulator = get_default_emulator(argv[0]);
+ /*
+ * Add scriptname to env
+ */
+ set_env("ESCRIPT_NAME", argv[0]);
/*
* Allocate the argv vector to be used for arguments to Erlang.
@@ -353,6 +383,14 @@ erealloc(void *p, size_t size)
}
#endif
+#ifdef HAVE_COPYING_PUTENV
+static void
+efree(void *p)
+{
+ free(p);
+}
+#endif
+
static char*
strsave(char* string)
{
diff --git a/erts/lib_src/win/ethread.c b/erts/lib_src/win/ethread.c
index ba77b3dc88..98fcd2d451 100644
--- a/erts/lib_src/win/ethread.c
+++ b/erts/lib_src/win/ethread.c
@@ -203,6 +203,8 @@ ethr_init(ethr_init_data *id)
if (!ethr_not_inited__)
return EINVAL;
+ ethr_not_inited__ = 0;
+
#ifdef _WIN32_WINNT
os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&os_version);
@@ -238,8 +240,6 @@ ethr_init(ethr_init_data *id)
if (erts_get_cpu_configured(ethr_cpu_info__) == 1)
child_wait_spin_count = 0;
- ethr_not_inited__ = 0;
-
return 0;
error: