Select Git revision
Forked from
Gilles Grimaud / my-kernel
This fork has diverged from the upstream repository.
Thierno souleymane Bah authored
context.c 2.53 KiB
#include "context.h"
#include "utils.h"
ctx_t *current_ctx = NULL;
ctx_t *ring_ctx = NULL;
ctx_t *malloc_ctx()
{
int i;
for (i = 0; i < CTX_MAX && ctx_heap[i].used; i++)
;
if (i == CTX_MAX || ctx_heap[i].used)
return NULL;
ctx_heap[i].used = 1;
return &ctx_heap[i];
}
void free_ctx(ctx_t *ctx)
{
int i;
for (i = 0; i < CTX_MAX && (ctx_heap + i) == ctx; i++)
;
if (i == CTX_MAX || !ctx_heap[i].used)
return;
ctx_heap[i].used = 0;
}
int init_ctx(ctx_t *pctx, 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;
return 0;
}
void switch_to_ctx(ctx_t *pctx)
{
if (pctx->status == CTX_END || pctx->status == CTX_WAIT)
{
if (pctx->status == CTX_END)
{
// Si c'est l'unique ctx
if (pctx == pctx->next_ctx)
ring_ctx = NULL;
else
current_ctx->next_ctx = pctx->next_ctx;
free_ctx(pctx);
}
yield();
return;
}
assert(pctx->status != CTX_END && pctx->status != CTX_WAIT);
if (current_ctx != NULL)
{
// Sauvegarder où on en est avec le ctx courant
asm("mov %%esp, %0"
"\n\t"
"mov %%ebp, %1"
: "=r"(current_ctx->esp), "=r"(current_ctx->ebp));
}
current_ctx = pctx;
asm("mov %0, %%esp"
"\n\t"
"mov %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;
irq_enable();
current_ctx->f(current_ctx->args);
current_ctx->status = CTX_END;
puts("\nfunction termine\n");
yield();
}
ctx_t *create_ctx(funct_t f, void *args)
{
ctx_t *new_ctx = malloc_ctx();
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, f, args);
return new_ctx;
}
void yield()
{
irq_disable();
if (ring_ctx == NULL)
{
puts("\nSystem stopped\n");
for (;;)
;
}
if (current_ctx == NULL)
switch_to_ctx(ring_ctx->next_ctx);
else
switch_to_ctx(current_ctx->next_ctx);
irq_enable();
}
void start_sched() {}