aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/aclocal.m491
-rw-r--r--erts/doc/src/notes.xml76
-rw-r--r--erts/emulator/beam/erl_time.h6
-rw-r--r--erts/emulator/beam/erl_time_sup.c85
4 files changed, 185 insertions, 73 deletions
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index bf48c832b3..11c311f2c0 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -726,9 +726,15 @@ esac
AC_DEFUN(ERL_MONOTONIC_CLOCK,
[
- default_resolution_clock_gettime_monotonic="CLOCK_HIGHRES CLOCK_BOOTTIME CLOCK_MONOTONIC"
- low_resolution_clock_gettime_monotonic="CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST"
- high_resolution_clock_gettime_monotonic="CLOCK_MONOTONIC_PRECISE"
+ if test "$3" = "yes"; then
+ default_resolution_clock_gettime_monotonic="CLOCK_HIGHRES CLOCK_BOOTTIME CLOCK_MONOTONIC"
+ low_resolution_clock_gettime_monotonic="CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST"
+ high_resolution_clock_gettime_monotonic="CLOCK_MONOTONIC_PRECISE"
+ else
+ default_resolution_clock_gettime_monotonic="CLOCK_HIGHRES CLOCK_UPTIME CLOCK_MONOTONIC"
+ low_resolution_clock_gettime_monotonic="CLOCK_MONOTONIC_COARSE CLOCK_UPTIME_FAST"
+ high_resolution_clock_gettime_monotonic="CLOCK_UPTIME_PRECISE"
+ fi
case "$1" in
high_resolution)
@@ -1466,7 +1472,7 @@ AC_ARG_WITH(with_sparc_memory_order,
LM_CHECK_THR_LIB
ERL_INTERNAL_LIBS
-ERL_MONOTONIC_CLOCK(high_resolution)
+ERL_MONOTONIC_CLOCK(high_resolution, undefined, no)
case $erl_monotonic_clock_func in
clock_gettime)
@@ -2202,7 +2208,7 @@ AC_DEFUN(ERL_TIME_CORRECTION,
AC_ARG_WITH(clock-resolution,
AS_HELP_STRING([--with-clock-resolution=high|low|default],
- [specify wanted clock resolution)]))
+ [specify wanted clock resolution]))
AC_ARG_WITH(clock-gettime-realtime-id,
AS_HELP_STRING([--with-clock-gettime-realtime-id=CLOCKID],
@@ -2212,6 +2218,24 @@ AC_ARG_WITH(clock-gettime-monotonic-id,
AS_HELP_STRING([--with-clock-gettime-monotonic-id=CLOCKID],
[specify clock id to use with clock_gettime() for monotonic time)]))
+AC_ARG_ENABLE(prefer-elapsed-monotonic-time-during-suspend,
+ AS_HELP_STRING([--enable-prefer-elapsed-monotonic-time-during-suspend],
+ [Prefer an OS monotonic time source with elapsed time during suspend])
+ AS_HELP_STRING([--disable-prefer-elapsed-monotonic-time-during-suspend],
+ [Do not prefer an OS monotonic time source with elapsed time during suspend]),
+[ case "$enableval" in
+ yes) prefer_elapsed_monotonic_time_during_suspend=yes ;;
+ *) prefer_elapsed_monotonic_time_during_suspend=no ;;
+ esac ], prefer_elapsed_monotonic_time_during_suspend=no)
+
+AC_ARG_ENABLE(gettimeofday-as-os-system-time,
+ AS_HELP_STRING([--enable-gettimeofday-as-os-system-time],
+ [Force usage of gettimeofday() for OS system time]),
+[ case "$enableval" in
+ yes) force_gettimeofday_os_system_time=yes ;;
+ *) force_gettimeofday_os_system_time=no ;;
+ esac ], force_gettimeofday_os_system_time=no)
+
case "$with_clock_resolution" in
""|no|yes)
with_clock_resolution=default;;
@@ -2222,6 +2246,17 @@ case "$with_clock_resolution" in
;;
esac
+if test "$force_gettimeofday_os_system_time" = "yes"; then
+
+ AC_CHECK_FUNCS([gettimeofday])
+ if test "$ac_cv_func_gettimeofday" = "yes"; then
+ AC_DEFINE(OS_SYSTEM_TIME_GETTIMEOFDAY, [1], [Define if you want to implement erts_os_system_time() using gettimeofday()])
+ else
+ AC_MSG_ERROR([No gettimeofday() available])
+ fi
+
+else # $force_gettimeofday_os_system_time != yes
+
case "$with_clock_gettime_realtime_id" in
""|no)
with_clock_gettime_realtime_id=no
@@ -2239,23 +2274,6 @@ case "$with_clock_gettime_realtime_id" in
;;
esac
-case "$with_clock_gettime_monotonic_id" in
- ""|no)
- with_clock_gettime_monotonic_id=no
- ;;
- CLOCK_*CPUTIME*)
- AC_MSG_ERROR([Invalid clock_gettime() monotonic clock id: Refusing to use the cputime clock id $with_clock_gettime_monotonic_id as monotonic clock id])
- ;;
- CLOCK_REALTIME*|CLOCK_TAI*)
- AC_MSG_ERROR([Invalid clock_gettime() monotonic clock id: Refusing to use the realtime clock id $with_clock_gettime_monotonic_id as monotonic clock id])
- ;;
- CLOCK_*)
- ;;
- *)
- AC_MSG_ERROR([Invalid clock_gettime() clock id: $with_clock_gettime_monotonic_id])
- ;;
-esac
-
case "$with_clock_resolution-$with_clock_gettime_realtime_id" in
high-no)
ERL_WALL_CLOCK(high_resolution);;
@@ -2296,15 +2314,34 @@ if test "x$erl_wall_clock_id" != "x"; then
AC_DEFINE_UNQUOTED(WALL_CLOCK_ID, [$erl_wall_clock_id], [Define to wall clock id to use])
fi
+fi # $force_gettimeofday_os_system_time != yes
+
+case "$with_clock_gettime_monotonic_id" in
+ ""|no)
+ with_clock_gettime_monotonic_id=no
+ ;;
+ CLOCK_*CPUTIME*)
+ AC_MSG_ERROR([Invalid clock_gettime() monotonic clock id: Refusing to use the cputime clock id $with_clock_gettime_monotonic_id as monotonic clock id])
+ ;;
+ CLOCK_REALTIME*|CLOCK_TAI*)
+ AC_MSG_ERROR([Invalid clock_gettime() monotonic clock id: Refusing to use the realtime clock id $with_clock_gettime_monotonic_id as monotonic clock id])
+ ;;
+ CLOCK_*)
+ ;;
+ *)
+ AC_MSG_ERROR([Invalid clock_gettime() clock id: $with_clock_gettime_monotonic_id])
+ ;;
+esac
+
case "$with_clock_resolution-$with_clock_gettime_monotonic_id" in
high-no)
- ERL_MONOTONIC_CLOCK(high_resolution);;
+ ERL_MONOTONIC_CLOCK(high_resolution, undefined, $prefer_elapsed_monotonic_time_during_suspend);;
low-no)
- ERL_MONOTONIC_CLOCK(low_resolution);;
+ ERL_MONOTONIC_CLOCK(low_resolution, undefined, $prefer_elapsed_monotonic_time_during_suspend);;
default-no)
- ERL_MONOTONIC_CLOCK(default_resolution);;
+ ERL_MONOTONIC_CLOCK(default_resolution, undefined, $prefer_elapsed_monotonic_time_during_suspend);;
*)
- ERL_MONOTONIC_CLOCK(custom_resolution, $with_clock_gettime_monotonic_id);;
+ ERL_MONOTONIC_CLOCK(custom_resolution, $with_clock_gettime_monotonic_id, $prefer_elapsed_monotonic_time_during_suspend);;
esac
case "$erl_monotonic_clock_func-$erl_monotonic_clock_id-$with_clock_gettime_monotonic_id" in
@@ -2352,7 +2389,7 @@ if test $erl_cv_clock_gettime_monotonic_raw = yes; then
AC_DEFINE(HAVE_CLOCK_GETTIME_MONOTONIC_RAW, [1], [Define if you have clock_gettime(CLOCK_MONOTONIC_RAW, _)])
fi
-ERL_MONOTONIC_CLOCK(high_resolution)
+ERL_MONOTONIC_CLOCK(high_resolution, undefined, no)
case $$erl_monotonic_clock_low_resolution-$erl_monotonic_clock_func in
no-mach_clock_get_time)
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 64de3aa622..ab6291614c 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -31,6 +31,82 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 7.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A process could end up in an inconsistent half exited
+ state in the runtime system without SMP support. This
+ could occur if the processes was traced by a port that it
+ also was linked to, and the port terminated abnormally
+ while handling a trace message for the process.</p>
+ <p>
+ This bug has always existed in the runtime system without
+ SMP support, but never in the runtime system with SMP
+ support.</p>
+ <p>
+ Own Id: OTP-12889 Aux Id: seq12885 </p>
+ </item>
+ <item>
+ <p>
+ Removed unnecessary copying of data when retrieving
+ corrected Erlang monotonic time.</p>
+ <p>
+ Own Id: OTP-12894</p>
+ </item>
+ <item>
+ <p>
+ Changed default OS monotonic clock source chosen at build
+ time. This in order to improve performance. The behavior
+ will now on most systems be that (both OS and Erlang)
+ monotonic time stops when the system is suspended.</p>
+ <p>
+ If you prefer that monotonic time elapse during suspend
+ of the machine, you can pass the command line argument
+ <c>--enable-prefer-elapsed-monotonic-time-during-suspend</c>
+ to <c>configure</c> when building Erlang/OTP. The
+ configuration stage will try to find such a clock source,
+ but might not be able to find it. Note that there might
+ be a performance penalty associated with such a clock
+ source.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12895</p>
+ </item>
+ <item>
+ <p>
+ <c>erlang:system_info(end_time)</c> returned a faulty
+ value on 32-bit architectures.</p>
+ <p>
+ Own Id: OTP-12896</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The <c>configure</c> command line argument
+ <c>--enable-gettimeofday-as-os-system-time</c> has been
+ added which force usage of <c>gettimeofday()</c> for OS
+ system time. This will improve performance of
+ <c>os:system_time()</c> and <c>os:timestamp()</c> on
+ MacOS X, at the expense of worse accuracy, resolution and
+ precision of Erlang monotonic time, Erlang system time,
+ and OS system time.</p>
+ <p>
+ Own Id: OTP-12892</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 7.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/erl_time.h b/erts/emulator/beam/erl_time.h
index 36a3d52264..43e543e035 100644
--- a/erts/emulator/beam/erl_time.h
+++ b/erts/emulator/beam/erl_time.h
@@ -345,8 +345,10 @@ erts_time_unit_conversion(Uint64 value,
#endif /* !ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT */
#define ERTS_MONOTONIC_TIME_END_EXTERNAL \
- (ERTS_MONOTONIC_TIME_START_EXTERNAL \
- + (ERTS_MONOTONIC_END - ERTS_MONOTONIC_BEGIN))
+ (ERTS_MONOTONIC_TIME_START_EXTERNAL < 0 \
+ ? (ERTS_MONOTONIC_TIME_START_EXTERNAL \
+ + (ERTS_MONOTONIC_END - ERTS_MONOTONIC_BEGIN)) \
+ : (ERTS_MONOTONIC_END - ERTS_MONOTONIC_TIME_START_EXTERNAL))
#define ERTS_MSEC_TO_CLKTCKS__(MON) \
((MON) * (ERTS_CLKTCK_RESOLUTION/1000))
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index 7f8f560681..7327e0b48c 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -124,7 +124,11 @@ typedef struct {
typedef struct {
ErtsMonotonicCorrectionInstance prev;
- ErtsMonotonicCorrectionInstance curr;
+ ErtsMonotonicCorrectionInstance curr;
+} ErtsMonotonicCorrectionInstances;
+
+typedef struct {
+ ErtsMonotonicCorrectionInstances insts;
ErtsMonotonicDriftData drift;
ErtsMonotonicTime last_check;
int short_check_interval;
@@ -272,27 +276,24 @@ static ERTS_INLINE ErtsMonotonicTime
read_corrected_time(int os_drift_corrected)
{
ErtsMonotonicTime os_mtime;
- ErtsMonotonicCorrectionData cdata;
- ErtsMonotonicCorrectionInstance *cip;
+ ErtsMonotonicCorrectionInstance ci;
erts_smp_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx);
os_mtime = erts_os_monotonic_time();
- cdata = time_sup.inf.c.parmon.cdata;
-
- erts_smp_rwmtx_runlock(&time_sup.inf.c.parmon.rwmtx);
-
- if (os_mtime >= cdata.curr.os_mtime)
- cip = &cdata.curr;
+ if (os_mtime >= time_sup.inf.c.parmon.cdata.insts.curr.os_mtime)
+ ci = time_sup.inf.c.parmon.cdata.insts.curr;
else {
- if (os_mtime < cdata.prev.os_mtime)
+ if (os_mtime < time_sup.inf.c.parmon.cdata.insts.prev.os_mtime)
erl_exit(ERTS_ABORT_EXIT,
"OS monotonic time stepped backwards\n");
- cip = &cdata.prev;
+ ci = time_sup.inf.c.parmon.cdata.insts.prev;
}
- return calc_corrected_erl_mtime(os_mtime, cip, NULL,
+ erts_smp_rwmtx_runlock(&time_sup.inf.c.parmon.rwmtx);
+
+ return calc_corrected_erl_mtime(os_mtime, &ci, NULL,
os_drift_corrected);
}
@@ -360,9 +361,8 @@ check_time_correction(void *vesdp)
{
int init_drift_adj = !vesdp;
ErtsSchedulerData *esdp = (ErtsSchedulerData *) vesdp;
- ErtsMonotonicCorrectionData cdata;
ErtsMonotonicCorrection new_correction;
- ErtsMonotonicCorrectionInstance *cip;
+ ErtsMonotonicCorrectionInstance ci;
ErtsMonotonicTime mdiff, sdiff, os_mtime, erl_mtime, os_stime,
erl_stime, time_offset, timeout_pos;
Uint timeout;
@@ -373,16 +373,15 @@ check_time_correction(void *vesdp)
erts_os_times(&os_mtime, &os_stime);
- cdata = time_sup.inf.c.parmon.cdata;
+ ci = time_sup.inf.c.parmon.cdata.insts.curr;
erts_smp_rwmtx_runlock(&time_sup.inf.c.parmon.rwmtx);
- if (os_mtime < cdata.curr.os_mtime)
+ if (os_mtime < ci.os_mtime)
erl_exit(ERTS_ABORT_EXIT,
"OS monotonic time stepped backwards\n");
- cip = &cdata.curr;
- erl_mtime = calc_corrected_erl_mtime(os_mtime, cip, &mdiff,
+ erl_mtime = calc_corrected_erl_mtime(os_mtime, &ci, &mdiff,
os_drift_corrected);
time_offset = get_time_offset();
erl_stime = erl_mtime + time_offset;
@@ -397,7 +396,7 @@ check_time_correction(void *vesdp)
time_sup.inf.c.shadow_offset = 0;
}
- new_correction = cip->correction;
+ new_correction = ci.correction;
if (time_sup.r.o.warp_mode == ERTS_MULTI_TIME_WARP_MODE
&& (sdiff < -2*time_sup.r.o.adj.small_diff
@@ -408,7 +407,7 @@ check_time_correction(void *vesdp)
set_time_offset(time_offset);
schedule_send_time_offset_changed_notifications(time_offset);
begin_short_intervals = 1;
- if (cdata.curr.correction.error != 0) {
+ if (ci.correction.error != 0) {
set_new_correction = 1;
new_correction.error = 0;
}
@@ -425,12 +424,12 @@ check_time_correction(void *vesdp)
time_sup.inf.c.shadow_offset -= sdiff;
sdiff = 0;
begin_short_intervals = 1;
- if (cdata.curr.correction.error != 0) {
+ if (ci.correction.error != 0) {
set_new_correction = 1;
new_correction.error = 0;
}
}
- else if (cdata.curr.correction.error == 0) {
+ else if (ci.correction.error == 0) {
if (sdiff < -time_sup.r.o.adj.small_diff) {
set_new_correction = 1;
if (sdiff < -time_sup.r.o.adj.large_diff)
@@ -446,9 +445,9 @@ check_time_correction(void *vesdp)
new_correction.error = -ERTS_TCORR_ERR_SMALL_ADJ;
}
}
- else if (cdata.curr.correction.error > 0) {
+ else if (ci.correction.error > 0) {
if (sdiff < 0) {
- if (cdata.curr.correction.error != ERTS_TCORR_ERR_LARGE_ADJ
+ if (ci.correction.error != ERTS_TCORR_ERR_LARGE_ADJ
&& sdiff < -time_sup.r.o.adj.large_diff) {
new_correction.error = ERTS_TCORR_ERR_LARGE_ADJ;
set_new_correction = 1;
@@ -466,9 +465,9 @@ check_time_correction(void *vesdp)
new_correction.error = 0;
}
}
- else /* if (cdata.curr.correction.error < 0) */ {
+ else /* if (ci.correction.error < 0) */ {
if (0 < sdiff) {
- if (cdata.curr.correction.error != -ERTS_TCORR_ERR_LARGE_ADJ
+ if (ci.correction.error != -ERTS_TCORR_ERR_LARGE_ADJ
&& time_sup.r.o.adj.large_diff < sdiff) {
new_correction.error = -ERTS_TCORR_ERR_LARGE_ADJ;
set_new_correction = 1;
@@ -631,8 +630,8 @@ check_time_correction(void *vesdp)
#ifdef ERTS_TIME_CORRECTION_PRINT
print_correction(set_new_correction,
sdiff,
- cip->correction.error,
- cip->correction.drift,
+ ci.correction.error,
+ ci.correction.drift,
new_correction.error,
new_correction.drift,
timeout);
@@ -644,7 +643,7 @@ check_time_correction(void *vesdp)
os_mtime = erts_os_monotonic_time();
/* Save previous correction instance */
- time_sup.inf.c.parmon.cdata.prev = *cip;
+ time_sup.inf.c.parmon.cdata.insts.prev = ci;
/*
* Current correction instance begin when
@@ -657,15 +656,15 @@ check_time_correction(void *vesdp)
* next OS monotonic time using previous
* correction.
*/
- erl_mtime = calc_corrected_erl_mtime(os_mtime, cip, NULL,
+ erl_mtime = calc_corrected_erl_mtime(os_mtime, &ci, NULL,
os_drift_corrected);
/*
* Save new current correction instance.
*/
- time_sup.inf.c.parmon.cdata.curr.erl_mtime = erl_mtime;
- time_sup.inf.c.parmon.cdata.curr.os_mtime = os_mtime;
- time_sup.inf.c.parmon.cdata.curr.correction = new_correction;
+ time_sup.inf.c.parmon.cdata.insts.curr.erl_mtime = erl_mtime;
+ time_sup.inf.c.parmon.cdata.insts.curr.os_mtime = os_mtime;
+ time_sup.inf.c.parmon.cdata.insts.curr.correction = new_correction;
erts_smp_rwmtx_rwunlock(&time_sup.inf.c.parmon.rwmtx);
}
@@ -784,24 +783,22 @@ static ErtsMonotonicTime
finalize_corrected_time_offset(ErtsSystemTime *stimep)
{
ErtsMonotonicTime os_mtime;
- ErtsMonotonicCorrectionData cdata;
- ErtsMonotonicCorrectionInstance *cip;
+ ErtsMonotonicCorrectionInstance ci;
int os_drift_corrected = time_sup.r.o.os_corrected_monotonic_time;
erts_smp_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx);
erts_os_times(&os_mtime, stimep);
- cdata = time_sup.inf.c.parmon.cdata;
+ ci = time_sup.inf.c.parmon.cdata.insts.curr;
erts_smp_rwmtx_runlock(&time_sup.inf.c.parmon.rwmtx);
- if (os_mtime < cdata.curr.os_mtime)
+ if (os_mtime < ci.os_mtime)
erl_exit(ERTS_ABORT_EXIT,
"OS monotonic time stepped backwards\n");
- cip = &cdata.curr;
- return calc_corrected_erl_mtime(os_mtime, cip, NULL,
+ return calc_corrected_erl_mtime(os_mtime, &ci, NULL,
os_drift_corrected);
}
@@ -1128,13 +1125,13 @@ erts_init_time_sup(int time_correction, ErtsTimeWarpMode time_warp_mode)
cdatap->drift.intervals[0].time.sys = time_sup.inf.c.sinit;
cdatap->drift.intervals[0].time.mon = time_sup.inf.c.minit;
- cdatap->curr.correction.drift = 0;
- cdatap->curr.correction.error = 0;
- cdatap->curr.erl_mtime = ERTS_MONOTONIC_BEGIN;
- cdatap->curr.os_mtime = time_sup.inf.c.minit;
+ cdatap->insts.curr.correction.drift = 0;
+ cdatap->insts.curr.correction.error = 0;
+ cdatap->insts.curr.erl_mtime = ERTS_MONOTONIC_BEGIN;
+ cdatap->insts.curr.os_mtime = time_sup.inf.c.minit;
cdatap->last_check = time_sup.inf.c.minit;
cdatap->short_check_interval = ERTS_INIT_SHORT_INTERVAL_COUNTER;
- cdatap->prev = cdatap->curr;
+ cdatap->insts.prev = cdatap->insts.curr;
if (!time_sup.r.o.os_corrected_monotonic_time)
time_sup.r.o.get_time = get_corrected_time;