aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2009-02-14 00:45:29 +0200
committerLasse Collin <lasse.collin@tukaani.org>2009-02-14 00:45:29 +0200
commit3084d662d2646ab7eb58daf0dc32cf3f9a74eec7 (patch)
tree6601b6dee1b3c35b6894d71fcdbf1554801aff4f /src
parentInitial port to DOS using DJGPP. (diff)
downloadxz-3084d662d2646ab7eb58daf0dc32cf3f9a74eec7.tar.xz
Cleanups to the code that detects the amount of RAM and
the number of CPU cores. Added support for using sysinfo() on Linux systems whose libc lacks appropriate sysconf() support (at least dietlibc). The Autoconf macros were split into separate files, and CPU core count detection was moved from hardware.c to cpucores.h. The core count isn't used for anything real for now, so a problematic part in process.c was commented out.
Diffstat (limited to 'src')
-rw-r--r--src/common/cpucores.h52
-rw-r--r--src/common/physmem.h21
-rw-r--r--src/xz/args.c4
-rw-r--r--src/xz/hardware.c50
-rw-r--r--src/xz/hardware.h11
-rw-r--r--src/xz/message.c5
-rw-r--r--src/xz/process.c2
7 files changed, 102 insertions, 43 deletions
diff --git a/src/common/cpucores.h b/src/common/cpucores.h
new file mode 100644
index 00000000..7e1a1438
--- /dev/null
+++ b/src/common/cpucores.h
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file cpucores.h
+/// \brief Get the number of online CPU cores
+//
+// This code has been put into the public domain.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef CPUCORES_H
+#define CPUCORES_H
+
+#if defined(HAVE_NCPU_SYSCONF)
+# include <unistd.h>
+
+#elif defined(HAVE_NCPU_SYSCTL)
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# endif
+# ifdef HAVE_SYS_SYSCTL_H
+# include <sys/sysctl.h>
+# endif
+#endif
+
+
+static inline uint32_t
+cpucores(void)
+{
+ uint32_t ret = 0;
+
+#if defined(HAVE_CPUCORES_SYSCONF)
+ const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ if (cpus > 0)
+ ret = (uint32_t)(cpus);
+
+#elif defined(HAVE_CPUCORES_SYSCTL)
+ int name[2] = { CTL_HW, HW_NCPU };
+ int cpus;
+ size_t cpus_size = sizeof(cpus);
+ if (!sysctl(name, &cpus, &cpus_size, NULL, NULL)
+ && cpus_size == sizeof(cpus) && cpus > 0)
+ ret = (uint32_t)(cpus);
+#endif
+
+ return ret;
+}
+
+#endif
diff --git a/src/common/physmem.h b/src/common/physmem.h
index fb17eac5..7075bc56 100644
--- a/src/common/physmem.h
+++ b/src/common/physmem.h
@@ -14,27 +14,27 @@
#ifndef PHYSMEM_H
#define PHYSMEM_H
-#if defined(HAVE_PHYSMEM_SYSCTL) || defined(HAVE_NCPU_SYSCTL)
+#if defined(HAVE_PHYSMEM_SYSCONF)
+# include <unistd.h>
+
+#elif defined(HAVE_PHYSMEM_SYSCTL)
# ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
# endif
# ifdef HAVE_SYS_SYSCTL_H
# include <sys/sysctl.h>
# endif
-#endif
-#if defined(HAVE_PHYSMEM_SYSCONF) || defined(HAVE_NCPU_SYSCONF)
-# include <unistd.h>
-#endif
+#elif defined(HAVE_PHYSMEM_SYSINFO)
+# include <sys/sysinfo.h>
-#ifdef _WIN32
+#elif defined(_WIN32)
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0500
# endif
# include <windows.h>
-#endif
-#ifdef __DJGPP__
+#elif defined(__DJGPP__)
# include <dpmi.h>
#endif
@@ -75,6 +75,11 @@ physmem(void)
ret = mem.ui;
}
+#elif defined(HAVE_PHYSMEM_SYSINFO)
+ struct sysinfo si;
+ if (sysinfo(&si) == 0)
+ ret = (uint64_t)(si.totalram) * si.mem_unit;
+
#elif defined(_WIN32)
MEMORYSTATUSEX meminfo;
meminfo.dwLength = sizeof(meminfo);
diff --git a/src/xz/args.c b/src/xz/args.c
index 29abf971..f8732000 100644
--- a/src/xz/args.c
+++ b/src/xz/args.c
@@ -135,8 +135,8 @@ parse_real(args_info *args, int argc, char **argv)
break;
case 'T':
- opt_threads = str_to_uint64("threads", optarg,
- 1, SIZE_MAX);
+ hardware_threadlimit_set(str_to_uint64(
+ "threads", optarg, 1, SIZE_MAX));
break;
// --version
diff --git a/src/xz/hardware.c b/src/xz/hardware.c
index 0c372726..0695ccb1 100644
--- a/src/xz/hardware.c
+++ b/src/xz/hardware.c
@@ -19,11 +19,12 @@
#include "private.h"
#include "physmem.h"
+#include "cpucores.h"
/// Maximum number of free *coder* threads. This can be set with
/// the --threads=NUM command line option.
-size_t opt_threads = 1;
+static uint32_t threads_max;
/// Memory usage limit for encoding
@@ -40,38 +41,31 @@ static uint64_t memlimit_custom = 0;
/// Get the number of CPU cores, and set opt_threads to default to that value.
/// User can then override this with --threads command line option.
static void
-hardware_cores(void)
+hardware_threadlimit_init(void)
{
-#if defined(HAVE_NUM_PROCESSORS_SYSCONF)
- const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
- if (cpus > 0)
- opt_threads = (size_t)(cpus);
-
-#elif defined(HAVE_NUM_PROCESSORS_SYSCTL)
- int name[2] = { CTL_HW, HW_NCPU };
- int cpus;
- size_t cpus_size = sizeof(cpus);
- if (!sysctl(name, &cpus, &cpus_size, NULL, NULL)
- && cpus_size == sizeof(cpus) && cpus > 0)
- opt_threads = (size_t)(cpus);
-#endif
-
- // Limit opt_threads so that maximum number of threads doesn't exceed.
-
-#if defined(_SC_THREAD_THREADS_MAX)
- const long threads_max = sysconf(_SC_THREAD_THREADS_MAX);
- if (threads_max > 0 && (size_t)(threads_max) < opt_threads)
- opt_threads = (size_t)(threads_max);
-
-#elif defined(PTHREAD_THREADS_MAX)
- if (opt_threads > PTHREAD_THREADS_MAX)
- opt_threads = PTHREAD_THREADS_MAX;
-#endif
+ threads_max = cpucores();
+ if (threads_max == 0)
+ threads_max = 1;
return;
}
+extern void
+hardware_threadlimit_set(uint32_t threadlimit)
+{
+ threads_max = threadlimit;
+ return;
+}
+
+
+extern uint32_t
+hardware_threadlimit_get(void)
+{
+ return threads_max;
+}
+
+
static void
hardware_memlimit_init(void)
{
@@ -117,6 +111,6 @@ extern void
hardware_init(void)
{
hardware_memlimit_init();
- hardware_cores();
+ hardware_threadlimit_init();
return;
}
diff --git a/src/xz/hardware.h b/src/xz/hardware.h
index a6d91d78..36761fd1 100644
--- a/src/xz/hardware.h
+++ b/src/xz/hardware.h
@@ -17,14 +17,19 @@
//
///////////////////////////////////////////////////////////////////////////////
-extern size_t opt_threads;
-
-
/// Initialize some hardware-specific variables, which are needed by other
/// hardware_* functions.
extern void hardware_init(void);
+/// Set custom value for maximum number of coder threads.
+extern void hardware_threadlimit_set(uint32_t threadlimit);
+
+/// Get the maximum number of coder threads. Some additional helper threads
+/// are allowed on top of this).
+extern uint32_t hardware_threadlimit_get(void);
+
+
/// Set custom memory usage limit. This is used for both encoding and
/// decoding. Zero indicates resetting the limit back to defaults.
extern void hardware_memlimit_set(uint64_t memlimit);
diff --git a/src/xz/message.c b/src/xz/message.c
index fd519c8f..544572b8 100644
--- a/src/xz/message.c
+++ b/src/xz/message.c
@@ -1029,8 +1029,9 @@ message_help(bool long_help)
hardware_memlimit_encoder() / (1024 * 1024),
hardware_memlimit_decoder() / (1024 * 1024));
printf(N_(" * one thread for (de)compression.\n\n",
- " * %'" PRIu64 " threads for (de)compression.\n\n",
- (uint64_t)(opt_threads)), (uint64_t)(opt_threads));
+ " * %'" PRIu32 " threads for (de)compression.\n\n",
+ hardware_threadlimit_get()),
+ hardware_threadlimit_get());
}
printf(_("Report bugs to <%s> (in English or Finnish).\n"),
diff --git a/src/xz/process.c b/src/xz/process.c
index 9b966546..efe363ce 100644
--- a/src/xz/process.c
+++ b/src/xz/process.c
@@ -246,6 +246,7 @@ coder_set_compression_settings(void)
memory_limit >> 20);
}
+/*
// Limit the number of worker threads so that memory usage
// limit isn't exceeded.
assert(memory_usage > 0);
@@ -255,6 +256,7 @@ coder_set_compression_settings(void)
if (opt_threads > thread_limit)
opt_threads = thread_limit;
+*/
return;
}