[Gluster-devel] swapcontest usage in syncio.c
Emmanuel Dreyfus
manu at netbsd.org
Wed Aug 8 16:36:50 UTC 2012
On Wed, Aug 08, 2012 at 12:49:11PM +0000, Emmanuel Dreyfus wrote:
> The problem is caused by a non portable behavior of swapcontext(): on
> Linux it remains in the same thread, on NetBSD it switches to the
> thread where getcontext()/makecontext() was run.
Is the attached patch resonable enough to be posted in gerrit?
--
Emmanuel Dreyfus
manu at netbsd.org
-------------- next part --------------
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index c84832d..5e7634a 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -15,6 +15,8 @@
#include "syncop.h"
+static int syntask_newctx (struct synctask *);
+
static void
__run (struct synctask *task)
{
@@ -82,6 +84,14 @@ __wait (struct synctask *task)
void
synctask_yield (struct synctask *task)
{
+ if (task->stack == NULL) {
+ int ret;
+
+ ret = syntask_newctx (task);
+ if (ret != 0)
+ return;
+ }
+
if (swapcontext (&task->ctx, &task->proc->sched) < 0) {
gf_log ("syncop", GF_LOG_ERROR,
"swapcontext failed (%s)", strerror (errno));
@@ -164,6 +174,33 @@ synctask_done (struct synctask *task)
}
+static int
+syntask_newctx (struct synctask *newtask)
+{
+ if (getcontext (&newtask->ctx) < 0) {
+ gf_log ("syncop", GF_LOG_ERROR,
+ "getcontext failed (%s)",
+ strerror (errno));
+ goto err;
+ }
+
+ newtask->stack = CALLOC (1, newtask->env->stacksize);
+ if (!newtask->stack) {
+ gf_log ("syncop", GF_LOG_ERROR,
+ "out of memory for stack");
+ goto err;
+ }
+
+ newtask->ctx.uc_stack.ss_sp = newtask->stack;
+ newtask->ctx.uc_stack.ss_size = newtask->env->stacksize;
+
+ makecontext (&newtask->ctx, (void *) synctask_wrap, 2, newtask);
+
+ return 0;
+err:
+ return -1;
+}
+
int
synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
call_frame_t *frame, void *opaque)
@@ -195,25 +232,6 @@ synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
INIT_LIST_HEAD (&newtask->all_tasks);
- if (getcontext (&newtask->ctx) < 0) {
- gf_log ("syncop", GF_LOG_ERROR,
- "getcontext failed (%s)",
- strerror (errno));
- goto err;
- }
-
- newtask->stack = CALLOC (1, env->stacksize);
- if (!newtask->stack) {
- gf_log ("syncop", GF_LOG_ERROR,
- "out of memory for stack");
- goto err;
- }
-
- newtask->ctx.uc_stack.ss_sp = newtask->stack;
- newtask->ctx.uc_stack.ss_size = env->stacksize;
-
- makecontext (&newtask->ctx, (void *) synctask_wrap, 2, newtask);
-
newtask->state = SYNCTASK_INIT;
newtask->slept = 1;
@@ -292,6 +310,14 @@ synctask_switchto (struct synctask *task)
task->woken = 0;
task->slept = 0;
+ if (task->stack == NULL) {
+ int ret;
+
+ ret = syntask_newctx (task);
+ if (ret != 0)
+ return;
+ }
+
if (swapcontext (&task->proc->sched, &task->ctx) < 0) {
gf_log ("syncop", GF_LOG_ERROR,
"swapcontext failed (%s)", strerror (errno));
More information about the Gluster-devel
mailing list