diff options
author | Rickard Green <[email protected]> | 2015-03-20 21:37:15 +0100 |
---|---|---|
committer | Rickard Green <[email protected]> | 2015-03-20 21:37:15 +0100 |
commit | 6642d62c071f94d3e76254453099e2df01f7ad0e (patch) | |
tree | bb7acaeb1710092da6257ac3abd937bce67e394d /lib/kernel | |
parent | 74099492bee421c4829537bca3c4bc0c4fbec031 (diff) | |
parent | f4e3cd1c970cfc5ad54f2ed64832d05749c305d4 (diff) | |
download | otp-6642d62c071f94d3e76254453099e2df01f7ad0e.tar.gz otp-6642d62c071f94d3e76254453099e2df01f7ad0e.tar.bz2 otp-6642d62c071f94d3e76254453099e2df01f7ad0e.zip |
Merge branch 'rickard/time_api/master/OTP-11997'
* rickard/time_api/master/OTP-11997: (22 commits)
Update primary bootstrap
inets: Suppress deprecated warning on erlang:now/0
inets: Cleanup of multiple copies of functions Add inets_lib with common functions used by multiple modules
inets: Update comments
Suppress deprecated warning on erlang:now/0
Use new time API and be back-compatible in inets Remove unused functions and removed redundant test
asn1 test SUITE: Eliminate use of now/0
Disable deprecated warning on erlang:now/0 in diameter_lib
Use new time API and be back-compatible in ssh
Replace all calls to now/0 in CT with new time API functions
test_server: Replace usage of erlang:now() with usage of new API
Replace usage of erlang:now() with usage of new API
Replace usage of erlang:now() with usage of new API
Replace usage of erlang:now() with usage of new API
Replace usage of erlang:now() with usage of new API
otp_SUITE: Warn for calls to erlang:now/0
Replace usage of erlang:now() with usage of new API
Multiple timer wheels
Erlang based BIF timer implementation for scalability
Implement ethread events with timeout
...
Diffstat (limited to 'lib/kernel')
-rw-r--r-- | lib/kernel/doc/src/os.xml | 48 | ||||
-rw-r--r-- | lib/kernel/src/auth.erl | 4 | ||||
-rw-r--r-- | lib/kernel/src/dist_util.erl | 6 | ||||
-rw-r--r-- | lib/kernel/src/global.erl | 18 | ||||
-rw-r--r-- | lib/kernel/src/inet_db.erl | 3 | ||||
-rw-r--r-- | lib/kernel/src/inet_res.erl | 14 | ||||
-rw-r--r-- | lib/kernel/src/kernel.app.src | 2 | ||||
-rw-r--r-- | lib/kernel/src/os.erl | 14 | ||||
-rw-r--r-- | lib/kernel/src/pg2.erl | 11 |
9 files changed, 90 insertions, 30 deletions
diff --git a/lib/kernel/doc/src/os.xml b/lib/kernel/doc/src/os.xml index 8b85f24455..b9dbede0d3 100644 --- a/lib/kernel/doc/src/os.xml +++ b/lib/kernel/doc/src/os.xml @@ -142,14 +142,49 @@ DirOut = os:cmd("dir"), % on Win32 platform</code> </desc> </func> <func> + <name name="system_time" arity="0"/> + <fsummary>Current OS system time</fsummary> + <desc> + <p>Returns current + <seealso marker="erts:time_correction#OS_System_Time">OS system time</seealso> + in <c>native</c> + <seealso marker="erts:erlang#type_time_unit">time unit</seealso>.</p> + + <note><p>This time is <em>not</em> a monotonically increasing time.</p></note> + </desc> + </func> + <func> + <name name="system_time" arity="1"/> + <fsummary>Current OS system time</fsummary> + <desc> + <p>Returns current + <seealso marker="erts:time_correction#OS_System_Time">OS system time</seealso> + converted into the <c><anno>Unit</anno></c> passed as argument.</p> + + <p>Calling <c>os:system_time(<anno>Unit</anno>)</c> is equivalent to: + <seealso marker="erts:erlang#convert_time_unit/3"><c>erlang:convert_time_unit</c></seealso><c>(</c><seealso marker="#system_time/0"><c>os:system_time()</c></seealso><c>, + native, <anno>Unit</anno>)</c>.</p> + + <note><p>This time is <em>not</em> a monotonically increasing time.</p></note> + </desc> + </func> + <func> <name name="timestamp" arity="0"/> <type_desc variable="Timestamp">Timestamp = {MegaSecs, Secs, MicroSecs}</type_desc> - <fsummary>Returna a timestamp from the OS in the erlang:now/0 format</fsummary> + <fsummary>Current OS system time on the erlang:timestamp/0 format</fsummary> <desc> - <p>Returns a tuple in the same format as <seealso marker="erts:erlang#now/0">erlang:now/0</seealso>. The difference is that this function returns what the operating system thinks (a.k.a. the wall clock time) without any attempts at time correction. The result of two different calls to this function is <em>not</em> guaranteed to be different.</p> - <p>The most obvious use for this function is logging. The tuple can be used together with the function <seealso marker="stdlib:calendar#now_to_universal_time/1">calendar:now_to_universal_time/1</seealso> -or <seealso marker="stdlib:calendar#now_to_local_time/1">calendar:now_to_local_time/1</seealso> to get calendar time. Using the calendar time together with the <c>MicroSecs</c> part of the return tuple from this function allows you to log timestamps in high resolution and consistent with the time in the rest of the operating system.</p> - <p>Example of code formatting a string in the format "DD Mon YYYY HH:MM:SS.mmmmmm", where DD is the day of month, Mon is the textual month name, YYYY is the year, HH:MM:SS is the time and mmmmmm is the microseconds in six positions:</p> + <p>Returns current + <seealso marker="erts:time_correction#OS_System_Time">OS system time</seealso> + in the same format as <seealso marker="erts:erlang#timestamp/0">erlang:timestamp/0</seealso>. + The tuple can be used together with the function + <seealso marker="stdlib:calendar#now_to_universal_time/1">calendar:now_to_universal_time/1</seealso> + or <seealso marker="stdlib:calendar#now_to_local_time/1">calendar:now_to_local_time/1</seealso> to + get calendar time. Using the calendar time together with the <c>MicroSecs</c> part of the return + tuple from this function allows you to log timestamps in high resolution and consistent with the + time in the rest of the operating system.</p> + <p>Example of code formatting a string in the format "DD Mon YYYY HH:MM:SS.mmmmmm", where + DD is the day of month, Mon is the textual month name, YYYY is the year, HH:MM:SS is the time and + mmmmmm is the microseconds in six positions:</p> <code> -module(print_time). -export([format_utc_timestamp/0]). @@ -168,6 +203,9 @@ format_utc_timestamp() -> 1> <input>io:format("~s~n",[print_time:format_utc_timestamp()]).</input> 29 Apr 2009 9:55:30.051711 </pre> + <p>OS system time can also be retreived by + <c><seealso marker="#system_time/0"><c>os:system_time/0</c></seealso></c>, + and <seealso marker="#system_time/1"><c>os:system_time/1</c></seealso>.</p> </desc> </func> <func> diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl index eda35147d3..dbc486bee1 100644 --- a/lib/kernel/src/auth.erl +++ b/lib/kernel/src/auth.erl @@ -370,8 +370,8 @@ check_cookie1([], Result) -> %% Creates a new, random cookie. create_cookie(Name) -> - {_, S1, S2} = now(), - Seed = S2*10000+S1, + Seed = abs(erlang:monotonic_time() + bxor erlang:unique_integer()), Cookie = random_cookie(20, Seed, []), case file:open(Name, [write, raw]) of {ok, File} -> diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index b127fe2e33..6b510bd0c3 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -298,7 +298,7 @@ shutdown(_Module, _Line, _Data, Reason) -> exit(Reason). %% Use this line to debug connection. %% Set net_kernel verbose = 1 as well. -%% exit({Reason, ?MODULE, _Line, _Data, erlang:now()}). +%% exit({Reason, ?MODULE, _Line, _Data, erlang:timestamp()}). flush_down() -> @@ -373,7 +373,9 @@ gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) -> %% gen_challenge() returns a "random" number %% --------------------------------------------------------------- gen_challenge() -> - {A,B,C} = erlang:now(), + A = erlang:phash2([erlang:node()]), + B = erlang:monotonic_time(), + C = erlang:unique_integer(), {D,_} = erlang:statistics(reductions), {E,_} = erlang:statistics(runtime), {F,_} = erlang:statistics(wall_clock), diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl index 0a4edea452..6c36d417a2 100644 --- a/lib/kernel/src/global.erl +++ b/lib/kernel/src/global.erl @@ -881,11 +881,12 @@ handle_info({nodeup, Node}, S0) when S0#state.connect_all -> false -> resend_pre_connect(Node), - %% now() is used as a tag to separate different synch sessions + %% erlang:unique_integer([monotonic]) is used as a tag to + %% separate different synch sessions %% from each others. Global could be confused at bursty nodeups %% because it couldn't separate the messages between the different %% synch sessions started by a nodeup. - MyTag = now(), + MyTag = erlang:unique_integer([monotonic]), put({sync_tag_my, Node}, MyTag), ?trace({sending_nodeup_to_locker, {node,Node},{mytag,MyTag}}), S1#state.the_locker ! {nodeup, Node, MyTag}, @@ -1772,8 +1773,8 @@ update_locker_known(Upd, S) -> S#multi{known = Known, the_boss = TheBoss}. random_element(L) -> - {A,B,C} = now(), - E = (A+B+C) rem length(L), + E = abs(erlang:monotonic_time() + bxor erlang:unique_integer()) rem length(L), lists:nth(E+1, L). exclude_known(Others, Known) -> @@ -2072,9 +2073,10 @@ random_sleep(Times) -> end, case get(random_seed) of undefined -> - {A1, A2, A3} = now(), - _ = random:seed(A1, A2, A3 + erlang:phash(node(), 100000)), - ok; + _ = random:seed(erlang:phash2([erlang:node()]), + erlang:monotonic_time(), + erlang:unique_integer()), + ok; _ -> ok end, %% First time 1/4 seconds, then doubling each time up to 8 seconds max. @@ -2106,7 +2108,7 @@ trace_message(S, M, X) -> S#state{trace = [trace_message(M, X) | S#state.trace]}. trace_message(M, X) -> - {node(), now(), M, nodes(), X}. + {node(), erlang:timestamp(), M, nodes(), X}. %%----------------------------------------------------------------- %% Each sync process corresponds to one call to sync. Each such diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl index 2ebdc0f554..abe207295f 100644 --- a/lib/kernel/src/inet_db.erl +++ b/lib/kernel/src/inet_db.erl @@ -1372,8 +1372,7 @@ cache_rr(_Db, Cache, RR) -> ets:insert(Cache, RR). times() -> - {Mega,Secs,_} = erlang:now(), - Mega*1000000 + Secs. + erlang:monotonic_time(1). %% lookup and remove old entries diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl index 6037da1d22..410128a16a 100644 --- a/lib/kernel/src/inet_res.erl +++ b/lib/kernel/src/inet_res.erl @@ -715,10 +715,10 @@ udp_send(#sock{inet=I}, {A,B,C,D}=IP, Port, Buffer) udp_recv(#sock{inet6=I}, {A,B,C,D,E,F,G,H}=IP, Port, Timeout, Decode) when ?ip6(A,B,C,D,E,F,G,H), ?port(Port) -> - do_udp_recv(I, IP, Port, Timeout, Decode, erlang:now(), Timeout); + do_udp_recv(I, IP, Port, Timeout, Decode, time_now(), Timeout); udp_recv(#sock{inet=I}, {A,B,C,D}=IP, Port, Timeout, Decode) when ?ip(A,B,C,D), ?port(Port) -> - do_udp_recv(I, IP, Port, Timeout, Decode, erlang:now(), Timeout). + do_udp_recv(I, IP, Port, Timeout, Decode, time_now(), Timeout). do_udp_recv(_I, _IP, _Port, 0, _Decode, _Start, _T) -> timeout; @@ -742,7 +742,7 @@ do_udp_recv(I, IP, Port, Timeout, Decode, Start, T) -> NewTimeout = erlang:max(0, Timeout - 50), do_udp_recv(I, IP, Port, NewTimeout, Decode, Start, T); false -> - Now = erlang:now(), + Now = time_now(), NewT = erlang:max(0, Timeout - now_ms(Now, Start)), do_udp_recv(I, IP, Port, Timeout, Decode, Start, NewT); Result -> @@ -1057,5 +1057,9 @@ dns_msg(Msg) -> end. -compile({inline, [now_ms/2]}). -now_ms({Meg1,Sec1,Mic1}, {Meg0,Sec0,Mic0}) -> - ((Meg1-Meg0)*1000000 + (Sec1-Sec0))*1000 + ((Mic1-Mic0) div 1000). +now_ms(Int1, Int0) -> + Int1 - Int0. + +-compile({inline, [time_now/0]}). +time_now() -> + erlang:monotonic_time(1000). diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src index 9f6c0f4624..0cb10791d7 100644 --- a/lib/kernel/src/kernel.app.src +++ b/lib/kernel/src/kernel.app.src @@ -115,6 +115,6 @@ {applications, []}, {env, [{error_logger, tty}]}, {mod, {kernel, []}}, - {runtime_dependencies, ["erts-6.1.2", "stdlib-2.0", "sasl-2.4"]} + {runtime_dependencies, ["erts-7.0", "stdlib-2.0", "sasl-2.4"]} ] }. diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl index 7468a06f3c..3647545777 100644 --- a/lib/kernel/src/os.erl +++ b/lib/kernel/src/os.erl @@ -26,7 +26,8 @@ %%% BIFs --export([getenv/0, getenv/1, getenv/2, getpid/0, putenv/2, timestamp/0, unsetenv/1]). +-export([getenv/0, getenv/1, getenv/2, getpid/0, putenv/2, system_time/0, system_time/1, + timestamp/0, unsetenv/1]). -spec getenv() -> [string()]. @@ -65,6 +66,17 @@ getpid() -> putenv(_, _) -> erlang:nif_error(undef). +-spec system_time() -> integer(). + +system_time() -> + erlang:nif_error(undef). + +-spec system_time(Unit) -> integer() when + Unit :: erlang:time_unit(). + +system_time(_Unit) -> + erlang:nif_error(undef). + -spec timestamp() -> Timestamp when Timestamp :: erlang:timestamp(). diff --git a/lib/kernel/src/pg2.erl b/lib/kernel/src/pg2.erl index b562d4ffd2..70d7a75671 100644 --- a/lib/kernel/src/pg2.erl +++ b/lib/kernel/src/pg2.erl @@ -140,19 +140,22 @@ get_closest_pid(Name) -> [Pid] -> Pid; [] -> - {_,_,X} = erlang:now(), case get_members(Name) of [] -> {error, {no_process, Name}}; Members -> - lists:nth((X rem length(Members))+1, Members) + random_element(Members) end; Members when is_list(Members) -> - {_,_,X} = erlang:now(), - lists:nth((X rem length(Members))+1, Members); + random_element(Members); Else -> Else end. +random_element(List) -> + X = abs(erlang:monotonic_time() + bxor erlang:unique_integer()), + lists:nth((X rem length(List)) + 1, List). + %%% %%% Callback functions from gen_server %%% |