Ejemplo n.º 1
0
void co_resume(void)
{
	cothread_ctx *tctx = co_get_thread_ctx();

	co_call(tctx->co_curr->restarget);
	tctx->co_curr->restarget = tctx->co_curr->caller;
}
Ejemplo n.º 2
0
static void co_runner(void)
{
	cothread_ctx *tctx = co_get_thread_ctx();
	coroutine *co = tctx->co_curr;

	co->restarget = co->caller;
	co->func(co->data);
	co_exit();
}
Ejemplo n.º 3
0
void co_call(coroutine_t coro)
{
	cothread_ctx *tctx = co_get_thread_ctx();
	coroutine *co = (coroutine *) coro, *oldco = tctx->co_curr;

	co->caller = tctx->co_curr;
	tctx->co_curr = co;

  co_switch_context(&oldco->ctx, &co->ctx);
}
Ejemplo n.º 4
0
static void co_switch_context(co_ctx_t *octx, co_ctx_t *nctx)
{
	cothread_ctx *tctx = co_get_thread_ctx();

	if (swapcontext(&octx->cc, &nctx->cc) < 0) {
		fprintf(stderr, "[PCL] Context switch failed: curr=%p\n",
			tctx->co_curr);
		exit(1);
	}
}
Ejemplo n.º 5
0
void co_delete(coroutine_t coro)
{
	cothread_ctx *tctx = co_get_thread_ctx();
	coroutine *co = (coroutine *) coro;

	if (co == tctx->co_curr) {
		fprintf(stderr, "[PCL] Cannot delete itself: curr=%p\n",
			tctx->co_curr);
		exit(1);
	}
	if (co->alloc)
		free(co);
}
Ejemplo n.º 6
0
static void co_del_helper(void *data)
{
	cothread_ctx *tctx;
	coroutine *cdh;

	for (;;) {
		tctx = co_get_thread_ctx();
		cdh = tctx->co_dhelper;
		tctx->co_dhelper = NULL;
		co_delete(tctx->co_curr->caller);
		co_call((coroutine_t) cdh);
		if (tctx->co_dhelper == NULL) {
			fprintf(stderr,
				"[PCL] Resume to delete helper coroutine: curr=%p caller=%p\n",
				tctx->co_curr, tctx->co_curr->caller);
			exit(1);
		}
	}
}
Ejemplo n.º 7
0
void co_exit_to(coroutine_t coro)
{
	cothread_ctx *tctx = co_get_thread_ctx();
	coroutine *co = (coroutine *) coro;

	if (tctx->dchelper == NULL &&
	    (tctx->dchelper = co_create(co_del_helper, NULL,
					tctx->stk, sizeof(tctx->stk))) == NULL) {
		fprintf(stderr, "[PCL] Unable to create delete helper coroutine: curr=%p\n",
			tctx->co_curr);
		exit(1);
	}
	tctx->co_dhelper = co;

	co_call((coroutine_t) tctx->dchelper);

	fprintf(stderr, "[PCL] Stale coroutine called: curr=%p  exitto=%p  caller=%p\n",
		tctx->co_curr, co, tctx->co_curr->caller);
	exit(1);
}
Ejemplo n.º 8
0
/*
 * This code comes from the GNU Pth implementation and uses the
 * sigstack/sigaltstack() trick.
 *
 * The ingenious fact is that this variant runs really on _all_ POSIX
 * compliant systems without special platform kludges.  But be _VERY_
 * carefully when you change something in the following code. The slightest
 * change or reordering can lead to horribly broken code.  Really every
 * function call in the following case is intended to be how it is, doubt
 * me...
 *
 * For more details we strongly recommend you to read the companion
 * paper ``Portable Multithreading -- The Signal Stack Trick for
 * User-Space Thread Creation'' from Ralf S. Engelschall.
 */
static void co_ctx_bootstrap(void)
{
	cothread_ctx *tctx = co_get_thread_ctx();
	co_ctx_t * volatile ctx_starting;
	void (* volatile ctx_starting_func)(void);

	/*
	 * Switch to the final signal mask (inherited from parent)
	 */
	sigprocmask(SIG_SETMASK, &ctx_creating_sigs, NULL);

	/*
	 * Move startup details from static storage to local auto
	 * variables which is necessary because it has to survive in
	 * a local context until the thread is scheduled for real.
	 */
	ctx_starting = ctx_creating;
	ctx_starting_func = (void (*)(void)) ctx_creating_func;

	/*
	 * Save current machine state (on new stack) and
	 * go back to caller until we're scheduled for real...
	 */
	if (!setjmp(ctx_starting->cc))
		longjmp(ctx_caller.cc, 1);

	/*
	 * The new thread is now running: GREAT!
	 * Now we just invoke its init function....
	 */
	ctx_starting_func();

	fprintf(stderr, "[PCL] Hmm, you really shouldn't reach this point: curr=%p\n",
		tctx->co_curr);
	exit(1);
}
Ejemplo n.º 9
0
coroutine_t co_current(void)
{
	cothread_ctx *tctx = co_get_thread_ctx();

	return (coroutine_t) tctx->co_curr;
}
Ejemplo n.º 10
0
void co_exit(void)
{
	cothread_ctx *tctx = co_get_thread_ctx();

	co_exit_to((coroutine_t) tctx->co_curr->restarget);
}