diff --git a/include/lighttpd/server.h b/include/lighttpd/server.h index 4c2f814..9bf7616 100644 --- a/include/lighttpd/server.h +++ b/include/lighttpd/server.h @@ -68,6 +68,10 @@ struct liServer { liWorker *main_worker; guint worker_count; GArray *workers; +#ifdef LIGHTY_OS_LINUX + cpu_set_t affinity_mask; /** cpus used by workers */ + guint affinity_cpus; /** total number of cpus in affinity_mask */ +#endif GArray *ts_formats; /** array of (GString*), add with li_server_ts_format_add() */ struct ev_loop *loop; diff --git a/include/lighttpd/sys-process.h b/include/lighttpd/sys-process.h index 53df76e..5ffcdaf 100644 --- a/include/lighttpd/sys-process.h +++ b/include/lighttpd/sys-process.h @@ -13,5 +13,9 @@ #include #endif +#ifdef LIGHTY_OS_LINUX +#include +#endif + #endif diff --git a/src/main/plugin_core.c b/src/main/plugin_core.c index f457cd0..a89b29d 100644 --- a/src/main/plugin_core.c +++ b/src/main/plugin_core.c @@ -9,8 +9,6 @@ #include #include -#include - static liAction* core_list(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) { liAction *a; guint i; @@ -1550,29 +1548,37 @@ static const liPluginAngel angelcbs[] = { { NULL, NULL } }; +#include static void plugin_core_prepare_worker(liServer *srv, liPlugin *p, liWorker *wrk) { UNUSED(p); -#ifdef LIGHTY_OS_LINUX + +#if defined(LIGHTY_OS_LINUX) && 0 /* sched_setaffinity is only available on linux */ - { + if (srv->affinity_cpus != 0) { + gint cpu; + guint cpu_nth; cpu_set_t mask; - if (0 != sched_getaffinity(0, sizeof(mask), &mask)) { - ERROR(srv, "couldn't get cpu affinity mask: %s", g_strerror(errno)); - } else { - guint cpus = 0; - while (CPU_ISSET(cpus, &mask)) cpus++; - if (cpus) { + /* bind worker to n-th cpu */ + for (cpu_nth = 0, cpu = 0; cpu < CPU_SETSIZE; cpu++) { + //g_print("wrk: %u cpu: %d\n", wrk->ndx, cpu); + if (!CPU_ISSET(cpu, &srv->affinity_mask)) + continue; + + if ((wrk->ndx % srv->affinity_cpus) == cpu_nth) { CPU_ZERO(&mask); - CPU_SET(wrk->ndx % cpus, &mask); - if (0 != sched_setaffinity(0, sizeof(mask), &mask)) { + CPU_SET(wrk->ndx % srv->affinity_cpus, &mask); + DEBUG(srv, "binding worker #%u to cpu #%u", wrk->ndx+1, wrk->ndx % srv->affinity_cpus); + if (0 != sched_setaffinity(0, sizeof(srv->affinity_mask), &mask)) { ERROR(srv, "couldn't set cpu affinity mask: %s", g_strerror(errno)); } - } else { - ERROR(srv, "%s", "cpu 0 not enabled, no affinity set"); + + break; } + + cpu_nth++; } } #else diff --git a/src/main/server.c b/src/main/server.c index e847813..eb07336 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -175,6 +175,20 @@ liServer* li_server_new(const gchar *module_dir, gboolean module_resident) { srv->io_timeout = 300; /* default I/O timeout */ srv->keep_alive_queue_timeout = 5; +#ifdef LIGHTY_OS_LINUX + /* sched_getaffinity is only available on linux */ + if (0 != sched_getaffinity(0, sizeof(srv->affinity_mask), &srv->affinity_mask)) { + ERROR(srv, "couldn't get cpu affinity mask: %s", g_strerror(errno)); + } else { + /* how many cpus do we have */ + gint cpu; + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + if (CPU_ISSET(cpu, &srv->affinity_mask)) + srv->affinity_cpus++; + } + } +#endif + return srv; }