aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/src')
-rw-r--r--lib/kernel/src/application.erl2
-rw-r--r--lib/kernel/src/code.erl29
-rw-r--r--lib/kernel/src/disk_log.erl50
-rw-r--r--lib/kernel/src/file.erl57
-rw-r--r--lib/kernel/src/file_server.erl9
-rw-r--r--lib/kernel/src/hipe_unified_loader.erl11
-rw-r--r--lib/kernel/src/user_sup.erl6
7 files changed, 108 insertions, 56 deletions
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl
index caac4d926c..c299fb085c 100644
--- a/lib/kernel/src/application.erl
+++ b/lib/kernel/src/application.erl
@@ -59,7 +59,7 @@
-callback start(StartType :: normal | {takeover, node()} | {failover, node()},
StartArgs :: term()) ->
- {ok, pid()} | {ok, pid(), State :: term()} | {error, Reason :: term}.
+ {'ok', pid()} | {'ok', pid(), State :: term()} | {'error', Reason :: term()}.
-callback stop(State :: term()) ->
term().
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 882e9625fe..b7fda69ce0 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -324,15 +324,7 @@ start_link(Flags) ->
%%-----------------------------------------------------------------
do_start(Flags) ->
- %% The following module_info/1 calls are here to ensure
- %% that these modules are loaded prior to their use elsewhere in
- %% the code_server.
- %% Otherwise a deadlock may occur when the code_server is starting.
- code_server = code_server:module_info(module),
- packages = packages:module_info(module),
- catch hipe_unified_loader:load_hipe_modules(),
- Modules2 = [gb_sets, gb_trees, ets, os, binary, unicode, filename, lists],
- lists:foreach(fun (M) -> M = M:module_info(module) end, Modules2),
+ load_code_server_prerequisites(),
Mode = get_mode(Flags),
case init:get_argument(root) of
@@ -360,6 +352,25 @@ do_start(Flags) ->
{error, crash}
end.
+%% Make sure that all modules that the code_server process calls
+%% (directly or indirectly) are loaded. Otherwise the code_server
+%% process will deadlock.
+
+load_code_server_prerequisites() ->
+ %% Please keep the alphabetical order.
+ Needed = [binary,
+ ets,
+ filename,
+ gb_sets,
+ gb_trees,
+ hipe_unified_loader,
+ lists,
+ os,
+ packages,
+ unicode],
+ [M = M:module_info(module) || M <- Needed],
+ ok.
+
do_stick_dirs() ->
do_s(compiler),
do_s(stdlib),
diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl
index d6bc23be6d..fb9415d440 100644
--- a/lib/kernel/src/disk_log.erl
+++ b/lib/kernel/src/disk_log.erl
@@ -64,7 +64,7 @@
%%-define(PROFILE(C), C).
-define(PROFILE(C), void).
--compile({inline,[{log_loop,4},{log_end_sync,2},{replies,2},{rflat,1}]}).
+-compile({inline,[{log_loop,5},{log_end_sync,2},{replies,2},{rflat,1}]}).
%%%----------------------------------------------------------------------
%%% Contract type specifications
@@ -685,7 +685,7 @@ handle({From, {log, B}}, S) ->
L when L#log.mode =:= read_only ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
L when L#log.status =:= ok, L#log.format =:= internal ->
- log_loop(S, From, [B], []);
+ log_loop(S, From, [B], [], iolist_size(B));
L when L#log.status =:= ok, L#log.format =:= external ->
reply(From, {error, {format_external, L#log.name}}, S);
L when L#log.status =:= {blocked, false} ->
@@ -700,7 +700,7 @@ handle({From, {blog, B}}, S) ->
L when L#log.mode =:= read_only ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
L when L#log.status =:= ok ->
- log_loop(S, From, [B], []);
+ log_loop(S, From, [B], [], iolist_size(B));
L when L#log.status =:= {blocked, false} ->
reply(From, {error, {blocked_log, L#log.name}}, S);
L when L#log.blocked_by =:= From ->
@@ -714,7 +714,7 @@ handle({alog, B}, S) ->
notify_owners({read_only,B}),
loop(S);
L when L#log.status =:= ok, L#log.format =:= internal ->
- log_loop(S, [], [B], []);
+ log_loop(S, [], [B], [], iolist_size(B));
L when L#log.status =:= ok ->
notify_owners({format_external, B}),
loop(S);
@@ -730,7 +730,7 @@ handle({balog, B}, S) ->
notify_owners({read_only,B}),
loop(S);
L when L#log.status =:= ok ->
- log_loop(S, [], [B], []);
+ log_loop(S, [], [B], [], iolist_size(B));
L when L#log.status =:= {blocked, false} ->
notify_owners({blocked_log, B}),
loop(S);
@@ -1029,38 +1029,42 @@ handle(_, S) ->
loop(S).
sync_loop(From, S) ->
- log_loop(S, [], [], From).
+ log_loop(S, [], [], From, 0).
+
+-define(MAX_LOOK_AHEAD, 64*1024).
%% Inlined.
-log_loop(S, Pids, _Bins, _Sync) when S#state.cache_error =/= ok ->
+log_loop(S, Pids, _Bins, _Sync, _Sz) when S#state.cache_error =/= ok ->
loop(cache_error(S, Pids));
-log_loop(S, Pids, Bins, Sync) when S#state.messages =:= [] ->
+log_loop(#state{messages = []}=S, Pids, Bins, Sync, Sz)
+ when Sz > ?MAX_LOOK_AHEAD ->
+ loop(log_end(S, Pids, Bins, Sync));
+log_loop(#state{messages = []}=S, Pids, Bins, Sync, Sz) ->
receive
Message ->
- log_loop(Message, Pids, Bins, Sync, S, get(log))
+ log_loop(Message, Pids, Bins, Sync, Sz, S, get(log))
after 0 ->
loop(log_end(S, Pids, Bins, Sync))
end;
-log_loop(S, Pids, Bins, Sync) ->
+log_loop(S, Pids, Bins, Sync, Sz) ->
[M | Ms] = S#state.messages,
S1 = S#state{messages = Ms},
- log_loop(M, Pids, Bins, Sync, S1, get(log)).
+ log_loop(M, Pids, Bins, Sync, Sz, S1, get(log)).
%% Items logged after the last sync request found are sync:ed as well.
-log_loop({alog,B}, Pids, Bins, Sync, S, L) when L#log.format =:= internal ->
+log_loop({alog,B}, Pids, Bins, Sync, Sz, S, #log{format = internal}) ->
%% {alog, _} allowed for the internal format only.
- log_loop(S, Pids, [B | Bins], Sync);
-log_loop({balog, B}, Pids, Bins, Sync, S, _L) ->
- log_loop(S, Pids, [B | Bins], Sync);
-log_loop({From, {log, B}}, Pids, Bins, Sync, S, L)
- when L#log.format =:= internal ->
+ log_loop(S, Pids, [B | Bins], Sync, Sz+iolist_size(B));
+log_loop({balog, B}, Pids, Bins, Sync, Sz, S, _L) ->
+ log_loop(S, Pids, [B | Bins], Sync, Sz+iolist_size(B));
+log_loop({From, {log, B}}, Pids, Bins, Sync, Sz, S, #log{format = internal}) ->
%% {log, _} allowed for the internal format only.
- log_loop(S, [From | Pids], [B | Bins], Sync);
-log_loop({From, {blog, B}}, Pids, Bins, Sync, S, _L) ->
- log_loop(S, [From | Pids], [B | Bins], Sync);
-log_loop({From, sync}, Pids, Bins, Sync, S, _L) ->
- log_loop(S, Pids, Bins, [From | Sync]);
-log_loop(Message, Pids, Bins, Sync, S, _L) ->
+ log_loop(S, [From | Pids], [B | Bins], Sync, Sz+iolist_size(B));
+log_loop({From, {blog, B}}, Pids, Bins, Sync, Sz, S, _L) ->
+ log_loop(S, [From | Pids], [B | Bins], Sync, Sz+iolist_size(B));
+log_loop({From, sync}, Pids, Bins, Sync, Sz, S, _L) ->
+ log_loop(S, Pids, Bins, [From | Sync], Sz);
+log_loop(Message, Pids, Bins, Sync, _Sz, S, _L) ->
NS = log_end(S, Pids, Bins, Sync),
handle(Message, NS).
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index a3c0e7da26..4028dd4f0b 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -28,9 +28,11 @@
%% File system and metadata.
-export([get_cwd/0, get_cwd/1, set_cwd/1, delete/1, rename/2,
make_dir/1, del_dir/1, list_dir/1,
- read_file_info/1, write_file_info/2,
+ read_file_info/1, read_file_info/2,
+ write_file_info/2, write_file_info/3,
altname/1,
- read_link_info/1, read_link/1,
+ read_link_info/1, read_link_info/2,
+ read_link/1,
make_link/2, make_symlink/2,
read_file/1, write_file/2, write_file/3]).
%% Specialized
@@ -107,6 +109,10 @@
-type posix_file_advise() :: 'normal' | 'sequential' | 'random'
| 'no_reuse' | 'will_need' | 'dont_need'.
-type sendfile_option() :: {chunk_size, non_neg_integer()}.
+-type file_info_option() :: {'time', 'local'} | {'time', 'universal'}
+ | {'time', 'posix'}.
+
+
%%%-----------------------------------------------------------------
%%% General functions
@@ -214,6 +220,15 @@ del_dir(Name) ->
read_file_info(Name) ->
check_and_call(read_file_info, [file_name(Name)]).
+-spec read_file_info(Filename, Opts) -> {ok, FileInfo} | {error, Reason} when
+ Filename :: name(),
+ Opts :: [file_info_option()],
+ FileInfo :: file_info(),
+ Reason :: posix() | badarg.
+
+read_file_info(Name, Opts) when is_list(Opts) ->
+ check_and_call(read_file_info, [file_name(Name), Opts]).
+
-spec altname(Name :: name()) -> any().
altname(Name) ->
@@ -227,6 +242,16 @@ altname(Name) ->
read_link_info(Name) ->
check_and_call(read_link_info, [file_name(Name)]).
+-spec read_link_info(Name, Opts) -> {ok, FileInfo} | {error, Reason} when
+ Name :: name(),
+ Opts :: [file_info_option()],
+ FileInfo :: file_info(),
+ Reason :: posix() | badarg.
+
+read_link_info(Name, Opts) when is_list(Opts) ->
+ check_and_call(read_link_info, [file_name(Name),Opts]).
+
+
-spec read_link(Name) -> {ok, Filename} | {error, Reason} when
Name :: name(),
Filename :: filename(),
@@ -243,6 +268,15 @@ read_link(Name) ->
write_file_info(Name, Info = #file_info{}) ->
check_and_call(write_file_info, [file_name(Name), Info]).
+-spec write_file_info(Filename, FileInfo, Opts) -> ok | {error, Reason} when
+ Filename :: name(),
+ Opts :: [file_info_option()],
+ FileInfo :: file_info(),
+ Reason :: posix() | badarg.
+
+write_file_info(Name, Info = #file_info{}, Opts) when is_list(Opts) ->
+ check_and_call(write_file_info, [file_name(Name), Info, Opts]).
+
-spec list_dir(Dir) -> {ok, Filenames} | {error, Reason} when
Dir :: name(),
Filenames :: [filename()],
@@ -267,9 +301,9 @@ read_file(Name) ->
make_link(Old, New) ->
check_and_call(make_link, [file_name(Old), file_name(New)]).
--spec make_symlink(Name1, Name2) -> ok | {error, Reason} when
- Name1 :: name(),
- Name2 :: name(),
+-spec make_symlink(Existing, New) -> ok | {error, Reason} when
+ Existing :: name(),
+ New :: name(),
Reason :: posix() | badarg.
make_symlink(Old, New) ->
@@ -1103,8 +1137,9 @@ change_group(Name, GroupId)
Mtime :: date_time(),
Reason :: posix() | badarg.
-change_time(Name, Time)
- when is_tuple(Time) ->
+change_time(Name, {{Y, M, D}, {H, Min, Sec}}=Time)
+ when is_integer(Y), is_integer(M), is_integer(D),
+ is_integer(H), is_integer(Min), is_integer(Sec)->
write_file_info(Name, #file_info{mtime=Time}).
-spec change_time(Filename, Atime, Mtime) -> ok | {error, Reason} when
@@ -1113,8 +1148,12 @@ change_time(Name, Time)
Mtime :: date_time(),
Reason :: posix() | badarg.
-change_time(Name, Atime, Mtime)
- when is_tuple(Atime), is_tuple(Mtime) ->
+change_time(Name, {{AY, AM, AD}, {AH, AMin, ASec}}=Atime,
+ {{MY, MM, MD}, {MH, MMin, MSec}}=Mtime)
+ when is_integer(AY), is_integer(AM), is_integer(AD),
+ is_integer(AH), is_integer(AMin), is_integer(ASec),
+ is_integer(MY), is_integer(MM), is_integer(MD),
+ is_integer(MH), is_integer(MMin), is_integer(MSec)->
write_file_info(Name, #file_info{atime=Atime, mtime=Mtime}).
%%
diff --git a/lib/kernel/src/file_server.erl b/lib/kernel/src/file_server.erl
index 64c61ba3ac..81f9efcf39 100644
--- a/lib/kernel/src/file_server.erl
+++ b/lib/kernel/src/file_server.erl
@@ -147,15 +147,24 @@ handle_call({get_cwd, Name}, _From, Handle) ->
handle_call({read_file_info, Name}, _From, Handle) ->
{reply, ?PRIM_FILE:read_file_info(Handle, Name), Handle};
+handle_call({read_file_info, Name, Opts}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_file_info(Handle, Name, Opts), Handle};
+
handle_call({altname, Name}, _From, Handle) ->
{reply, ?PRIM_FILE:altname(Handle, Name), Handle};
handle_call({write_file_info, Name, Info}, _From, Handle) ->
{reply, ?PRIM_FILE:write_file_info(Handle, Name, Info), Handle};
+handle_call({write_file_info, Name, Info, Opts}, _From, Handle) ->
+ {reply, ?PRIM_FILE:write_file_info(Handle, Name, Info, Opts), Handle};
+
handle_call({read_link_info, Name}, _From, Handle) ->
{reply, ?PRIM_FILE:read_link_info(Handle, Name), Handle};
+handle_call({read_link_info, Name, Opts}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_link_info(Handle, Name, Opts), Handle};
+
handle_call({read_link, Name}, _From, Handle) ->
{reply, ?PRIM_FILE:read_link(Handle, Name), Handle};
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
index 1d3eb926ca..8b3aa0286d 100644
--- a/lib/kernel/src/hipe_unified_loader.erl
+++ b/lib/kernel/src/hipe_unified_loader.erl
@@ -36,7 +36,6 @@
-export([chunk_name/1,
%% Only the code and code_server modules may call the entries below!
- load_hipe_modules/0,
load_native_code/2,
post_beam_load/1,
load_module/3,
@@ -78,16 +77,6 @@ chunk_name(Architecture) ->
%%========================================================================
--spec load_hipe_modules() -> 'ok'.
-%% @doc
-%% Ensures HiPE's loader modules are loaded.
-%% Called from code.erl at start-up.
-
-load_hipe_modules() ->
- ok.
-
-%%========================================================================
-
-spec load_native_code(Mod, binary()) -> 'no_native' | {'module', Mod}
when is_subtype(Mod, atom()).
%% @doc
diff --git a/lib/kernel/src/user_sup.erl b/lib/kernel/src/user_sup.erl
index 35b7ff0cfe..7c97da189a 100644
--- a/lib/kernel/src/user_sup.erl
+++ b/lib/kernel/src/user_sup.erl
@@ -45,7 +45,7 @@ init([]) ->
Pid = start_slave(Master),
{ok, Pid, Pid};
{M, F, A} ->
- case start_user({M, F}, A) of
+ case start_user(M, F, A) of
{ok, Pid} ->
{ok, Pid, Pid};
Error ->
@@ -95,8 +95,8 @@ terminate(_Reason, UserPid) ->
%% is guaranteed that the user is started.
%%-----------------------------------------------------------------
-start_user(Func,A) ->
- apply(Func, A),
+start_user(Mod, Func, A) ->
+ apply(Mod, Func, A),
wait_for_user_p(100).
wait_for_user_p(0) ->