diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/doc/src/erl.xml | 18 | ||||
-rw-r--r-- | erts/emulator/beam/erl_init.c | 72 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.c | 7 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.h | 6 | ||||
-rw-r--r-- | erts/emulator/beam/time.c | 12 | ||||
-rw-r--r-- | erts/emulator/beam/utils.c | 43 | ||||
-rw-r--r-- | erts/etc/common/ct_run.c | 40 | ||||
-rw-r--r-- | erts/etc/common/dialyzer.c | 39 | ||||
-rw-r--r-- | erts/etc/common/erlc.c | 37 | ||||
-rw-r--r-- | erts/etc/common/erlexec.c | 10 | ||||
-rw-r--r-- | erts/etc/common/escript.c | 30 | ||||
-rw-r--r-- | erts/etc/common/typer.c | 38 | ||||
-rw-r--r-- | erts/lib_src/win/ethread.c | 4 |
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: |