hardware.c revision 292588
1/////////////////////////////////////////////////////////////////////////////// 2// 3/// \file hardware.c 4/// \brief Detection of available hardware resources 5// 6// Author: Lasse Collin 7// 8// This file has been put into the public domain. 9// You can do whatever you want with this file. 10// 11/////////////////////////////////////////////////////////////////////////////// 12 13#include "private.h" 14 15 16/// Maximum number of worker threads. This can be set with 17/// the --threads=NUM command line option. 18static uint32_t threads_max = 1; 19 20/// Memory usage limit for compression 21static uint64_t memlimit_compress; 22 23/// Memory usage limit for decompression 24static uint64_t memlimit_decompress; 25 26/// Total amount of physical RAM 27static uint64_t total_ram; 28 29 30extern void 31hardware_threads_set(uint32_t n) 32{ 33 if (n == 0) { 34 // Automatic number of threads was requested. 35 // If threading support was enabled at build time, 36 // use the number of available CPU cores. Otherwise 37 // use one thread since disabling threading support 38 // omits lzma_cputhreads() from liblzma. 39#ifdef MYTHREAD_ENABLED 40 threads_max = lzma_cputhreads(); 41 if (threads_max == 0) 42 threads_max = 1; 43#else 44 threads_max = 1; 45#endif 46 } else { 47 threads_max = n; 48 } 49 50 return; 51} 52 53 54extern uint32_t 55hardware_threads_get(void) 56{ 57 return threads_max; 58} 59 60 61extern void 62hardware_memlimit_set(uint64_t new_memlimit, 63 bool set_compress, bool set_decompress, bool is_percentage) 64{ 65 if (is_percentage) { 66 assert(new_memlimit > 0); 67 assert(new_memlimit <= 100); 68 new_memlimit = (uint32_t)new_memlimit * total_ram / 100; 69 } 70 71 if (set_compress) 72 memlimit_compress = new_memlimit; 73 74 if (set_decompress) 75 memlimit_decompress = new_memlimit; 76 77 return; 78} 79 80 81extern uint64_t 82hardware_memlimit_get(enum operation_mode mode) 83{ 84 // Zero is a special value that indicates the default. Currently 85 // the default simply disables the limit. Once there is threading 86 // support, this might be a little more complex, because there will 87 // probably be a special case where a user asks for "optimal" number 88 // of threads instead of a specific number (this might even become 89 // the default mode). Each thread may use a significant amount of 90 // memory. When there are no memory usage limits set, we need some 91 // default soft limit for calculating the "optimal" number of 92 // threads. 93 const uint64_t memlimit = mode == MODE_COMPRESS 94 ? memlimit_compress : memlimit_decompress; 95 return memlimit != 0 ? memlimit : UINT64_MAX; 96} 97 98 99/// Helper for hardware_memlimit_show() to print one human-readable info line. 100static void 101memlimit_show(const char *str, uint64_t value) 102{ 103 // The memory usage limit is considered to be disabled if value 104 // is 0 or UINT64_MAX. This might get a bit more complex once there 105 // is threading support. See the comment in hardware_memlimit_get(). 106 if (value == 0 || value == UINT64_MAX) 107 printf("%s %s\n", str, _("Disabled")); 108 else 109 printf("%s %s MiB (%s B)\n", str, 110 uint64_to_str(round_up_to_mib(value), 0), 111 uint64_to_str(value, 1)); 112 113 return; 114} 115 116 117extern void 118hardware_memlimit_show(void) 119{ 120 if (opt_robot) { 121 printf("%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\n", total_ram, 122 memlimit_compress, memlimit_decompress); 123 } else { 124 // TRANSLATORS: Test with "xz --info-memory" to see if 125 // the alignment looks nice. 126 memlimit_show(_("Total amount of physical memory (RAM): "), 127 total_ram); 128 memlimit_show(_("Memory usage limit for compression: "), 129 memlimit_compress); 130 memlimit_show(_("Memory usage limit for decompression: "), 131 memlimit_decompress); 132 } 133 134 tuklib_exit(E_SUCCESS, E_ERROR, message_verbosity_get() != V_SILENT); 135} 136 137 138extern void 139hardware_init(void) 140{ 141 // Get the amount of RAM. If we cannot determine it, 142 // use the assumption defined by the configure script. 143 total_ram = lzma_physmem(); 144 if (total_ram == 0) 145 total_ram = (uint64_t)(ASSUME_RAM) * 1024 * 1024; 146 147 // Set the defaults. 148 hardware_memlimit_set(0, true, true, false); 149 return; 150} 151