Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
The Tor Project
Core
Tor
Commits
aca05fc5
Commit
aca05fc5
authored
Apr 03, 2014
by
Nick Mathewson
🥄
Browse files
get_total_system_memory(): see how much RAM we have
parent
17d5734d
Changes
5
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
aca05fc5
...
...
@@ -353,6 +353,7 @@ AC_CHECK_FUNCS(
strtok_r \
strtoull \
sysconf \
sysctl \
uname \
vasprintf \
_vscprintf
...
...
@@ -877,6 +878,7 @@ AC_CHECK_HEADERS(
sys/prctl.h \
sys/resource.h \
sys/socket.h \
sys/sysctl.h \
sys/syslimits.h \
sys/time.h \
sys/types.h \
...
...
src/common/compat.c
View file @
aca05fc5
...
...
@@ -38,6 +38,9 @@
#ifdef HAVE_SYS_TYPES_H
#include
<sys/types.h>
#endif
#ifdef HAVE_SYS_SYSCTL_H
#include
<sys/sysctl.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include
<sys/stat.h>
#endif
...
...
@@ -3311,3 +3314,119 @@ format_win32_error(DWORD err)
}
#endif
#if defined(HW_PHYSMEM64)
/* This appears to be an OpenBSD thing */
#define INT64_HW_MEM HW_PHYSMEM64
#elif defined(HW_MEMSIZE)
/* OSX defines this one */
#define INT64_HW_MEM HW_MEMSIZE
#endif
/**
* Helper: try to detect the total system memory, and return it. On failure,
* return 0.
*/
static
uint64_t
get_total_system_memory_impl
(
void
)
{
#if defined(__linux__)
/* On linux, sysctl is deprecated. Because proc is so awesome that you
* shouldn't _want_ to write portable code, I guess? */
unsigned
long
long
result
=
0
;
int
fd
=
-
1
;
char
*
s
=
NULL
;
const
char
*
cp
;
size_t
file_size
=
0
;
if
(
-
1
==
(
fd
=
tor_open_cloexec
(
"/proc/meminfo"
,
O_RDONLY
,
0
)))
return
0
;
s
=
read_file_to_str_until_eof
(
fd
,
65536
,
&
file_size
);
if
(
!
s
)
goto
err
;
cp
=
strstr
(
s
,
"MemTotal:"
);
if
(
!
cp
)
goto
err
;
/* Use the system sscanf so that space will match a wider number of space */
if
(
sscanf
(
cp
,
"MemTotal: %llu kB
\n
"
,
&
result
)
!=
1
)
goto
err
;
close
(
fd
);
tor_free
(
s
);
return
result
*
1024
;
err:
tor_free
(
s
);
close
(
fd
);
return
0
;
#elif defined (_WIN32)
/* Windows has MEMORYSTATUSEX; pretty straightforward. */
MEMORYSTATUSEX
ms
;
memset
(
&
ms
,
0
,
sizeof
(
ms
));
ms
.
dwLength
=
sizeof
(
ms
);
if
(
!
GlobalMemoryStatusEx
(
&
ms
))
return
0
;
return
ms
.
ullTotalPhys
;
#elif defined(HAVE_SYSCTL) && defined(INT64_HW_MEM)
/* On many systems, HW_PYHSMEM is clipped to 32 bits; let's use a better
* variant if we know about it. */
uint64_t
memsize
=
0
;
size_t
len
=
sizeof
(
memsize
);
int
mib
[
2
]
=
{
CTL_HW
,
INT64_HW_MEM
};
if
(
sysctl
(
mib
,
2
,
&
memsize
,
&
len
,
NULL
,
0
))
return
0
;
return
memsize
;
#elif defined(HAVE_SYSCTL) && defined(HW_PHYSMEM)
/* On some systems (like FreeBSD I hope) you can use a size_t with
* HW_PHYSMEM. */
size_t
memsize
=
0
;
size_t
len
=
sizeof
(
memsize
);
int
mib
[
2
]
=
{
CTL_HW
,
HW_USERMEM
};
if
(
sysctl
(
mib
,
2
,
&
memsize
,
&
len
,
NULL
,
0
))
return
-
1
;
return
memsize
;
#else
/* I have no clue. */
return
0
;
#endif
}
/**
* Try to find out how much physical memory the system has. On success,
* return 0 and set *<b>mem_out</b> to that value. On failure, return -1.
*/
int
get_total_system_memory
(
size_t
*
mem_out
)
{
static
size_t
mem_cached
=
0
;
uint64_t
m
=
get_total_system_memory_impl
();
if
(
0
==
m
)
{
/* We couldn't find our memory total */
if
(
0
==
mem_cached
)
{
/* We have no cached value either */
*
mem_out
=
0
;
return
-
1
;
}
*
mem_out
=
mem_cached
;
return
0
;
}
#if SIZE_T_MAX != UINT64_MAX
if
(
m
>
SIZE_T_MAX
)
{
/* I think this could happen if we're a 32-bit Tor running on a 64-bit
* system: we could have more system memory than would fit in a
* size_t. */
m
=
SIZE_T_MAX
;
}
#endif
*
mem_out
=
mem_cached
=
(
size_t
)
m
;
return
-
1
;
}
src/common/compat.h
View file @
aca05fc5
...
...
@@ -637,6 +637,8 @@ char *make_path_absolute(char *fname);
char
**
get_environment
(
void
);
int
get_total_system_memory
(
size_t
*
mem_out
);
int
spawn_func
(
void
(
*
func
)(
void
*
),
void
*
data
);
void
spawn_exit
(
void
)
ATTR_NORETURN
;
...
...
src/or/main.c
View file @
aca05fc5
...
...
@@ -2751,6 +2751,7 @@ sandbox_init_filter(void)
"/dev/srandom"
,
0
,
"/dev/urandom"
,
0
,
"/dev/random"
,
0
,
"/proc/meminfo"
,
0
,
NULL
,
0
);
...
...
src/test/test_util.c
View file @
aca05fc5
...
...
@@ -3606,6 +3606,34 @@ test_util_socketpair(void *arg)
tor_close_socket
(
fds
[
1
]);
}
static
void
test_util_max_mem
(
void
*
arg
)
{
size_t
memory1
,
memory2
;
int
r
,
r2
;
(
void
)
arg
;
r
=
get_total_system_memory
(
&
memory1
);
r2
=
get_total_system_memory
(
&
memory2
);
tt_int_op
(
r
,
==
,
r2
);
tt_int_op
(
memory2
,
==
,
memory1
);
TT_BLATHER
((
"System memory: "
U64_FORMAT
,
U64_PRINTF_ARG
(
memory1
)));
if
(
r
==
0
)
{
/* You have at least a megabyte. */
tt_int_op
(
memory1
,
>
,
(
1
<<
20
));
}
else
{
/* You do not have a petabyte. */
#if SIZEOF_SIZE_T == SIZEOF_UINT64_T
tt_int_op
(
memory1
,
<
,
(
U64_LITERAL
(
1
)
<<
50
));
#endif
}
done:
;
}
struct
testcase_t
util_tests
[]
=
{
UTIL_LEGACY
(
time
),
UTIL_TEST
(
parse_http_time
,
0
),
...
...
@@ -3669,6 +3697,7 @@ struct testcase_t util_tests[] = {
(
void
*
)
"0"
},
{
"socketpair_ersatz"
,
test_util_socketpair
,
TT_FORK
,
&
socketpair_setup
,
(
void
*
)
"1"
},
UTIL_TEST
(
max_mem
,
0
),
END_OF_TESTCASES
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment