aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/configure.in1
-rw-r--r--erts/doc/src/erts_alloc.xml8
-rw-r--r--erts/emulator/beam/erl_time.h30
-rw-r--r--erts/emulator/beam/erl_time_sup.c22
-rw-r--r--erts/emulator/beam/io.c1
-rw-r--r--erts/emulator/beam/sys.h3
-rw-r--r--erts/emulator/beam/time.c47
-rw-r--r--erts/emulator/sys/common/erl_check_io.c3
-rw-r--r--erts/emulator/sys/common/erl_check_io.h6
-rw-r--r--erts/emulator/sys/common/erl_poll.c2
-rw-r--r--erts/emulator/sys/common/erl_poll.h2
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h1
-rw-r--r--erts/emulator/sys/unix/sys.c4
-rw-r--r--erts/emulator/sys/vxworks/erl_vxworks_sys.h1
-rw-r--r--erts/emulator/sys/win32/erl_poll.c6
-rw-r--r--erts/emulator/sys/win32/erl_win_sys.h15
-rwxr-xr-xerts/emulator/sys/win32/sys.c2
-rw-r--r--erts/emulator/sys/win32/sys_time.c4
18 files changed, 103 insertions, 55 deletions
diff --git a/erts/configure.in b/erts/configure.in
index 4174439d76..e6c412e666 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1589,6 +1589,7 @@ AC_CHECK_SIZEOF(void *)
AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF(size_t)
AC_CHECK_SIZEOF(off_t)
+AC_CHECK_SIZEOF(time_t)
BITS64=
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 3b5ee5391c..8378e7c676 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -436,10 +436,10 @@
in "the <c>alloc_util</c> framework" section.</item>
<tag><marker id="M_t"><c><![CDATA[+M<S>t true|false]]></c></marker></tag>
<item>
- Multiple, thread specific instances of the allocator.
+ <p>Multiple, thread specific instances of the allocator.
This option will only have any effect on the runtime system
with SMP support. Default behaviour on the runtime system with
- SMP support:
+ SMP support:</p>
<taglist>
<tag><c>ll_alloc</c></tag>
<item><c>1</c> instance.</item>
@@ -448,9 +448,9 @@
a lock-free instance of its own and other threads will use
a common instance.</item>
</taglist>
- It was previously (before ERTS version 5.9) possible to configure
+ <p>It was previously (before ERTS version 5.9) possible to configure
a smaller amount of thread specific instances than schedulers.
- This is, however, not possible any more.
+ This is, however, not possible any more.</p>
</item>
</taglist>
<p>Currently the following flags are available for configuration of
diff --git a/erts/emulator/beam/erl_time.h b/erts/emulator/beam/erl_time.h
index 7a09d30ff6..6c6e193818 100644
--- a/erts/emulator/beam/erl_time.h
+++ b/erts/emulator/beam/erl_time.h
@@ -20,7 +20,11 @@
#ifndef ERL_TIME_H__
#define ERL_TIME_H__
-extern erts_smp_atomic_t do_time; /* set at clock interrupt */
+#define ERTS_SHORT_TIME_T_MAX ERTS_AINT32_T_MAX
+#define ERTS_SHORT_TIME_T_MIN ERTS_AINT32_T_MIN
+typedef erts_aint32_t erts_short_time_t;
+
+extern erts_smp_atomic32_t do_time; /* set at clock interrupt */
extern SysTimeval erts_first_emu_time;
/*
@@ -71,22 +75,32 @@ void erts_cancel_smp_ptimer(ErtsSmpPTimer *ptimer);
void erts_init_time(void);
void erts_set_timer(ErlTimer*, ErlTimeoutProc, ErlCancelProc, void*, Uint);
void erts_cancel_timer(ErlTimer*);
-void erts_bump_timer(erts_aint_t);
+void erts_bump_timer(erts_short_time_t);
Uint erts_timer_wheel_memory_size(void);
Uint erts_time_left(ErlTimer *);
-erts_aint_t erts_next_time(void);
+erts_short_time_t erts_next_time(void);
#ifdef DEBUG
void erts_p_slpq(void);
#endif
-ERTS_GLB_INLINE erts_aint_t erts_do_time_read_and_reset(void);
-ERTS_GLB_INLINE void erts_do_time_add(long);
+ERTS_GLB_INLINE erts_short_time_t erts_do_time_read_and_reset(void);
+ERTS_GLB_INLINE void erts_do_time_add(erts_short_time_t);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
-ERTS_GLB_INLINE erts_aint_t erts_do_time_read_and_reset(void) { return erts_smp_atomic_xchg_acqb(&do_time, 0L); }
-ERTS_GLB_INLINE void erts_do_time_add(long elapsed) { erts_smp_atomic_add_relb(&do_time, elapsed); }
+ERTS_GLB_INLINE erts_short_time_t erts_do_time_read_and_reset(void)
+{
+ erts_short_time_t time = erts_smp_atomic32_xchg_acqb(&do_time, 0);
+ if (time < 0)
+ erl_exit(ERTS_ABORT_EXIT, "Internal time management error\n");
+ return time;
+}
+
+ERTS_GLB_INLINE void erts_do_time_add(erts_short_time_t elapsed)
+{
+ erts_smp_atomic32_add_relb(&do_time, elapsed);
+}
#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
@@ -105,7 +119,7 @@ void erts_get_now_cpu(Uint* megasec, Uint* sec, Uint* microsec);
#endif
void erts_get_timeval(SysTimeval *tv);
-long erts_get_time(void);
+erts_time_t erts_get_time(void);
void erts_get_emu_time(SysTimeval *);
ERTS_GLB_INLINE int erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p);
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index 4d1e1c8a59..b319288f7d 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -371,7 +371,7 @@ static void init_erts_deliver_time(const SysTimeval *inittv)
static void do_erts_deliver_time(const SysTimeval *current)
{
SysTimeval cur_time;
- long elapsed;
+ erts_time_t elapsed;
/* calculate and deliver appropriate number of ticks */
cur_time = *current;
@@ -385,7 +385,10 @@ static void do_erts_deliver_time(const SysTimeval *current)
this by simply pretend as if the time stood still. :) */
if (elapsed > 0) {
- erts_do_time_add(elapsed);
+
+ ASSERT(elapsed < ((erts_time_t) ERTS_SHORT_TIME_T_MAX));
+
+ erts_do_time_add((erts_short_time_t) elapsed);
last_delivered = cur_time;
}
}
@@ -592,10 +595,10 @@ static const int mdays[14] = {0, 31, 28, 31, 30, 31, 30,
* greater of equal to 1600 , and month [1-12] and day [1-31]
* are within range. Otherwise it returns -1.
*/
-static int long gregday(int year, int month, int day)
+static time_t gregday(int year, int month, int day)
{
- int long ndays = 0;
- int gyear, pyear, m;
+ time_t ndays = 0;
+ time_t gyear, pyear, m;
/* number of days in previous years */
gyear = year - 1600;
@@ -798,13 +801,14 @@ void erts_deliver_time(void) {
void erts_time_remaining(SysTimeval *rem_time)
{
- int ticks;
+ erts_time_t ticks;
SysTimeval cur_time;
- long elapsed;
+ erts_time_t elapsed;
/* erts_next_time() returns no of ticks to next timeout or -1 if none */
- if ((ticks = erts_next_time()) == -1) {
+ ticks = (erts_time_t) erts_next_time();
+ if (ticks == (erts_time_t) -1) {
/* timer queue empty */
/* this will cause at most 100000000 ticks */
rem_time->tv_sec = 100000;
@@ -839,7 +843,7 @@ void erts_get_timeval(SysTimeval *tv)
erts_smp_mtx_unlock(&erts_timeofday_mtx);
}
-long
+erts_time_t
erts_get_time(void)
{
SysTimeval sys_tv;
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index c2cc03509e..759621d3c2 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -644,7 +644,6 @@ erts_open_driver(erts_driver_t* driver, /* Pointer to driver. */
name, opts);
erts_unblock_fpe(fpe_was_unmasked);
port->caller = NIL;
- erts_unblock_fpe(fpe_was_unmasked);
if (IS_TRACED_FL(port, F_TRACE_SCHED_PORTS)) {
trace_sched_ports_where(port, am_out, am_start);
}
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index d8cd22a177..efc6dd2c6b 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -636,10 +636,11 @@ extern char *erts_sys_ddll_error(int code);
/*
* System interfaces for startup.
*/
+#include "erl_time.h"
void erts_sys_schedule_interrupt(int set);
#ifdef ERTS_SMP
-void erts_sys_schedule_interrupt_timed(int set, long msec);
+void erts_sys_schedule_interrupt_timed(int set, erts_short_time_t msec);
void erts_sys_main_thread(void);
#endif
diff --git a/erts/emulator/beam/time.c b/erts/emulator/beam/time.c
index db9a24e0a3..932d157cd8 100644
--- a/erts/emulator/beam/time.c
+++ b/erts/emulator/beam/time.c
@@ -107,20 +107,31 @@ static ErlTimer *tiw_min_ptr;
/* Actual interval time chosen by sys_init_time() */
static int itime; /* Constant after init */
-erts_smp_atomic_t do_time; /* set at clock interrupt */
-static ERTS_INLINE erts_aint_t do_time_read(void) { return erts_smp_atomic_read_acqb(&do_time); }
-static ERTS_INLINE erts_aint_t do_time_update(void) { return do_time_read(); }
-static ERTS_INLINE void do_time_init(void) { erts_smp_atomic_init_nob(&do_time, 0L); }
+erts_smp_atomic32_t do_time; /* set at clock interrupt */
+static ERTS_INLINE erts_short_time_t do_time_read(void)
+{
+ return erts_smp_atomic32_read_acqb(&do_time);
+}
+
+static ERTS_INLINE erts_short_time_t do_time_update(void)
+{
+ return do_time_read();
+}
+
+static ERTS_INLINE void do_time_init(void)
+{
+ erts_smp_atomic32_init_nob(&do_time, 0);
+}
/* get the time (in units of itime) to the next timeout,
or -1 if there are no timeouts */
-static erts_aint_t next_time_internal(void) /* PRE: tiw_lock taken by caller */
+static erts_short_time_t next_time_internal(void) /* PRE: tiw_lock taken by caller */
{
int i, tm, nto;
- unsigned int min;
+ Uint32 min;
ErlTimer* p;
- erts_aint_t dt;
+ erts_short_time_t dt;
if (tiw_nto == 0)
return -1; /* no timeouts in wheel */
@@ -133,7 +144,7 @@ static erts_aint_t next_time_internal(void) /* PRE: tiw_lock taken by caller */
/* start going through wheel to find next timeout */
tm = nto = 0;
- min = (unsigned int) -1; /* max unsigned int */
+ min = (Uint32) -1; /* max Uint32 */
i = tiw_pos;
do {
p = tiw[i];
@@ -162,7 +173,11 @@ static erts_aint_t next_time_internal(void) /* PRE: tiw_lock taken by caller */
i = (i + 1) % TIW_SIZE;
} while (i != tiw_pos);
dt = do_time_read();
- return ((min >= dt) ? (min - dt) : 0);
+ if (min <= (Uint32) dt)
+ return 0;
+ if ((min - (Uint32) dt) > (Uint32) ERTS_SHORT_TIME_T_MAX)
+ return ERTS_SHORT_TIME_T_MAX;
+ return (erts_short_time_t) (min - (Uint32) dt);
}
static void remove_timer(ErlTimer *p) {
@@ -191,9 +206,9 @@ static void remove_timer(ErlTimer *p) {
}
/* Private export to erl_time_sup.c */
-erts_aint_t erts_next_time(void)
+erts_short_time_t erts_next_time(void)
{
- erts_aint_t ret;
+ erts_short_time_t ret;
erts_smp_mtx_lock(&tiw_lock);
(void)do_time_update();
@@ -202,7 +217,7 @@ erts_aint_t erts_next_time(void)
return ret;
}
-static ERTS_INLINE void bump_timer_internal(erts_aint_t dt) /* PRE: tiw_lock is write-locked */
+static ERTS_INLINE void bump_timer_internal(erts_short_time_t dt) /* PRE: tiw_lock is write-locked */
{
Uint keep_pos;
Uint count;
@@ -273,7 +288,7 @@ static ERTS_INLINE void bump_timer_internal(erts_aint_t dt) /* PRE: tiw_lock is
}
}
-void erts_bump_timer(erts_aint_t dt) /* dt is value from do_time */
+void erts_bump_timer(erts_short_time_t dt) /* dt is value from do_time */
{
erts_smp_mtx_lock(&tiw_lock);
bump_timer_internal(dt);
@@ -378,8 +393,8 @@ erts_set_timer(ErlTimer* p, ErlTimeoutProc timeout, ErlCancelProc cancel,
insert_timer(p, t);
erts_smp_mtx_unlock(&tiw_lock);
#if defined(ERTS_SMP)
- if (t <= (Uint) LONG_MAX)
- erts_sys_schedule_interrupt_timed(1, (long) t);
+ if (t <= (Uint) ERTS_SHORT_TIME_T_MAX)
+ erts_sys_schedule_interrupt_timed(1, (erts_short_time_t) t);
#endif
}
@@ -419,7 +434,7 @@ Uint
erts_time_left(ErlTimer *p)
{
Uint left;
- erts_aint_t dt;
+ erts_short_time_t dt;
erts_smp_mtx_lock(&tiw_lock);
diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c
index 2005450c36..23a4bf1b04 100644
--- a/erts/emulator/sys/common/erl_check_io.c
+++ b/erts/emulator/sys/common/erl_check_io.c
@@ -1134,7 +1134,8 @@ ERTS_CIO_EXPORT(erts_check_io_interrupt)(int set)
}
void
-ERTS_CIO_EXPORT(erts_check_io_interrupt_timed)(int set, long msec)
+ERTS_CIO_EXPORT(erts_check_io_interrupt_timed)(int set,
+ erts_short_time_t msec)
{
ERTS_CIO_POLL_INTR_TMD(pollset.ps, set, msec);
}
diff --git a/erts/emulator/sys/common/erl_check_io.h b/erts/emulator/sys/common/erl_check_io.h
index 7cc1658062..edab7947ba 100644
--- a/erts/emulator/sys/common/erl_check_io.h
+++ b/erts/emulator/sys/common/erl_check_io.h
@@ -46,8 +46,8 @@ void erts_check_io_async_sig_interrupt_nkp(void);
#endif
void erts_check_io_interrupt_kp(int);
void erts_check_io_interrupt_nkp(int);
-void erts_check_io_interrupt_timed_kp(int, long);
-void erts_check_io_interrupt_timed_nkp(int, long);
+void erts_check_io_interrupt_timed_kp(int, erts_short_time_t);
+void erts_check_io_interrupt_timed_nkp(int, erts_short_time_t);
void erts_check_io_kp(int);
void erts_check_io_nkp(int);
void erts_init_check_io_kp(void);
@@ -64,7 +64,7 @@ int erts_check_io_max_files(void);
void erts_check_io_async_sig_interrupt(void);
#endif
void erts_check_io_interrupt(int);
-void erts_check_io_interrupt_timed(int, long);
+void erts_check_io_interrupt_timed(int, erts_short_time_t);
void erts_check_io(int);
void erts_init_check_io(void);
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index 80db2055a2..b6cb271f17 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -2171,7 +2171,7 @@ ERTS_POLL_EXPORT(erts_poll_async_sig_interrupt)(ErtsPollSet ps)
void
ERTS_POLL_EXPORT(erts_poll_interrupt_timed)(ErtsPollSet ps,
int set,
- long msec)
+ erts_short_time_t msec)
{
#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT || defined(ERTS_SMP)
if (!set)
diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h
index e0296c6a33..8dde619105 100644
--- a/erts/emulator/sys/common/erl_poll.h
+++ b/erts/emulator/sys/common/erl_poll.h
@@ -223,7 +223,7 @@ void ERTS_POLL_EXPORT(erts_poll_interrupt)(ErtsPollSet,
int);
void ERTS_POLL_EXPORT(erts_poll_interrupt_timed)(ErtsPollSet,
int,
- long);
+ erts_short_time_t);
ErtsPollEvents ERTS_POLL_EXPORT(erts_poll_control)(ErtsPollSet,
ErtsSysFdType,
ErtsPollEvents,
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index 9a5ed9f5bc..c8fcec8547 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -146,6 +146,7 @@ typedef void *GETENV_STATE;
/*
** For the erl_timer_sup module.
*/
+typedef time_t erts_time_t;
typedef struct timeval SysTimeval;
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index c6b63350e5..52477467b3 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -265,7 +265,7 @@ struct {
int (*event)(ErlDrvPort, ErlDrvEvent, ErlDrvEventData);
void (*check_io_as_interrupt)(void);
void (*check_io_interrupt)(int);
- void (*check_io_interrupt_tmd)(int, long);
+ void (*check_io_interrupt_tmd)(int, erts_short_time_t);
void (*check_io)(int);
Uint (*size)(void);
Eterm (*info)(void *);
@@ -371,7 +371,7 @@ erts_sys_schedule_interrupt(int set)
#ifdef ERTS_SMP
void
-erts_sys_schedule_interrupt_timed(int set, long msec)
+erts_sys_schedule_interrupt_timed(int set, erts_short_time_t msec)
{
ERTS_CHK_IO_INTR_TMD(set, msec);
}
diff --git a/erts/emulator/sys/vxworks/erl_vxworks_sys.h b/erts/emulator/sys/vxworks/erl_vxworks_sys.h
index ae46403600..69d9ca3478 100644
--- a/erts/emulator/sys/vxworks/erl_vxworks_sys.h
+++ b/erts/emulator/sys/vxworks/erl_vxworks_sys.h
@@ -158,6 +158,7 @@ typedef struct _vxworks_tms {
typedef long long SysHrTime;
+typedef time_t erts_time_t;
typedef struct timeval SysTimeval;
extern int sys_init_hrtime(void);
diff --git a/erts/emulator/sys/win32/erl_poll.c b/erts/emulator/sys/win32/erl_poll.c
index ab4ef05118..7a1d129cd5 100644
--- a/erts/emulator/sys/win32/erl_poll.c
+++ b/erts/emulator/sys/win32/erl_poll.c
@@ -442,8 +442,8 @@ poll_wait_timeout(ErtsPollSet ps, SysTimeval *tvp)
if (erts_atomic32_read_nob(&ps->wakeup_state) != ERTS_POLL_NOT_WOKEN)
return (DWORD) 0;
- if (timeout > ERTS_AINT32_T_MAX) /* Also prevents DWORD overflow */
- timeout = ERTS_AINT32_T_MAX;
+ if (timeout > ((time_t) ERTS_AINT32_T_MAX))
+ timeout = ERTS_AINT32_T_MAX; /* Also prevents DWORD overflow */
erts_smp_atomic32_set_relb(&ps->timeout, (erts_aint32_t) timeout);
return (DWORD) timeout;
@@ -1012,7 +1012,7 @@ void erts_poll_interrupt(ErtsPollSet ps, int set /* bool */)
void erts_poll_interrupt_timed(ErtsPollSet ps,
int set /* bool */,
- long msec)
+ erts_short_time_t msec)
{
HARDTRACEF(("In erts_poll_interrupt_timed(%d,%ld)",set,msec));
if (!set)
diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h
index d770691026..cf3fb4446f 100644
--- a/erts/emulator/sys/win32/erl_win_sys.h
+++ b/erts/emulator/sys/win32/erl_win_sys.h
@@ -117,9 +117,20 @@ int erts_check_io_debug(void);
#define SYS_CLK_TCK 1000
#define SYS_CLOCK_RESOLUTION 1
+#if SIZEOF_TIME_T != 8
+# error "Unexpected sizeof(time_t)"
+#endif
+
+/*
+ * gcc uses a 4 byte time_t and vc++ uses an 8 byte time_t.
+ * Types seen in beam_emu.c *need* to have the same size
+ * as in the rest of the system...
+ */
+typedef __int64 erts_time_t;
+
typedef struct {
- long tv_sec;
- long tv_usec;
+ erts_time_t tv_sec;
+ erts_time_t tv_usec;
} SysTimeval;
typedef struct {
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index a49fa8ca34..a701747b78 100755
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -3290,7 +3290,7 @@ erts_sys_schedule_interrupt(int set)
#ifdef ERTS_SMP
void
-erts_sys_schedule_interrupt_timed(int set, long msec)
+erts_sys_schedule_interrupt_timed(int set, erts_short_time_t msec)
{
erts_check_io_interrupt_timed(set, msec);
}
diff --git a/erts/emulator/sys/win32/sys_time.c b/erts/emulator/sys/win32/sys_time.c
index fc868507cb..e5b9513edc 100644
--- a/erts/emulator/sys/win32/sys_time.c
+++ b/erts/emulator/sys/win32/sys_time.c
@@ -55,8 +55,8 @@ sys_gettimeofday(SysTimeval *tv)
GetSystemTime(&t);
SystemTimeToFileTime(&t, &ft);
memcpy(&lft, &ft, sizeof(lft));
- tv->tv_usec = (long) ((lft / LL_LITERAL(10)) % LL_LITERAL(1000000));
- tv->tv_sec = (long) ((lft / LL_LITERAL(10000000)) - EPOCH_JULIAN_DIFF);
+ tv->tv_usec = (erts_time_t) ((lft / LL_LITERAL(10)) % LL_LITERAL(1000000));
+ tv->tv_sec = (erts_time_t) ((lft / LL_LITERAL(10000000)) - EPOCH_JULIAN_DIFF);
}
SysHrTime