diff options
author | Emmanuel Dreyfus <manu@netbsd.org> | 2012-08-13 06:35:18 +0200 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2012-08-13 05:15:41 -0700 |
commit | cdf6ad3695b0842acc3d4aadc5ebb474f07e8913 (patch) | |
tree | c4d5f0532f43819155c72ce033f650c993c37c77 /libglusterfs | |
parent | eabf3911675562a920040d0fe1a783ece1beb341 (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')
-rw-r--r-- | libglusterfs/src/syncop.c | 10 |
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)); |