Skip to content

Instantly share code, notes, and snippets.

@shaliniJK
Created October 10, 2018 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shaliniJK/e56b59064b93582261c7cec906119245 to your computer and use it in GitHub Desktop.
Save shaliniJK/e56b59064b93582261c7cec906119245 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "switch.h"
#include "hardware.h"
#include "hwconfig.h"
struct ctx_s *ctx_courant = NULL;
struct ctx_s *ctx_ring = NULL;
int init_ctx (struct ctx_s *ctx, int stack_size, func_t f, void *args){
void *stack = malloc(stack_size);
assert(stack != NULL);
ctx -> ebp = stack+ stack_size - sizeof(void*);
ctx -> esp = ctx -> ebp;
ctx -> magic = CTX_MAGIC;
ctx -> stack_size = stack_size;
ctx -> arg = args;
ctx -> f = f;
ctx -> state = INIT;
return 0;
}
void switch_to_ctx(struct ctx_s *ctx)
{
assert(ctx -> magic == CTX_MAGIC);
/* Sauver le contexte courant */
if(ctx_courant != NULL){
asm("movl %%ebp, %0" "\n\t" "movl %%esp, %1"
:"=r"(ctx_courant -> ebp)
,"=r"(ctx_courant -> esp));
}
/* Sauvegarde le ctx donné en paramètre avant d'écraser la valeur des registres */
ctx_courant = ctx;
asm("movl %0, %%ebp"
"\n\t"
"movl %1, %%esp"
:
:"r"(ctx_courant -> ebp),
"r"(ctx_courant -> esp));
/* restaure/active un nouveau contexte */
if(ctx_courant -> state == INIT){
ctx_courant -> state = STARTED;
ctx_courant -> f(ctx_courant -> arg);
ctx_courant -> state = TERM;
yield();
} else {
return;
}
}
int create_ctx(int stack_size, func_t f, void *args){
struct ctx_s *old;
struct ctx_s *new;
new = malloc(sizeof(struct ctx_s));
assert(new != NULL);
init_ctx(new, stack_size, f, args);
if(ctx_courant != NULL){
old = ctx_courant;
}
else {
old = ctx_ring;
}
if(old != NULL){
new->next = old->next;
old->next = new;
} else {
ctx_ring = new;
new->next = new;
}
return 0;
}
void yield() {
assert(ctx_ring!=NULL || ctx_courant!=NULL);
if(ctx_courant != NULL){
while(ctx_courant->next->state == TERM){
assert(ctx_courant != ctx_courant->next);
struct ctx_s *tmp = ctx_courant->next;
ctx_courant->next = tmp->next;
free(tmp);
}
switch_to_ctx(ctx_courant->next);
} else {
switch_to_ctx(ctx_ring);
}
}
void start_sched(){
/*
- definir la fonction handler qui pour faire appel a yield
- utiliser irq_disable et irq_enable pour les code qui ne doivent pas etre interrompues
*/
}
#ifndef SWITCH_H
#define SWITCH_H
#define CTX_MAGIC 0xDEADBEEF
typedef void (func_t) (void*);
struct ctx_s {
void *ebp;
void *esp;
unsigned int magic;
int stack_size;
void *arg;
func_t *f;
enum state_e {INIT,STARTED,TERM} state;
struct ctx_s *next;
};
int init_ctx (struct ctx_s *ctx, int stack_size, func_t f, void *args);
void switch_to_ctx(struct ctx_s *ctx);
int create_ctx(int stack_size, func_t f, void *args);
void yield();
void start_sched();
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment