summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/syncop.c
diff options
context:
space:
mode:
authorEmmanuel Dreyfus <manu@netbsd.org>2012-08-13 06:35:18 +0200
committerAnand Avati <avati@redhat.com>2012-08-13 05:15:41 -0700
commitcdf6ad3695b0842acc3d4aadc5ebb474f07e8913 (patch)
treec4d5f0532f43819155c72ce033f650c993c37c77 /libglusterfs/src/syncop.c
parenteabf3911675562a920040d0fe1a783ece1beb341 (diff)
NetBSD swapcontext() portability fix
Further analysis of the problem reveals some wrong conclusions I made before. NetBSD's swapcontext() preempts no thread. It alters the pthread private pointer, leading to multiple threads with the same pthread pointer. That led me to the wrong conclusion that thread were preempted. I guess this can be called a bug: NetBSD swapcontext() is incompatible with libpthread. Fortunately, there is a workaround, swapcontext() can be told to let the pthread private pointer untouched. This change just does that, fixing the crashes without sacrifying performances. There is just one problem: not all NetBSD ports have the capability to do that: at least ports using sh3, sparc, sparc64 and powerpc are left broken by this change. This problem will be addressed by upcoming fixes in NetBSD. BUG: 764655 Change-Id: I4191cb984176fce7064730ab55bd62c9156846cd Signed-off-by: Emmanuel Dreyfus <manu@netbsd.org> Reviewed-on: http://review.gluster.com/3794 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'libglusterfs/src/syncop.c')
-rw-r--r--libglusterfs/src/syncop.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index 7b34c631d8c..cbd20251500 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -82,6 +82,11 @@ __wait (struct synctask *task)
void
synctask_yield (struct synctask *task)
{
+#if defined(__NetBSD__) && defined(_UC_TLSBASE)
+ /* Preserve pthread private pointer through swapcontex() */
+ task->proc->sched.uc_flags &= ~_UC_TLSBASE;
+#endif
+
if (swapcontext (&task->ctx, &task->proc->sched) < 0) {
gf_log ("syncop", GF_LOG_ERROR,
"swapcontext failed (%s)", strerror (errno));
@@ -290,6 +295,11 @@ synctask_switchto (struct synctask *task)
task->woken = 0;
task->slept = 0;
+#if defined(__NetBSD__) && defined(_UC_TLSBASE)
+ /* Preserve pthread private pointer through swapcontex() */
+ task->ctx.uc_flags &= ~_UC_TLSBASE;
+#endif
+
if (swapcontext (&task->proc->sched, &task->ctx) < 0) {
gf_log ("syncop", GF_LOG_ERROR,
"swapcontext failed (%s)", strerror (errno));