[pacman-dev] [PATCH 1/2] Add _alpm_for_each_cpu() internal API.
Tavian Barnes
tavianator at gmail.com
Mon Feb 21 17:38:34 EST 2011
This function takes a callback which is called in a separate thread
for every CPU core you have, to spread a parallel workload over the
available cores.
---
lib/libalpm/util.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/libalpm/util.h | 3 ++
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 458f750..4e5cf85 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -39,6 +39,7 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <locale.h> /* setlocale */
+#include <pthread.h>
/* libarchive */
#include <archive.h>
@@ -938,6 +939,58 @@ long _alpm_parsedate(const char *line)
return(atol(line));
}
+typedef struct {
+ _alpm_for_each_cpu_callback callback;
+ void *ptr;
+ int thread, numcpus;
+ int ret;
+} _alpm_thread_payload;
+
+static void *_alpm_thread_callback(void *ptr)
+{
+ _alpm_thread_payload *payload = ptr;
+ payload->ret = payload->callback(payload->ptr, payload->thread, payload->numcpus);
+ return NULL;
+}
+
+static int _alpm_numcpus()
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ long numcpus = sysconf(_SC_NPROCESSORS_ONLN);
+ if(numcpus >= 1) {
+ return numcpus;
+ }
+#endif
+
+ return 1;
+}
+
+int _alpm_for_each_cpu(_alpm_for_each_cpu_callback callback, void *ptr)
+{
+ int numcpus = _alpm_numcpus();
+
+ pthread_t threads[numcpus];
+ _alpm_thread_payload payloads[numcpus];
+ for(int i = 0; i < numcpus; i++) {
+ payloads[i].callback = callback;
+ payloads[i].ptr = ptr;
+ payloads[i].thread = i;
+ payloads[i].numcpus = numcpus;
+
+ pthread_create(&threads[i], NULL, _alpm_thread_callback, &payloads[i]);
+ }
+
+ int ret = 0;
+ for(int i = 0; i < numcpus; i++) {
+ pthread_join(threads[i], NULL);
+ if(payloads[i].ret != 0) {
+ ret = payloads[i].ret;
+ }
+ }
+
+ return ret;
+}
+
#ifndef HAVE_STRNDUP
/* A quick and dirty implementation derived from glibc */
static size_t strnlen(const char *s, size_t max)
diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
index 015e9bf..72cd5d7 100644
--- a/lib/libalpm/util.h
+++ b/lib/libalpm/util.h
@@ -98,6 +98,9 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg);
unsigned long _alpm_hash_sdbm(const char *str);
long _alpm_parsedate(const char *line);
+typedef int (*_alpm_for_each_cpu_callback)(void *ptr, int thread, int numcpus);
+int _alpm_for_each_cpu(_alpm_for_each_cpu_callback callback, void *ptr);
+
#ifndef HAVE_STRSEP
char *strsep(char **, const char *);
#endif
--
1.7.4.1
More information about the pacman-dev
mailing list