Module Name:    src
Committed By:   pooka
Date:           Mon Nov 29 11:40:55 UTC 2010

Modified Files:
        src/lib/librumpuser: rumpuser_sp.c

Log Message:
Cache syscall worker threads and include some stetson-harrison
limits.  This improves syscall throughput about 2x for non-userio
syscalls (no copyin/out, e.g. getpid()) and almost 1.5x even for
things like __sysctl().
(measured for cases where the remote process is on the local machine)

XXX: if the pthread deadqueue sucks for anything which cares about
performance, why does it exist?  Nuking it would make supporting
variable stack size easier.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/lib/librumpuser/rumpuser_sp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/librumpuser/rumpuser_sp.c
diff -u src/lib/librumpuser/rumpuser_sp.c:1.19 src/lib/librumpuser/rumpuser_sp.c:1.20
--- src/lib/librumpuser/rumpuser_sp.c:1.19	Sat Nov 27 18:30:51 2010
+++ src/lib/librumpuser/rumpuser_sp.c	Mon Nov 29 11:40:54 2010
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpuser_sp.c,v 1.19 2010/11/27 18:30:51 pooka Exp $	*/
+/*      $NetBSD: rumpuser_sp.c,v 1.20 2010/11/29 11:40:54 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpuser_sp.c,v 1.19 2010/11/27 18:30:51 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_sp.c,v 1.20 2010/11/29 11:40:54 pooka Exp $");
 
 #include <sys/types.h>
 #include <sys/atomic.h>
@@ -65,7 +65,17 @@
 
 #include "sp_common.c"
 
+#ifndef MAXCLI
 #define MAXCLI 256
+#endif
+#ifndef MAXWORKER
+#define MAXWORKER 128
+#endif
+#ifndef IDLEWORKER
+#define IDLEWORKER 16
+#endif
+int rumpsp_maxworker = MAXWORKER;
+int rumpsp_idleworker = IDLEWORKER;
 
 static struct pollfd pfdlist[MAXCLI];
 static struct spclient spclist[MAXCLI];
@@ -439,16 +449,44 @@
 	struct spclient *sba_spc;
 	struct rsp_hdr sba_hdr;
 	uint8_t *sba_data;
+
+	TAILQ_ENTRY(sysbouncearg) sba_entries;
 };
+static pthread_mutex_t sbamtx;
+static pthread_cond_t sbacv;
+static int nworker, idleworker;
+static TAILQ_HEAD(, sysbouncearg) syslist = TAILQ_HEAD_INITIALIZER(syslist);
+
+/*ARGSUSED*/
 static void *
 serv_syscallbouncer(void *arg)
 {
-	struct sysbouncearg *barg = arg;
+	struct sysbouncearg *sba;
+
+	for (;;) {
+		pthread_mutex_lock(&sbamtx);
+		if (idleworker >= rumpsp_idleworker) {
+			nworker--;
+			pthread_mutex_unlock(&sbamtx);
+			break;
+		}
+		idleworker++;
+		while (TAILQ_EMPTY(&syslist)) {
+			pthread_cond_wait(&sbacv, &sbamtx);
+		}
+
+		sba = TAILQ_FIRST(&syslist);
+		TAILQ_REMOVE(&syslist, sba, sba_entries);
+		idleworker--;
+		pthread_mutex_unlock(&sbamtx);
+
+		serv_handlesyscall(sba->sba_spc,
+		    &sba->sba_hdr, sba->sba_data);
+		spcrelease(sba->sba_spc);
+		free(sba->sba_data);
+		free(sba);
+	}
 
-	serv_handlesyscall(barg->sba_spc, &barg->sba_hdr, barg->sba_data);
-	spcrelease(barg->sba_spc);
-	free(barg->sba_data);
-	free(barg);
 	return NULL;
 }
 
@@ -567,7 +605,6 @@
 {
 	struct sysbouncearg *sba;
 	pthread_t pt;
-	int rv;
 
 	/* XXX: check that it's a syscall */
 
@@ -585,11 +622,23 @@
 	spc->spc_off = 0;
 
 	spcref(spc);
-	if ((rv = pthread_create(&pt, &pattr_detached,
-	    serv_syscallbouncer, sba)) != 0) {
-		/* panic */
-		abort();
+
+	pthread_mutex_lock(&sbamtx);
+	TAILQ_INSERT_TAIL(&syslist, sba, sba_entries);
+	if (idleworker > 0) {
+		/* do we have a daemon's tool (i.e. idle threads)? */
+		pthread_cond_signal(&sbacv);
+	} else if (nworker < rumpsp_maxworker) {
+		/*
+		 * Else, need to create one
+		 * (if we can, otherwise just expect another
+		 * worker to pick up the syscall)
+		 */
+		if (pthread_create(&pt, &pattr_detached,
+		    serv_syscallbouncer, NULL) == 0)
+			nworker++;
 	}
+	pthread_mutex_unlock(&sbamtx);
 }
 
 static void *
@@ -620,6 +669,9 @@
 	/* XXX: doesn't stacksize currently work on NetBSD */
 	pthread_attr_setstacksize(&pattr_detached, 32*1024);
 
+	pthread_mutex_init(&sbamtx, NULL);
+	pthread_cond_init(&sbacv, NULL);
+
 	DPRINTF(("rump_sp: server mainloop\n"));
 
 	for (;;) {

Reply via email to