Merge "Fix some typos in the linker configuration file format documentation."
diff --git a/docs/native_allocator.md b/docs/native_allocator.md
index 97c3648..2d06e2f 100644
--- a/docs/native_allocator.md
+++ b/docs/native_allocator.md
@@ -10,7 +10,7 @@
It is important to note that there are two modes for a native allocator
to run in on Android. The first is the normal allocator, the second is
called the svelte config, which is designed to run on memory constrained
-systems and be a bit slower, but take less PSS. To enable the svelte config,
+systems and be a bit slower, but take less RSS. To enable the svelte config,
add this line to the `BoardConfig.mk` for the given target:
MALLOC_SVELTE := true
@@ -55,7 +55,7 @@
When set to zero, `mallopt(M_DECAY_TIME, 0)`, it is expected that an
allocator will attempt to purge and release any unused memory back to the
kernel on free calls. This is important in Android to avoid consuming extra
-PSS.
+RSS.
When set to non-zero, `mallopt(M_DECAY_TIME, 1)`, an allocator can delay the
purge and release action. The amount of delay is up to the allocator
@@ -65,13 +65,13 @@
The drawback to this option is that most allocators do not have a separate
thread to handle the purge, so the decay is only handled when an
allocation operation occurs. For server processes, this can mean that
-PSS is slightly higher when the server is waiting for the next connection
+RSS is slightly higher when the server is waiting for the next connection
and no other allocation calls are made. The `M_PURGE` option is used to
force a purge in this case.
For all applications on Android, the call `mallopt(M_DECAY_TIME, 1)` is
made by default. The idea is that it allows application frees to run a
-bit faster, while only increasing PSS a bit.
+bit faster, while only increasing RSS a bit.
#### M\_PURGE
When called, `mallopt(M_PURGE, 0)`, an allocator should purge and release
@@ -115,7 +115,7 @@
## Performance
There are multiple different ways to evaluate the performance of a native
allocator on Android. One is allocation speed in various different scenarios,
-anoher is total PSS taken by the allocator.
+another is total RSS taken by the allocator.
The last is virtual address space consumed in 32 bit applications. There is
a limited amount of address space available in 32 bit apps, and there have
@@ -129,7 +129,7 @@
mmma -j bionic/benchmarks
These benchmarks are only used to verify the speed of the allocator and
-ignore anything related to PSS and virtual address space consumed.
+ignore anything related to RSS and virtual address space consumed.
#### Allocate/Free Benchmarks
These are the benchmarks to verify the allocation speed of a loop doing a
@@ -228,7 +228,7 @@
These numbers should be as performant as the current allocator.
### Memory Trace Benchmarks
-These benchmarks measure all three axes of a native allocator, PSS, virtual
+These benchmarks measure all three axes of a native allocator, RSS, virtual
address space consumed, speed of allocation. They are designed to
run on a trace of the allocations from a real world application or system
process.
@@ -248,7 +248,7 @@
/data/benchmarktest/trace_benchmark/trace_benchmark
#### Memory Replay Benchmarks
-These benchmarks display PSS, virtual memory consumed (VA space), and do a
+These benchmarks display RSS, virtual memory consumed (VA space), and do a
bit of performance testing on actual traces taken from running applications.
The trace data includes what thread does each operation, so the replay
@@ -279,8 +279,8 @@
Where XXX.txt is the name of a trace file.
-Every 100000 allocation operations, a dump of the PSS and VA space will be
-performed. At the end, a final PSS and VA space number will be printed.
+Every 100000 allocation operations, a dump of the RSS and VA space will be
+performed. At the end, a final RSS and VA space number will be printed.
For the most part, the intermediate data can be ignored, but it is always
a good idea to look over the data to verify that no strange spikes are
occurring.
@@ -304,6 +304,14 @@
executable, the virtual address space consumed is not much larger than the
current allocator. A small increase (on the order of a few MBs) would be okay.
+There is no specific benchmark for memory fragmentation, instead, the RSS
+when running the memory traces acts as a proxy for this. An allocator that
+is fragmenting badly will show an increase in RSS. The best trace for
+tracking fragmentation is system\_server.txt which is an extremely long
+trace (~13 million operations). The total number of live allocations goes
+up and down a bit, but stays mostly the same so an allocator that fragments
+badly would likely show an abnormal increase in RSS on this trace.
+
NOTE: When a native allocator calls mmap, it is expected that the allocator
will name the map using the call:
diff --git a/libc/bionic/__cxa_guard.cpp b/libc/bionic/__cxa_guard.cpp
index 30b5f41..e2e7477 100644
--- a/libc/bionic/__cxa_guard.cpp
+++ b/libc/bionic/__cxa_guard.cpp
@@ -16,9 +16,7 @@
#include <endian.h>
#include <limits.h>
-#undef _USING_LIBCXX // Prevent using of <atomic>.
#include <stdatomic.h>
-
#include <stddef.h>
#include "private/bionic_futex.h"
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index dd3a96e..4ebc796 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -106,30 +106,8 @@
}
void __libc_init_fdsan() {
- constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE;
- const prop_info* pi = __system_property_find(kFdsanPropertyName);
- if (!pi) {
- android_fdsan_set_error_level(default_level);
- return;
- }
- __system_property_read_callback(
- pi,
- [](void*, const char*, const char* value, uint32_t) {
- if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) {
- android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL);
- } else if (strcasecmp(value, "warn") == 0) {
- android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
- } else if (strcasecmp(value, "warn_once") == 0) {
- android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
- } else {
- if (strlen(value) != 0 && strcasecmp(value, "0") != 0) {
- async_safe_format_log(ANDROID_LOG_ERROR, "libc",
- "debug.fdsan set to unknown value '%s', disabling", value);
- }
- android_fdsan_set_error_level(default_level);
- }
- },
- nullptr);
+ constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_FATAL;
+ android_fdsan_set_error_level_from_property(default_level);
}
static FdTable& GetFdTable() {
@@ -355,6 +333,45 @@
return atomic_exchange(&GetFdTable().error_level, new_level);
}
+android_fdsan_error_level android_fdsan_set_error_level_from_property(
+ android_fdsan_error_level default_level) {
+ const prop_info* pi = __system_property_find(kFdsanPropertyName);
+ if (!pi) {
+ return android_fdsan_set_error_level(default_level);
+ }
+
+ struct callback_data {
+ android_fdsan_error_level default_value;
+ android_fdsan_error_level result;
+ };
+
+ callback_data data;
+ data.default_value = default_level;
+
+ __system_property_read_callback(
+ pi,
+ [](void* arg, const char*, const char* value, uint32_t) {
+ callback_data* data = static_cast<callback_data*>(arg);
+
+ if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) {
+ data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL);
+ } else if (strcasecmp(value, "warn") == 0) {
+ data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
+ } else if (strcasecmp(value, "warn_once") == 0) {
+ data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
+ } else {
+ if (strlen(value) != 0 && strcasecmp(value, "0") != 0) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "debug.fdsan set to unknown value '%s', disabling", value);
+ }
+ data->result = android_fdsan_set_error_level(data->default_value);
+ }
+ },
+ &data);
+
+ return data.result;
+}
+
int close(int fd) {
int rc = android_fdsan_close_with_tag(fd, 0);
if (rc == -1 && errno == EINTR) {
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 1169ed0..83b9318 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -197,4 +197,8 @@
*/
enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__));
+/*
+ * Set the error level to the global setting if available, or a default value.
+ */
+enum android_fdsan_error_level android_fdsan_set_error_level_from_property(enum android_fdsan_error_level default_level) __INTRODUCED_IN(30) __attribute__((__weak__));
__END_DECLS
diff --git a/linker/linker_sdk_versions.cpp b/linker/linker_sdk_versions.cpp
index b06f3e6..29c0f4a 100644
--- a/linker/linker_sdk_versions.cpp
+++ b/linker/linker_sdk_versions.cpp
@@ -26,10 +26,13 @@
* SUCH DAMAGE.
*/
-#include "linker.h"
-#include <android/api-level.h>
#include <atomic>
+#include <android/api-level.h>
+#include <android/fdsan.h>
+
+#include "linker.h"
+
static std::atomic<int> g_target_sdk_version(__ANDROID_API__);
void set_application_target_sdk_version(int target) {
@@ -38,6 +41,10 @@
target = __ANDROID_API__;
}
g_target_sdk_version = target;
+
+ if (target < 30) {
+ android_fdsan_set_error_level_from_property(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
+ }
}
int get_application_target_sdk_version() {