commit ab0dc25c61837db7ab6e62684b331c411b46c580
parent 8f8ab9252172e86fabc3f713430e2eb594902aa7
Author: Joris Vink <joris@coders.se>
Date: Tue, 4 Jun 2013 13:54:16 +0200
use sched_setaffinity() to set what CPU each worker process should run on.
Diffstat:
2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/includes/kore.h b/includes/kore.h
@@ -108,6 +108,7 @@ struct kore_module_handle {
struct kore_worker {
u_int16_t id;
+ u_int16_t cpu;
pid_t pid;
TAILQ_ENTRY(kore_worker) list;
};
diff --git a/src/kore.c b/src/kore.c
@@ -35,6 +35,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sched.h>
#include <unistd.h>
#include <time.h>
#include <regex.h>
@@ -69,12 +70,13 @@ pid_t mypid = -1;
static void kore_signal(int);
static void kore_worker_wait(int);
static void kore_worker_init(void);
-static void kore_worker_spawn(void);
static int kore_socket_nonblock(int);
static int kore_server_sslstart(void);
static void kore_event(int, int, void *);
+static void kore_worker_spawn(u_int16_t);
static int kore_server_accept(struct listener *);
static void kore_worker_entry(struct kore_worker *);
+static void kore_worker_setcpu(struct kore_worker *);
static int kore_connection_handle(struct connection *, int);
static void kore_server_final_disconnect(struct connection *);
static int kore_server_bind(struct listener *, const char *, int);
@@ -423,7 +425,7 @@ kore_connection_handle(struct connection *c, int flags)
static void
kore_worker_init(void)
{
- u_int8_t i;
+ u_int16_t i, cpu;
if (worker_count == 0)
fatal("no workers specified");
@@ -433,18 +435,23 @@ kore_worker_init(void)
if (worker_count > cpu_count)
kore_log("kore_worker_init(): more workers then cpu's");
+ cpu = 0;
TAILQ_INIT(&kore_workers);
- for (i = 0; i < worker_count; i++)
- kore_worker_spawn();
+ for (i = 0; i < worker_count; i++) {
+ kore_worker_spawn(cpu++);
+ if (cpu == cpu_count)
+ cpu = 0;
+ }
}
static void
-kore_worker_spawn(void)
+kore_worker_spawn(u_int16_t cpu)
{
struct kore_worker *kw;
kw = (struct kore_worker *)kore_malloc(sizeof(*kw));
kw->id = workerid++;
+ kw->cpu = cpu;
kw->pid = fork();
if (kw->pid == -1)
fatal("could not spawn worker child: %s", errno_s);
@@ -462,6 +469,7 @@ static void
kore_worker_wait(int final)
{
int r;
+ u_int16_t cpu;
siginfo_t info;
struct kore_worker *kw, *next;
@@ -483,6 +491,7 @@ kore_worker_wait(int final)
if (kw->pid != info.si_pid)
continue;
+ cpu = kw->cpu;
TAILQ_REMOVE(&kore_workers, kw, list);
kore_log("worker %d (%d)-> status %d (%d)",
kw->id, info.si_pid, info.si_status, info.si_code);
@@ -494,13 +503,28 @@ kore_worker_wait(int final)
if (info.si_code == CLD_EXITED ||
info.si_code == CLD_KILLED ||
info.si_code == CLD_DUMPED) {
- kore_log("worker died, respawning new one");
- kore_worker_spawn();
+ kore_log("worker gone, respawning new one");
+ kore_worker_spawn(cpu);
}
}
}
static void
+kore_worker_setcpu(struct kore_worker *kw)
+{
+ cpu_set_t cpuset;
+
+ CPU_ZERO(&cpuset);
+ CPU_SET(kw->cpu, &cpuset);
+ if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset) == -1) {
+ kore_log("kore_worker_setcpu(): %s", errno_s);
+ } else {
+ kore_log("kore_worker_setcpu(): worker %d on cpu %d",
+ kw->id, kw->cpu);
+ }
+}
+
+static void
kore_worker_entry(struct kore_worker *kw)
{
struct epoll_event *events;
@@ -512,6 +536,8 @@ kore_worker_entry(struct kore_worker *kw)
pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("unable to drop privileges");
+ kore_worker_setcpu(kw);
+
for (k = TAILQ_FIRST(&kore_workers); k != NULL; k = next) {
next = TAILQ_NEXT(k, list);
TAILQ_REMOVE(&kore_workers, k, list);