Select Git revision
-
Michael Hauspie authoredMichael Hauspie authored
try.c 2.04 KiB
#include <stdlib.h>
#include <assert.h>
#include "try.h"
static ctx_t *current_ctx = NULL;
static ctx_t *ring_ctx = NULL;
int try(ctx_t *pctx, func_t *f, int arg)
{
asm("movl %%esp, %0"
"\n\t"
"movl %%ebp, %1"
: "=r"(pctx->esp), "=r"(pctx->ebp));
return f(arg);
}
int throw(ctx_t * pctx, int r)
{
assert(pctx != NULL);
static int r_tmp;
r_tmp = r;
asm("movl %0 ,%%esp"
"\n\t"
"movl %1 ,%%ebp "
:
: "r"(pctx->esp), "r"(pctx->ebp));
return r_tmp;
}
int init_ctx(ctx_t *pctx, int stack_size, funct_t f, void *args)
{
pctx->stack = malloc(stack_size);
pctx->esp = pctx->stack + stack_size - sizeof(void *);
pctx->ebp = pctx->stack + stack_size - sizeof(void *);
pctx->f = f;
pctx->args = args;
pctx->status = CTX_INIT;
}
void switch_to_ctx(ctx_t *pctx)
{
assert(pctx->status != CTX_END);
if (current_ctx != NULL)
{
// Sauvegarder où on en est avec le ctx courant
asm("movl %%esp, %0"
"\n\t"
"movl %%ebp, %1"
: "=r"(current_ctx->esp), "=r"(current_ctx->ebp));
}
current_ctx = pctx;
asm("movl %0, %%esp"
"\n\t"
"movl %1, %%ebp"
:
: "r"(current_ctx->esp), "r"(current_ctx->ebp));
if (current_ctx->status == CTX_INIT)
start_ctx();
}
void start_ctx()
{
current_ctx->status = CTX_EXEC;
current_ctx->f(current_ctx->args);
current_ctx->status = CTX_END;
yield();
}
ctx_t *create_ctx(int stack_size, funct_t f, void *args)
{
ctx_t *new_ctx = malloc(sizeof(ctx_t));
if (ring_ctx == NULL)
{
new_ctx->next_ctx = new_ctx;
ring_ctx = new_ctx;
}
else
{
new_ctx->next_ctx = ring_ctx->next_ctx;
ring_ctx->next_ctx = new_ctx;
}
init_ctx(new_ctx, stack_size, f, args);
return new_ctx;
}
void yield()
{
assert(ring_ctx != NULL || current_ctx != NULL);
if (current_ctx == NULL)
switch_to_ctx(ring_ctx->next_ctx);
else
switch_to_ctx(current_ctx->next_ctx);
}