Skip to content
Snippets Groups Projects
Select Git revision
  • f74f7cc959d461dce9172ce8c09e0a483b298548
  • master default protected
  • sem_ping_pong
  • demo_sched
4 results

context.c

Blame
  • Forked from Gilles Grimaud / my-kernel
    This fork has diverged from the upstream repository.
    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() {}