diff --git a/Makefile.am b/Makefile.am
index 2ee81bd..0dc576c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,7 +17,7 @@
# .
SUBDIRS = tests
-AM_CXXFLAGS = -std=c++11 -Wall -Wextra -pedantic
+AM_CXXFLAGS = -std=c++11 -Wall -Wextra -pedantic -pthread
bin_PROGRAMS = termux-elf-cleaner
diff --git a/elf-cleaner.cpp b/elf-cleaner.cpp
index 144be0f..e4c6031 100644
--- a/elf-cleaner.cpp
+++ b/elf-cleaner.cpp
@@ -19,7 +19,10 @@ You should have received a copy of the GNU General Public License
along with termux-elf-cleaner. If not, see
. */
-#include
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
#include
#include
#include
@@ -29,6 +32,12 @@ along with termux-elf-cleaner. If not, see
#include
#include
+#include
+#include
+#include
+#include
+#include
+
#include "arghandling.h"
// Include a local elf.h copy as not all platforms have it.
@@ -55,6 +64,8 @@ int api_level = 21;
bool dry_run = false;
bool quiet = false;
+std::mutex mutex;
+
static char const *const usage_message[] =
{ "\
\n\
@@ -64,6 +75,7 @@ dynamic section entries which the Android linker warns about.\n\
Options:\n\
\n\
--api-level NN choose target api level, i.e. 21, 24, ..\n\
+--jobs N run parallel on n thread(s).\n\
--dry-run print info but but do not remove entries\n\
--quiet do not print info about removed entries\n\
--help display this help and exit\n\
@@ -299,6 +311,16 @@ int parse_file(const char *file_name)
return 0;
}
+void parse_file_handler(std::deque* files, unsigned int &pos) {
+ while (files->size() > pos) {
+ mutex.lock();
+ const char *file = files->at(pos);
+ pos++;
+ mutex.unlock();
+ parse_file(file);
+ }
+}
+
int main(int argc, char **argv)
{
int skip_args = 0;
@@ -334,9 +356,21 @@ int main(int argc, char **argv)
if (argmatch(argv, argc, "-quiet", "--quiet", 3, NULL, &skip_args))
quiet = true;
- for (int i = skip_args+1; i < argc; i++) {
- if (parse_file(argv[i]) != 0)
- return 1;
- }
+ int threads_count = std::thread::hardware_concurrency();
+ int files_count = argc - (skip_args + 1);
+ argmatch(argv, argc, "-jobs", "--jobs", 1, &threads_count, &skip_args);
+ if (argc - (skip_args + 1) <= threads_count) threads_count = files_count;
+ if (threads_count < 1) threads_count = 1;
+
+ std::deque files;
+ std::vector threads(threads_count);
+ unsigned int pos = 0;
+
+ for (int i = skip_args + 1; i < argc; i++)
+ files.push_back(argv[i]);
+ for (int i = 0; i < threads_count; i++)
+ threads[i] = std::thread(parse_file_handler, &files, std::ref(pos));
+ for (std::thread& thread : threads)
+ if (thread.joinable()) thread.join();
return 0;
}