diff options
author | Anthony Ramine <[email protected]> | 2013-04-05 11:47:02 +0200 |
---|---|---|
committer | Anthony Ramine <[email protected]> | 2013-04-11 14:28:45 +0200 |
commit | 9f2c736e273aed9034aeab2d2877b5c52cc8d327 (patch) | |
tree | 48aaedb3b41004bf8378ad6e7a5b33a5f437f782 /lib | |
parent | e72043e3519cb14aabf461849eba959b97e07410 (diff) | |
download | otp-9f2c736e273aed9034aeab2d2877b5c52cc8d327.tar.gz otp-9f2c736e273aed9034aeab2d2877b5c52cc8d327.tar.bz2 otp-9f2c736e273aed9034aeab2d2877b5c52cc8d327.zip |
Optimize communication with file io server
The file module communicates with a file io server with the following
protocol for file operations:
> {file_request,From,ReplyAs,Request}
< {file_reply,ReplyAs,Reply}
The ReplyAs value is sent by the client side to match against when
receiving the reply and is otherwise left untouched and passed as is by
the server.
This commit enables receive optimizations by using the reference of the
server monitor, changing the protocol to:
> {file_request,From,MonitorRef,Request}
< {file_reply,MonitorRef,Reply}
As the shape of the messages is not changed, backwards compatibility is
not a concern.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/kernel/src/file.erl | 43 | ||||
-rw-r--r-- | lib/kernel/test/file_SUITE.erl | 29 |
2 files changed, 42 insertions, 30 deletions
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index a4c56b346f..36289053eb 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -480,8 +480,7 @@ open(Item, Mode) -> Reason :: posix() | badarg | terminated. close(File) when is_pid(File) -> - R = file_request(File, close), - case wait_file_reply(File, R) of + case file_request(File, close) of {error, terminated} -> ok; Other -> @@ -503,8 +502,7 @@ close(_) -> Reason :: posix() | badarg. advise(File, Offset, Length, Advise) when is_pid(File) -> - R = file_request(File, {advise, Offset, Length, Advise}), - wait_file_reply(File, R); + file_request(File, {advise, Offset, Length, Advise}); advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) -> Module:advise(Handle, Offset, Length, Advise); advise(_, _, _, _) -> @@ -517,8 +515,7 @@ advise(_, _, _, _) -> Length :: non_neg_integer(). allocate(File, Offset, Length) when is_pid(File) -> - R = file_request(File, {allocate, Offset, Length}), - wait_file_reply(File, R); + file_request(File, {allocate, Offset, Length}); allocate(#file_descriptor{module = Module} = Handle, Offset, Length) -> Module:allocate(Handle, Offset, Length). @@ -601,8 +598,7 @@ pread_int(_, _, _) -> Reason :: posix() | badarg | terminated. pread(File, At, Sz) when is_pid(File), is_integer(Sz), Sz >= 0 -> - R = file_request(File, {pread, At, Sz}), - wait_file_reply(File, R); + file_request(File, {pread, At, Sz}); pread(#file_descriptor{module = Module} = Handle, Offs, Sz) when is_integer(Sz), Sz >= 0 -> Module:pread(Handle, Offs, Sz); @@ -658,8 +654,7 @@ pwrite_int(_, _, _) -> Reason :: posix() | badarg | terminated. pwrite(File, At, Bytes) when is_pid(File) -> - R = file_request(File, {pwrite, At, Bytes}), - wait_file_reply(File, R); + file_request(File, {pwrite, At, Bytes}); pwrite(#file_descriptor{module = Module} = Handle, Offs, Bytes) -> Module:pwrite(Handle, Offs, Bytes); pwrite(_, _, _) -> @@ -670,8 +665,7 @@ pwrite(_, _, _) -> Reason :: posix() | badarg | terminated. datasync(File) when is_pid(File) -> - R = file_request(File, datasync), - wait_file_reply(File, R); + file_request(File, datasync); datasync(#file_descriptor{module = Module} = Handle) -> Module:datasync(Handle); datasync(_) -> @@ -682,8 +676,7 @@ datasync(_) -> Reason :: posix() | badarg | terminated. sync(File) when is_pid(File) -> - R = file_request(File, sync), - wait_file_reply(File, R); + file_request(File, sync); sync(#file_descriptor{module = Module} = Handle) -> Module:sync(Handle); sync(_) -> @@ -696,8 +689,7 @@ sync(_) -> Reason :: posix() | badarg | terminated. position(File, At) when is_pid(File) -> - R = file_request(File, {position,At}), - wait_file_reply(File, R); + file_request(File, {position,At}); position(#file_descriptor{module = Module} = Handle, At) -> Module:position(Handle, At); position(_, _) -> @@ -708,8 +700,7 @@ position(_, _) -> Reason :: posix() | badarg | terminated. truncate(File) when is_pid(File) -> - R = file_request(File, truncate), - wait_file_reply(File, R); + file_request(File, truncate); truncate(#file_descriptor{module = Module} = Handle) -> Module:truncate(Handle); truncate(_) -> @@ -1497,25 +1488,19 @@ check_args([]) -> ok. %%----------------------------------------------------------------- -%% Functions for communicating with a file io server. +%% Function for communicating with a file io server. %% The messages sent have the following formats: %% %% {file_request,From,ReplyAs,Request} %% {file_reply,ReplyAs,Reply} file_request(Io, Request) -> - R = erlang:monitor(process, Io), - Io ! {file_request,self(),Io,Request}, - R. - -wait_file_reply(From, Ref) -> + Ref = erlang:monitor(process, Io), + Io ! {file_request,self(),Ref,Request}, receive - {file_reply,From,Reply} -> - erlang:demonitor(Ref), - receive {'DOWN', Ref, _, _, _} -> ok after 0 -> ok end, - %% receive {'EXIT', From, _} -> ok after 0 -> ok end, + {file_reply,Ref,Reply} -> + erlang:demonitor(Ref, [flush]), Reply; {'DOWN', Ref, _, _, _} -> - %% receive {'EXIT', From, _} -> ok after 0 -> ok end, {error, terminated} end. diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index c604e7073f..4218cfa646 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -91,6 +91,8 @@ -export([standard_io/1,mini_server/1]). +-export([old_io_protocol/1]). + %% Debug exports -export([create_file_slow/2, create_file/2, create_bin/2]). -export([verify_file/2, verify_bin/3]). @@ -114,7 +116,7 @@ all() -> delayed_write, read_ahead, segment_read, segment_write, ipread, pid2name, interleaved_read_write, otp_5814, otp_10852, large_file, large_write, read_line_1, read_line_2, read_line_3, - read_line_4, standard_io]. + read_line_4, standard_io, old_io_protocol]. groups() -> [{dirs, [], [make_del_dir, cur_dir_0, cur_dir_1, @@ -310,6 +312,31 @@ standard_io(Config) when is_list(Config) -> Pid ! die, receive after 1000 -> ok end. +old_io_protocol(suite) -> + []; +old_io_protocol(doc) -> + ["Test that the old file IO protocol =< R16B still works"]; +old_io_protocol(Config) when is_list(Config) -> + Dog = test_server:timetrap(test_server:seconds(5)), + RootDir = ?config(priv_dir,Config), + Name = filename:join(RootDir, + atom_to_list(?MODULE) + ++"old_io_protocol.fil"), + MyData = "0123456789abcdefghijklmnopqrstuvxyz", + ok = ?FILE_MODULE:write_file(Name, MyData), + {ok, Fd} = ?FILE_MODULE:open(Name, write), + Fd ! {file_request,self(),Fd,truncate}, + receive + {file_reply,Fd,ok} -> ok + end, + ok = ?FILE_MODULE:close(Fd), + {ok, <<>>} = ?FILE_MODULE:read_file(Name), + test_server:timetrap_cancel(Dog), + [] = flush(), + ok. + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% read_write_file(suite) -> []; |