aboutsummaryrefslogtreecommitdiffstats
path: root/erts/etc
diff options
context:
space:
mode:
Diffstat (limited to 'erts/etc')
-rw-r--r--erts/etc/common/Makefile.in13
-rw-r--r--erts/etc/common/erlexec.c42
-rw-r--r--erts/etc/common/typer.c455
-rw-r--r--erts/etc/unix/Install.src1
-rw-r--r--erts/etc/unix/etp-commands.in75
-rw-r--r--erts/etc/unix/to_erl.c2
-rw-r--r--erts/etc/win32/Install.c1
7 files changed, 565 insertions, 24 deletions
diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in
index d3af634729..b4fa0d4c79 100644
--- a/erts/etc/common/Makefile.in
+++ b/erts/etc/common/Makefile.in
@@ -143,7 +143,7 @@ MC_OUTPUTS=$(OBJDIR)/erlsrv_logmess.h $(OBJDIR)/erlsrv_logmess.res
MT_FLAG="-MD"
endif
INET_GETHOST = $(BINDIR)/inet_gethost.exe
-INSTALL_EMBEDDED_PROGS += $(BINDIR)/dialyzer.exe $(BINDIR)/erlc.exe $(BINDIR)/start_erl.exe $(BINDIR)/escript.exe $(BINDIR)/ct_run.exe
+INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer.exe $(BINDIR)/dialyzer.exe $(BINDIR)/erlc.exe $(BINDIR)/start_erl.exe $(BINDIR)/escript.exe $(BINDIR)/ct_run.exe
INSTALL_SRC = $(WINETC)/start_erl.c $(WINETC)/Nmakefile.start_erl
ERLEXECDIR=.
INSTALL_LIBS =
@@ -176,7 +176,7 @@ ENTRY_OBJ=
ERLSRV_OBJECTS=
MC_OUTPUTS=
INET_GETHOST = $(BINDIR)/inet_gethost@EXEEXT@
-INSTALL_EMBEDDED_PROGS += $(BINDIR)/dialyzer@EXEEXT@ \
+INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer@EXEEXT@ $(BINDIR)/dialyzer@EXEEXT@ \
$(BINDIR)/erlc@EXEEXT@ $(BINDIR)/escript@EXEEXT@ $(BINDIR)/ct_run@EXEEXT@ \
$(BINDIR)/run_erl $(BINDIR)/to_erl $(BINDIR)/dyn_erl
INSTALL_EMBEDDED_DATA = $(UXETC)/start.src $(UXETC)/start_erl.src
@@ -238,6 +238,7 @@ endif
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/reclaim.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/run_erl.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/to_erl.o
+ rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/typer.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/dyn_erl.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/safe_string.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/run_erl.o
@@ -360,7 +361,7 @@ Install.ini: ../$(TARGET)/Install.src ../../vsn.mk $(TARGET)/Makefile
else
-RC_GENERATED =
+RC_GENERATED = $(ERL_TOP)/erts/$(TARGET)/config.h
endif
#---------------------------------------------------------
# End of windows specific targets.
@@ -432,6 +433,12 @@ $(BINDIR)/dialyzer@EXEEXT@: $(OBJDIR)/dialyzer.o $(ERTS_LIB)
$(OBJDIR)/dialyzer.o: dialyzer.c $(RC_GENERATED)
$(V_CC) $(CFLAGS) -o $@ -c dialyzer.c
+$(BINDIR)/typer@EXEEXT@: $(OBJDIR)/typer.o $(ERTS_LIB)
+ $(ld_verbose)$(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/typer.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS)
+
+$(OBJDIR)/typer.o: typer.c $(RC_GENERATED)
+ $(V_CC) $(CFLAGS) -o $@ -c typer.c
+
$(BINDIR)/escript@EXEEXT@: $(OBJDIR)/escript.o $(ERTS_LIB)
$(ld_verbose)$(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/escript.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS)
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index 362817e94c..8b75199a1e 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -205,8 +205,8 @@ void error(char* format, ...);
* Local functions.
*/
-#if !defined(ERTS_HAVE_SMP_EMU)
-static void usage_notsup(const char *switchname);
+#if !defined(ERTS_HAVE_SMP_EMU) || !defined(ERTS_HAVE_PLAIN_EMU)
+static void usage_notsup(const char *switchname, const char *alt);
#endif
static char **build_args_from_env(char *env_var);
static char **build_args_from_string(char *env_var);
@@ -489,8 +489,7 @@ int main(int argc, char **argv)
cpuinfo = erts_cpu_info_create();
/* '-smp auto' is default */
#ifdef ERTS_HAVE_SMP_EMU
- if (erts_get_cpu_configured(cpuinfo) > 1)
- emu_type |= EMU_TYPE_SMP;
+ emu_type |= EMU_TYPE_SMP;
#endif
#if defined(__WIN32__) && defined(WIN32_ALWAYS_DEBUG)
@@ -522,12 +521,11 @@ int main(int argc, char **argv)
i++;
smp_auto:
emu_type_passed |= EMU_TYPE_SMP;
-#ifdef ERTS_HAVE_SMP_EMU
- if (erts_get_cpu_configured(cpuinfo) > 1)
- emu_type |= EMU_TYPE_SMP;
- else
+#if defined(ERTS_HAVE_PLAIN_EMU) && !defined(ERTS_HAVE_SMP_EMU)
+ emu_type &= ~EMU_TYPE_SMP;
+#else
+ emu_type |= EMU_TYPE_SMP;
#endif
- emu_type &= ~EMU_TYPE_SMP;
}
else if (strcmp(argv[i+1], "enable") == 0) {
i++;
@@ -536,14 +534,18 @@ int main(int argc, char **argv)
#ifdef ERTS_HAVE_SMP_EMU
emu_type |= EMU_TYPE_SMP;
#else
- usage_notsup("-smp enable");
+ usage_notsup("-smp enable", "");
#endif
}
else if (strcmp(argv[i+1], "disable") == 0) {
i++;
smp_disable:
- emu_type_passed |= EMU_TYPE_SMP;
+ emu_type_passed &= ~EMU_TYPE_SMP;
+#ifdef ERTS_HAVE_PLAIN_EMU
emu_type &= ~EMU_TYPE_SMP;
+#else
+ usage_notsup("-smp disable", " Use \"+S 1\" instead.");
+#endif
}
else {
smp:
@@ -552,7 +554,7 @@ int main(int argc, char **argv)
#ifdef ERTS_HAVE_SMP_EMU
emu_type |= EMU_TYPE_SMP;
#else
- usage_notsup("-smp");
+ usage_notsup("-smp", "");
#endif
}
} else if (strcmp(argv[i], "-smpenable") == 0) {
@@ -1185,14 +1187,14 @@ usage_aux(void)
#ifdef __WIN32__
"[-start_erl [datafile]] "
#endif
- "[-smp "
+ "[-smp [auto"
#ifdef ERTS_HAVE_SMP_EMU
- "[enable|"
+ "|enable"
#endif
- "auto|disable"
-#ifdef ERTS_HAVE_SMP_EMU
- "]"
+#ifdef ERTS_HAVE_PLAIN_EMU
+ "|disable"
#endif
+ "]"
"] "
"[-make] [-man [manopts] MANPAGE] [-x] [-emu_args] [-start_epmd BOOLEAN] "
"[-args_file FILENAME] [+A THREADS] [+a SIZE] [+B[c|d|i]] [+c [BOOLEAN]] "
@@ -1214,11 +1216,11 @@ usage(const char *switchname)
usage_aux();
}
-#if !defined(ERTS_HAVE_SMP_EMU)
+#if !defined(ERTS_HAVE_SMP_EMU) || !defined(ERTS_HAVE_PLAIN_EMU)
static void
-usage_notsup(const char *switchname)
+usage_notsup(const char *switchname, const char *alt)
{
- fprintf(stderr, "Argument \'%s\' not supported.\n", switchname);
+ fprintf(stderr, "Argument \'%s\' not supported.%s\n", switchname, alt);
usage_aux();
}
#endif
diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c
new file mode 100644
index 0000000000..77a95ccded
--- /dev/null
+++ b/erts/etc/common/typer.c
@@ -0,0 +1,455 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2006-2016. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * %CopyrightEnd%
+ */
+/*
+ * Purpose: Typer front-end.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sys.h"
+#ifdef __WIN32__
+#include <winbase.h>
+#endif
+
+#include <ctype.h>
+
+#define NO 0
+#define YES 1
+
+#define ASIZE(a) (sizeof(a)/sizeof(a[0]))
+
+static int debug = 0; /* Bit flags for debug printouts. */
+
+static char** eargv_base; /* Base of vector. */
+static char** eargv; /* First argument for erl. */
+
+static int eargc; /* Number of arguments in eargv. */
+
+#ifdef __WIN32__
+# define QUOTE(s) possibly_quote(s)
+# define IS_DIRSEP(c) ((c) == '/' || (c) == '\\')
+# define ERL_NAME "erl.exe"
+#else
+# define QUOTE(s) s
+# define IS_DIRSEP(c) ((c) == '/')
+# define ERL_NAME "erl"
+#endif
+
+#define UNSHIFT(s) eargc++, eargv--; eargv[0] = QUOTE(s)
+#define PUSH(s) eargv[eargc++] = QUOTE(s)
+#define PUSH2(s, t) PUSH(s); PUSH(t)
+#define PUSH3(s, t, u) PUSH2(s, t); PUSH(u)
+
+/*
+ * Local functions.
+ */
+
+static void error(char* format, ...);
+static void* emalloc(size_t size);
+static char* strsave(char* string);
+static void push_words(char* src);
+static int run_erlang(char* name, char** argv);
+static char* get_default_emulator(char* progname);
+#ifdef __WIN32__
+static char* possibly_quote(char* arg);
+static void* erealloc(void *p, size_t size);
+#endif
+
+/*
+ * Supply a strerror() function if libc doesn't.
+ */
+#ifndef HAVE_STRERROR
+
+extern int sys_nerr;
+
+#ifndef SYS_ERRLIST_DECLARED
+extern const char * const sys_errlist[];
+#endif /* !SYS_ERRLIST_DECLARED */
+
+char *strerror(int errnum)
+{
+ static char *emsg[1024];
+
+ if (errnum != 0) {
+ if (errnum > 0 && errnum < sys_nerr)
+ sprintf((char *) &emsg[0], "(%s)", sys_errlist[errnum]);
+ else
+ sprintf((char *) &emsg[0], "errnum = %d ", errnum);
+ }
+ else {
+ emsg[0] = '\0';
+ }
+ return (char *) &emsg[0];
+}
+#endif /* !HAVE_STRERROR */
+
+#ifdef __WIN32__
+int wmain(int argc, wchar_t **wcargv)
+{
+ char** argv;
+#else
+int
+main(int argc, char** argv)
+{
+#endif
+ int eargv_size;
+ int eargc_base; /* How many arguments in the base of eargv. */
+ char* emulator;
+ int need_shell = 0;
+
+#ifdef __WIN32__
+ int i;
+ int len;
+ /* Convert argv to utf8 */
+ argv = emalloc((argc+1) * sizeof(char*));
+ for (i=0; i<argc; i++) {
+ len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL);
+ argv[i] = emalloc(len*sizeof(char));
+ WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, argv[i], len, NULL, NULL);
+ }
+ argv[argc] = NULL;
+#endif
+
+ emulator = get_default_emulator(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.
+ */
+
+ eargv_size = argc*4+100;
+ eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
+ eargv = eargv_base;
+ eargc = 0;
+ push_words(emulator);
+ eargc_base = eargc;
+ eargv = eargv + eargv_size/2;
+ eargc = 0;
+
+ /*
+ * Push initial arguments.
+ */
+
+ if (argc > 1 && strcmp(argv[1], "-smp") == 0) {
+ PUSH("-smpauto");
+ argc--, argv++;
+ }
+
+ PUSH("+B");
+ PUSH2("-boot", "start_clean");
+ PUSH3("-run", "typer", "start");
+ PUSH("-extra");
+
+ /*
+ * Push everything except --shell.
+ */
+
+ while (argc > 1) {
+ if (strcmp(argv[1], "--shell") == 0) {
+ need_shell = 1;
+ } else {
+ PUSH(argv[1]);
+ }
+ argc--, argv++;
+ }
+
+ if (!need_shell) {
+ UNSHIFT("-noinput");
+ }
+
+ /*
+ * Move up the commands for invoking the emulator and adjust eargv
+ * accordingly.
+ */
+
+ while (--eargc_base >= 0) {
+ UNSHIFT(eargv_base[eargc_base]);
+ }
+
+ /*
+ * Invoke Erlang with the collected options.
+ */
+
+ PUSH(NULL);
+ return run_erlang(eargv[0], eargv);
+}
+
+static void
+push_words(char* src)
+{
+ char sbuf[MAXPATHLEN];
+ char* dst;
+
+ dst = sbuf;
+ while ((*dst++ = *src++) != '\0') {
+ if (isspace((int)*src)) {
+ *dst = '\0';
+ PUSH(strsave(sbuf));
+ dst = sbuf;
+ do {
+ src++;
+ } while (isspace((int)*src));
+ }
+ }
+ if (sbuf[0])
+ PUSH(strsave(sbuf));
+}
+#ifdef __WIN32__
+wchar_t *make_commandline(char **argv)
+{
+ static wchar_t *buff = NULL;
+ static int siz = 0;
+ int num = 0, len;
+ char **arg;
+ wchar_t *p;
+
+ if (*argv == NULL) {
+ return L"";
+ }
+ for (arg = argv; *arg != NULL; ++arg) {
+ num += strlen(*arg)+1;
+ }
+ if (!siz) {
+ siz = num;
+ buff = (wchar_t *) emalloc(siz*sizeof(wchar_t));
+ } else if (siz < num) {
+ siz = num;
+ buff = (wchar_t *) erealloc(buff,siz*sizeof(wchar_t));
+ }
+ p = buff;
+ num=0;
+ for (arg = argv; *arg != NULL; ++arg) {
+ len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, p, siz);
+ p+=(len-1);
+ *p++=L' ';
+ }
+ *(--p) = L'\0';
+
+ if (debug) {
+ printf("Processed command line:%S\n",buff);
+ }
+ return buff;
+}
+
+int my_spawnvp(char **argv)
+{
+ STARTUPINFOW siStartInfo;
+ PROCESS_INFORMATION piProcInfo;
+ DWORD ec;
+
+ memset(&siStartInfo,0,sizeof(STARTUPINFOW));
+ siStartInfo.cb = sizeof(STARTUPINFOW);
+ siStartInfo.dwFlags = STARTF_USESTDHANDLES;
+ siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+ if (!CreateProcessW(NULL,
+ make_commandline(argv),
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &siStartInfo,
+ &piProcInfo)) {
+ return -1;
+ }
+ CloseHandle(piProcInfo.hThread);
+
+ WaitForSingleObject(piProcInfo.hProcess,INFINITE);
+ if (!GetExitCodeProcess(piProcInfo.hProcess,&ec)) {
+ return 0;
+ }
+ return (int) ec;
+}
+#endif /* __WIN32__ */
+
+
+static int
+run_erlang(char* progname, char** argv)
+{
+#ifdef __WIN32__
+ int status;
+#endif
+
+ if (debug) {
+ int i = 0;
+ while (argv[i] != NULL)
+ printf(" %s", argv[i++]);
+ printf("\n");
+ }
+
+#ifdef __WIN32__
+ /*
+ * Alas, we must wait here for the program to finish.
+ * Otherwise, the shell from which we were executed will think
+ * we are finished and print a prompt and read keyboard input.
+ */
+
+ status = my_spawnvp(argv)/*_spawnvp(_P_WAIT,progname,argv)*/;
+ if (status == -1) {
+ fprintf(stderr, "typer: Error executing '%s': %d", progname,
+ GetLastError());
+ }
+ return status;
+#else
+ execvp(progname, argv);
+ error("Error %d executing \'%s\'.", errno, progname);
+ return 2;
+#endif
+}
+
+static void
+error(char* format, ...)
+{
+ char sbuf[1024];
+ va_list ap;
+
+ va_start(ap, format);
+ erts_vsnprintf(sbuf, sizeof(sbuf), format, ap);
+ va_end(ap);
+ fprintf(stderr, "typer: %s\n", sbuf);
+ exit(1);
+}
+
+static void*
+emalloc(size_t size)
+{
+ void *p = malloc(size);
+ if (p == NULL)
+ error("Insufficient memory");
+ return p;
+}
+
+#ifdef __WIN32__
+static void *
+erealloc(void *p, size_t size)
+{
+ void *res = realloc(p, size);
+ if (res == NULL)
+ error("Insufficient memory");
+ return res;
+}
+#endif
+
+static char*
+strsave(char* string)
+{
+ char* p = emalloc(strlen(string)+1);
+ strcpy(p, string);
+ return p;
+}
+
+static int
+file_exists(char *progname)
+{
+#ifdef __WIN32__
+ wchar_t wcsbuf[MAXPATHLEN];
+ MultiByteToWideChar(CP_UTF8, 0, progname, -1, wcsbuf, MAXPATHLEN);
+ return (_waccess(wcsbuf, 0) != -1);
+#else
+ return (access(progname, 1) != -1);
+#endif
+}
+
+static char*
+get_default_emulator(char* progname)
+{
+ char sbuf[MAXPATHLEN];
+ char* s;
+
+ if (strlen(progname) >= sizeof(sbuf))
+ return ERL_NAME;
+
+ strcpy(sbuf, progname);
+ for (s = sbuf+strlen(sbuf); s >= sbuf; s--) {
+ if (IS_DIRSEP(*s)) {
+ strcpy(s+1, ERL_NAME);
+ if(file_exists(sbuf))
+ return strsave(sbuf);
+ break;
+ }
+ }
+ return ERL_NAME;
+}
+
+#ifdef __WIN32__
+static char*
+possibly_quote(char* arg)
+{
+ int mustQuote = NO;
+ int n = 0;
+ char* s;
+ char* narg;
+
+ if (arg == NULL) {
+ return arg;
+ }
+
+ /*
+ * Scan the string to find out if it needs quoting and return
+ * the original argument if not.
+ */
+
+ for (s = arg; *s; s++, n++) {
+ switch(*s) {
+ case ' ':
+ mustQuote = YES;
+ continue;
+ case '"':
+ mustQuote = YES;
+ n++;
+ continue;
+ case '\\':
+ if(s[1] == '"')
+ n++;
+ continue;
+ default:
+ continue;
+ }
+ }
+ if (!mustQuote) {
+ return arg;
+ }
+
+ /*
+ * Insert the quotes and put a backslash in front of every quote
+ * inside the string.
+ */
+
+ s = narg = emalloc(n+2+1);
+ for (*s++ = '"'; *arg; arg++, s++) {
+ if (*arg == '"' || (*arg == '\\' && arg[1] == '"')) {
+ *s++ = '\\';
+ }
+ *s = *arg;
+ }
+ if (s[-1] == '\\') {
+ *s++ ='\\';
+ }
+ *s++ = '"';
+ *s = '\0';
+ return narg;
+}
+#endif /* __WIN32__ */
diff --git a/erts/etc/unix/Install.src b/erts/etc/unix/Install.src
index 8be696b16f..e71308edbe 100644
--- a/erts/etc/unix/Install.src
+++ b/erts/etc/unix/Install.src
@@ -89,6 +89,7 @@ cd "$ERL_ROOT/bin"
cp -p "$ERL_ROOT/erts-%I_VSN%/bin/erl" .
cp -p "$ERL_ROOT/erts-%I_VSN%/bin/erlc" .
cp -p "$ERL_ROOT/erts-%I_VSN%/bin/dialyzer" .
+cp -p "$ERL_ROOT/erts-%I_VSN%/bin/typer" .
cp -p "$ERL_ROOT/erts-%I_VSN%/bin/ct_run" .
cp -p "$ERL_ROOT/erts-%I_VSN%/bin/escript" .
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index c689d495e6..643cfbf323 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -2871,6 +2871,81 @@ define etp-disasm
end
end
+############################################################################
+#
+# Timer Wheel
+#
+
+define etp-timer-wheel
+# Args: TimerWheel
+ if (!erts_initialized)
+ printf "System not initialized!\n"
+ else
+ set $tiw = $arg0
+ printf "Number of timers: %d\n", $tiw->nto
+ printf "Min timeout pos: %d\n", $tiw->next_timeout_pos
+ printf "\n--- Soon Wheel ---\n"
+ set $ix = $tiw->pos & etp_tw_soon_wheel_mask
+ printf "Position: %ld (%d)\n", $tiw->pos, $ix
+ printf "Min timeout position: %ld (%d)\n", $tiw->soon.min_tpos, $tiw->soon.min_tpos & etp_tw_soon_wheel_mask
+ printf "Number of timers: %d\n", $tiw->soon.nto
+ set $slots = etp_tw_soon_wheel_size
+ while $slots > 0
+ set $tmr = $tiw->w[$ix]
+ if ($tmr != (ErtsTWheelTimer *) 0x0)
+ printf "---\n"
+ printf "Slot: %d\n", $ix
+ printf "\n"
+ while 1
+ printf "- Timeout pos: %ld\n", $tmr->timeout_pos
+ printf " Pointer: (ErtsTWheelTimer *) %p\n", $tmr
+ set $tmr = $tmr->next
+ if ($tmr == $tiw->w[$ix])
+ loop_break
+ end
+ end
+ end
+ set $ix++
+ if ($ix == (etp_tw_soon_wheel_first_slot + etp_tw_soon_wheel_size))
+ set $ix = etp_tw_soon_wheel_first_slot
+ end
+ set $slots--
+ end
+ printf "\n--- Later Wheel ---\n"
+ set $ix = (($tiw->later.pos >> etp_tw_later_wheel_shift) & etp_tw_later_wheel_mask) + etp_tw_later_wheel_first_slot
+ printf "Position: %ld (%d)\n", $tiw->later.pos, $ix
+ printf "Min timeout position: %ld (%d)\n", $tiw->later.min_tpos, (($tiw->later.min_tpos >> etp_tw_later_wheel_shift) & etp_tw_later_wheel_mask) + etp_tw_later_wheel_first_slot
+ printf "Number of timers: %d\n", $tiw->later.nto
+ set $slots = etp_tw_later_wheel_size
+ set $slot_pos = $tiw->later.pos
+ while $slots > 0
+ set $tmr = $tiw->w[$ix]
+ if ($tmr != (ErtsTWheelTimer *) 0x0)
+ printf "---\n"
+ printf "Slot: %d\n", $ix
+ printf "Slot Range: [%ld, %ld]\n", $slot_pos, $slot_pos + etp_tw_later_wheel_slot_size
+ printf "Pre timeout pos: %ld\n", $slot_pos - etp_tw_later_wheel_slot_size
+ printf "\n"
+ while 1
+ printf "- Timeout pos: %ld\n", $tmr->timeout_pos
+ printf " Pointer: (ErtsTWheelTimer *) %p\n", $tmr
+ set $tmr = $tmr->next
+ if ($tmr == $tiw->w[$ix])
+ loop_break
+ end
+ end
+ end
+ set $ix++
+ if ($ix == (etp_tw_later_wheel_first_slot + etp_tw_later_wheel_size))
+ set $ix = etp_tw_later_wheel_first_slot
+ end
+ set $slot_pos = $slot_pos + etp_tw_later_wheel_slot_size
+ set $slots--
+ end
+ end
+ printf "---\n"
+end
+
document etp-disasm
%---------------------------------------------------------------------------
% etp-disasm StartI EndI
diff --git a/erts/etc/unix/to_erl.c b/erts/etc/unix/to_erl.c
index 0bd469727c..0ccd7ead3e 100644
--- a/erts/etc/unix/to_erl.c
+++ b/erts/etc/unix/to_erl.c
@@ -416,7 +416,7 @@ int main(int argc, char **argv)
if (len) {
#ifdef DEBUG
- if(write(1, buf, len));
+ (void)write(1, buf, len);
#endif
if (write_all(wfd, buf, len) != len) {
fprintf(stderr, "Error in writing to FIFO.\n");
diff --git a/erts/etc/win32/Install.c b/erts/etc/win32/Install.c
index 04522a0779..5701df35a3 100644
--- a/erts/etc/win32/Install.c
+++ b/erts/etc/win32/Install.c
@@ -49,6 +49,7 @@ int wmain(int argc, wchar_t **argv)
HANDLE module = GetModuleHandle(NULL);
wchar_t *binaries[] = { L"erl.exe", L"werl.exe", L"erlc.exe",
L"dialyzer.exe",
+ L"typer.exe",
L"escript.exe", L"ct_run.exe", NULL };
wchar_t *scripts[] = { L"start_clean.boot", L"start_sasl.boot", L"no_dot_erlang.boot", NULL };
wchar_t fromname[MAX_PATH];