pthreadpool: Slightly serialize jobs
authorJeremy Allison <jra@samba.org>
Mon, 25 Aug 2014 19:27:54 +0000 (12:27 -0700)
committerKarolin Seeger <kseeger@samba.org>
Mon, 13 Oct 2014 19:20:08 +0000 (21:20 +0200)
Using the new msg_source program with 1.500 instances against a single
msg_sink I found the msg_source process to spawn two worker threads for
synchronously sending the data towards the receiving socket. This should
not happen: Per destination node we only create one queue. We strictly
only add pthreadpool jobs one after the other, so a single helper thread
should be perfectly sufficient.

It turned out that under heavy overload the main sending thread was
scheduled before the thread that just had finished its send() job. So
the helper thread was not able to increment the pool->num_idle variable
indicating that we don't have to create a new thread when the new job
is added.

This patch moves the signalling write under the mutex. This means that
indicating readiness via the pipe and the pool->num_idle variable happen both
under the same mutex lock and thus are atomic. No superfluous threads anymore.

Back port of commit 1c4284c7395f23cefa61a407db74cf5067aee2aa
that went into master.

https://bugzilla.samba.org/show_bug.cgi?id=10779

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/lib/pthreadpool/pthreadpool.c

index 04303776a2fec11572f4a99ae66d08de7b27f952..fbbb173a9e2aae42bc0b739de09badb0b5c5dd9c 100644 (file)
@@ -488,14 +488,14 @@ static void *pthreadpool_server(void *arg)
 
                        job->fn(job->private_data);
 
+                       res = pthread_mutex_lock(&pool->mutex);
+                       assert(res == 0);
+
                        written = write(pool->sig_pipe[1], &job->id,
                                        sizeof(int));
 
                        free(job);
 
-                       res = pthread_mutex_lock(&pool->mutex);
-                       assert(res == 0);
-
                        if (written != sizeof(int)) {
                                pthreadpool_server_exit(pool);
                                pthread_mutex_unlock(&pool->mutex);