aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2011-11-08 11:06:21 +0100
committerBjörn Gustavsson <[email protected]>2011-11-08 11:06:21 +0100
commit4a67884525973f104e9b05ea80bc16ffc71fada8 (patch)
tree00ef8d308f061737d0b1c8a7cf65598737cd8246
parent766a0a84f0b9e4b9341fb06364bf5430574588a6 (diff)
parent3d5cdb216fa5652bd8552ef4fa4eee310e543b42 (diff)
downloadotp-4a67884525973f104e9b05ea80bc16ffc71fada8.tar.gz
otp-4a67884525973f104e9b05ea80bc16ffc71fada8.tar.bz2
otp-4a67884525973f104e9b05ea80bc16ffc71fada8.zip
Merge branch 'bjorn/create-less-garbage'
* bjorn/create-less-garbage: Optimize filename:basename/1 to produce less garbage Optimize filename:extension/1 to produce less garbage sys.c for Unix: Undo caching of utsname in os_flavor() Pre-build the tuples returned by os:type/0 and os:version/0
-rw-r--r--erts/emulator/beam/erl_bif_info.c48
-rw-r--r--erts/emulator/sys/unix/sys.c17
-rw-r--r--lib/stdlib/src/filename.erl25
3 files changed, 48 insertions, 42 deletions
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index e17325b64f..de5e4046fa 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -119,6 +119,10 @@ static char erts_system_version[] = ("Erlang " ERLANG_OTP_RELEASE
# define PERFMON_GETPCR _IOR('P', 2, unsigned long long)
#endif
+/* Cached, pre-built {OsType,OsFlavor} and {Major,Minor,Build} tuples */
+static Eterm os_type_tuple;
+static Eterm os_version_tuple;
+
static Eterm
current_function(Process* p, Process* rp, Eterm** hpp, int full_info);
static Eterm current_stacktrace(Process* p, Process* rp, Eterm** hpp);
@@ -2227,16 +2231,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
return erts_instr_get_type_info(BIF_P);
}
else if (BIF_ARG_1 == am_os_type) {
- Eterm type = am_atom_put(os_type, strlen(os_type));
- Eterm flav, tup;
- char *buf = erts_alloc(ERTS_ALC_T_TMP, 1024); /* More than enough */
-
- os_flavor(buf, 1024);
- flav = am_atom_put(buf, strlen(buf));
- hp = HAlloc(BIF_P, 3);
- tup = TUPLE2(hp, type, flav);
- erts_free(ERTS_ALC_T_TMP, (void *) buf);
- BIF_RET(tup);
+ BIF_RET(os_type_tuple);
}
else if (BIF_ARG_1 == am_allocator) {
BIF_RET(erts_allocator_options((void *) BIF_P));
@@ -2262,16 +2257,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
BIF_RET(am_false);
}
else if (BIF_ARG_1 == am_os_version) {
- int major, minor, build;
- Eterm tup;
-
- os_version(&major, &minor, &build);
- hp = HAlloc(BIF_P, 4);
- tup = TUPLE3(hp,
- make_small(major),
- make_small(minor),
- make_small(build));
- BIF_RET(tup);
+ BIF_RET(os_version_tuple);
}
else if (BIF_ARG_1 == am_version) {
int n = strlen(ERLANG_VERSION);
@@ -4107,6 +4093,27 @@ BIF_RETTYPE erts_debug_lock_counters_1(BIF_ALIST_1)
BIF_ERROR(BIF_P, BADARG);
}
+static void os_info_init(void)
+{
+ Eterm type = am_atom_put(os_type, strlen(os_type));
+ Eterm flav;
+ int major, minor, build;
+ char* buf = erts_alloc(ERTS_ALC_T_TMP, 1024); /* More than enough */
+ Eterm* hp;
+
+ os_flavor(buf, 1024);
+ flav = am_atom_put(buf, strlen(buf));
+ erts_free(ERTS_ALC_T_TMP, (void *) buf);
+ hp = erts_alloc(ERTS_ALC_T_LL_TEMP_TERM, (3+4)*sizeof(Eterm));
+ os_type_tuple = TUPLE2(hp, type, flav);
+ hp += 3;
+ os_version(&major, &minor, &build);
+ os_version_tuple = TUPLE3(hp,
+ make_small(major),
+ make_small(minor),
+ make_small(build));
+}
+
void
erts_bif_info_init(void)
{
@@ -4114,4 +4121,5 @@ erts_bif_info_init(void)
erts_smp_atomic_init_nob(&hipe_test_reschedule_flag, 0);
process_info_init();
+ os_info_init();
}
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 94ec8dc8a0..20bfaad9aa 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -931,18 +931,13 @@ void
os_flavor(char* namebuf, /* Where to return the name. */
unsigned size) /* Size of name buffer. */
{
- static int called = 0;
- static struct utsname uts; /* Information about the system. */
-
- if (!called) {
- char* s;
+ struct utsname uts; /* Information about the system. */
+ char* s;
- (void) uname(&uts);
- called = 1;
- for (s = uts.sysname; *s; s++) {
- if (isupper((int) *s)) {
- *s = tolower((int) *s);
- }
+ (void) uname(&uts);
+ for (s = uts.sysname; *s; s++) {
+ if (isupper((int) *s)) {
+ *s = tolower((int) *s);
}
}
strcpy(namebuf, uts.sysname);
diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl
index 1cb9e4a25e..2fc9128e4e 100644
--- a/lib/stdlib/src/filename.erl
+++ b/lib/stdlib/src/filename.erl
@@ -147,9 +147,10 @@ basename(Name) when is_binary(Name) ->
end;
basename(Name0) ->
- Name = flatten(Name0),
+ Name1 = flatten(Name0),
{DirSep2, DrvSep} = separators(),
- basename1(skip_prefix(Name, DrvSep), [], DirSep2).
+ Name = skip_prefix(Name1, DrvSep),
+ basename1(Name, Name, DirSep2).
win_basenameb(<<Letter,$:,Rest/binary>>) when ?IS_DRIVELETTER(Letter) ->
basenameb(Rest,[<<"/">>,<<"\\">>]);
@@ -167,16 +168,18 @@ basenameb(Bin,Sep) ->
-basename1([$/|[]], Tail, DirSep2) ->
- basename1([], Tail, DirSep2);
+basename1([$/], Tail0, _DirSep2) ->
+ %% End of filename -- must get rid of trailing directory separator.
+ [_|Tail] = lists:reverse(Tail0),
+ lists:reverse(Tail);
basename1([$/|Rest], _Tail, DirSep2) ->
- basename1(Rest, [], DirSep2);
+ basename1(Rest, Rest, DirSep2);
basename1([DirSep2|Rest], Tail, DirSep2) when is_integer(DirSep2) ->
basename1([$/|Rest], Tail, DirSep2);
basename1([Char|Rest], Tail, DirSep2) when is_integer(Char) ->
- basename1(Rest, [Char|Tail], DirSep2);
+ basename1(Rest, Tail, DirSep2);
basename1([], Tail, _DirSep2) ->
- lists:reverse(Tail).
+ Tail.
skip_prefix(Name, false) ->
Name;
@@ -369,8 +372,8 @@ extension(Name0) ->
Name = flatten(Name0),
extension(Name, [], major_os_type()).
-extension([$.|Rest], _Result, OsType) ->
- extension(Rest, [$.], OsType);
+extension([$.|Rest]=Result, _Result, OsType) ->
+ extension(Rest, Result, OsType);
extension([Char|Rest], [], OsType) when is_integer(Char) ->
extension(Rest, [], OsType);
extension([$/|Rest], _Result, OsType) ->
@@ -378,9 +381,9 @@ extension([$/|Rest], _Result, OsType) ->
extension([$\\|Rest], _Result, win32) ->
extension(Rest, [], win32);
extension([Char|Rest], Result, OsType) when is_integer(Char) ->
- extension(Rest, [Char|Result], OsType);
+ extension(Rest, Result, OsType);
extension([], Result, _OsType) ->
- lists:reverse(Result).
+ Result.
%% Joins a list of filenames with directory separators.