aboutsummaryrefslogtreecommitdiff
path: root/src/xz/hardware.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2010-08-07 20:45:18 +0300
committerLasse Collin <lasse.collin@tukaani.org>2010-08-07 20:45:18 +0300
commit792331bdee706aa852a78b171040ebf814c6f3ae (patch)
tree255e92da193003ad47eb29ccf47ab353d93cafa5 /src/xz/hardware.c
parentAdd missing const to a global constant in xz. (diff)
downloadxz-792331bdee706aa852a78b171040ebf814c6f3ae.tar.xz
Disable the memory usage limiter by default.
For several people, the limiter causes bigger problems that it solves, so it is better to have it disabled by default. Those who want to have a limiter by default need to enable it via the environment variable XZ_DEFAULTS. Support for environment variable XZ_DEFAULTS was added. It is parsed before XZ_OPT and technically identical with it. The intended uses differ quite a bit though; see the man page. The memory usage limit can now be set separately for compression and decompression using --memlimit-compress and --memlimit-decompress. To set both at once, -M or --memlimit can be used. --memory was retained as a legacy alias for --memlimit for backwards compatibility. The semantics of --info-memory were changed in backwards incompatible way. Compatibility wasn't meaningful due to changes in the memory usage limiter functionality. The memory usage limiter info is no longer shown at the bottom of xz --long -help. The memory usage limiter support for removed completely from xzdec. xz's man page was updated to match the above changes. Various unrelated fixes were also made to the man page.
Diffstat (limited to 'src/xz/hardware.c')
-rw-r--r--src/xz/hardware.c96
1 files changed, 63 insertions, 33 deletions
diff --git a/src/xz/hardware.c b/src/xz/hardware.c
index 74742fce..c7d4f4f0 100644
--- a/src/xz/hardware.c
+++ b/src/xz/hardware.c
@@ -18,8 +18,11 @@
/// the --threads=NUM command line option.
static uint32_t threadlimit;
-/// Memory usage limit
-static uint64_t memlimit;
+/// Memory usage limit for compression
+static uint64_t memlimit_compress;
+
+/// Memory usage limit for decompression
+static uint64_t memlimit_decompress;
/// Total amount of physical RAM
static uint64_t total_ram;
@@ -49,50 +52,77 @@ hardware_threadlimit_get(void)
extern void
-hardware_memlimit_set(uint64_t new_memlimit)
+hardware_memlimit_set(uint64_t new_memlimit,
+ bool set_compress, bool set_decompress, bool is_percentage)
{
- if (new_memlimit != 0) {
- memlimit = new_memlimit;
- } else {
- // The default depends on the amount of RAM but so that
- // on "low-memory" systems the relative limit is higher
- // to make it more likely that files created with "xz -9"
- // will still decompress without overriding the limit
- // manually.
- //
- // If 40 % of RAM is 80 MiB or more, use 40 % of RAM as
- // the limit.
- memlimit = 40 * total_ram / 100;
- if (memlimit < UINT64_C(80) * 1024 * 1024) {
- // If 80 % of RAM is less than 80 MiB,
- // use 80 % of RAM as the limit.
- memlimit = 80 * total_ram / 100;
- if (memlimit > UINT64_C(80) * 1024 * 1024) {
- // Otherwise use 80 MiB as the limit.
- memlimit = UINT64_C(80) * 1024 * 1024;
- }
- }
+ if (is_percentage) {
+ assert(new_memlimit > 0);
+ assert(new_memlimit <= 100);
+ new_memlimit = (uint32_t)new_memlimit * total_ram / 100;
}
+ if (set_compress)
+ memlimit_compress = new_memlimit;
+
+ if (set_decompress)
+ memlimit_decompress = new_memlimit;
+
return;
}
-extern void
-hardware_memlimit_set_percentage(uint32_t percentage)
+extern uint64_t
+hardware_memlimit_get(enum operation_mode mode)
{
- assert(percentage > 0);
- assert(percentage <= 100);
+ // Zero is a special value that indicates the default. Currently
+ // the default simply disables the limit. Once there is threading
+ // support, this might be a little more complex, because there will
+ // probably be a special case where a user asks for "optimal" number
+ // of threads instead of a specific number (this might even become
+ // the default mode). Each thread may use a significant amount of
+ // memory. When there are no memory usage limits set, we need some
+ // default soft limit for calculating the "optimal" number of
+ // threads.
+ const uint64_t memlimit = mode == MODE_COMPRESS
+ ? memlimit_compress : memlimit_decompress;
+ return memlimit != 0 ? memlimit : UINT64_MAX;
+}
+
+
+/// Helper for hardware_memlimit_show() to print one human-readable info line.
+static void
+memlimit_show(const char *str, uint64_t value)
+{
+ // The memory usage limit is considered to be disabled if value
+ // is 0 or UINT64_MAX. This might get a bit more complex once there
+ // is threading support. See the comment in hardware_memlimit_get().
+ if (value == 0 || value == UINT64_MAX)
+ printf("%s %s\n", str, _("Disabled"));
+ else
+ printf("%s %s MiB (%s B)\n", str,
+ uint64_to_str(round_up_to_mib(value), 0),
+ uint64_to_str(value, 1));
- memlimit = percentage * total_ram / 100;
return;
}
-extern uint64_t
-hardware_memlimit_get(void)
+extern void
+hardware_memlimit_show(void)
{
- return memlimit;
+ if (opt_robot) {
+ printf("%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\n", total_ram,
+ memlimit_compress, memlimit_decompress);
+ } else {
+ memlimit_show(_("Total amount of physical memory (RAM): "),
+ total_ram);
+ memlimit_show(_("Memory usage limit for compression: "),
+ memlimit_compress);
+ memlimit_show(_("Memory usage limit for decompression: "),
+ memlimit_decompress);
+ }
+
+ tuklib_exit(E_SUCCESS, E_ERROR, message_verbosity_get() != V_SILENT);
}
@@ -106,7 +136,7 @@ hardware_init(void)
total_ram = (uint64_t)(ASSUME_RAM) * 1024 * 1024;
// Set the defaults.
- hardware_memlimit_set(0);
+ hardware_memlimit_set(0, true, true, false);
hardware_threadlimit_set(0);
return;
}