forked from M-Labs/artiq
soc/runtime: fix use of setjmp
This commit is contained in:
parent
3de24619b2
commit
b37ceb328f
|
@ -1,32 +1,33 @@
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
|
|
||||||
static struct exception_env *env_top;
|
#define MAX_EXCEPTION_CONTEXTS 64
|
||||||
|
|
||||||
|
struct exception_context {
|
||||||
|
void *jb[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct exception_context exception_contexts[MAX_EXCEPTION_CONTEXTS];
|
||||||
|
static int ec_top;
|
||||||
static int stored_id;
|
static int stored_id;
|
||||||
|
|
||||||
int exception_catch(struct exception_env *ee, int *id)
|
void *exception_push(void)
|
||||||
{
|
{
|
||||||
ee->prev = env_top;
|
if(ec_top >= MAX_EXCEPTION_CONTEXTS)
|
||||||
env_top = ee;
|
exception_raise(EID_NOMEM);
|
||||||
if(setjmp(env_top->jb)) {
|
return exception_contexts[ec_top++].jb;
|
||||||
*id = stored_id;
|
|
||||||
return 1;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void exception_pop(void)
|
void exception_pop(void)
|
||||||
{
|
{
|
||||||
env_top = env_top->prev;
|
ec_top--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exception_getid(void)
|
||||||
|
{
|
||||||
|
return stored_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exception_raise(int id)
|
void exception_raise(int id)
|
||||||
{
|
{
|
||||||
struct exception_env *ee;
|
__builtin_longjmp(exception_contexts[--ec_top].jb, 1);
|
||||||
|
|
||||||
ee = env_top;
|
|
||||||
env_top = env_top->prev;
|
|
||||||
stored_id = id; /* __builtin_longjmp needs its second argument set to 1 */
|
|
||||||
longjmp(ee->jb, 1);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
#ifndef __EXCEPTIONS_H
|
#ifndef __EXCEPTIONS_H
|
||||||
#define __EXCEPTIONS_H
|
#define __EXCEPTIONS_H
|
||||||
|
|
||||||
#include <setjmp.h>
|
enum {
|
||||||
|
EID_NOMEM = 0
|
||||||
struct exception_env {
|
|
||||||
jmp_buf jb;
|
|
||||||
struct exception_env *prev;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int exception_catch(struct exception_env *ee, int *id);
|
void *exception_push(void);
|
||||||
void exception_pop(void);
|
void exception_pop(void);
|
||||||
|
int exception_getid(void);
|
||||||
void exception_raise(int id) __attribute__((noreturn));
|
void exception_raise(int id) __attribute__((noreturn));
|
||||||
|
|
||||||
#endif /* __EXCEPTIONS_H */
|
#endif /* __EXCEPTIONS_H */
|
||||||
|
|
|
@ -68,8 +68,7 @@ typedef void (*kernel_function)(void);
|
||||||
static int run_kernel(const char *kernel_name, int *eid)
|
static int run_kernel(const char *kernel_name, int *eid)
|
||||||
{
|
{
|
||||||
kernel_function k;
|
kernel_function k;
|
||||||
struct exception_env ee;
|
void *jb;
|
||||||
int exception_occured;
|
|
||||||
|
|
||||||
k = find_symbol(symtab, kernel_name);
|
k = find_symbol(symtab, kernel_name);
|
||||||
if(k == NULL) {
|
if(k == NULL) {
|
||||||
|
@ -77,10 +76,11 @@ static int run_kernel(const char *kernel_name, int *eid)
|
||||||
return KERNEL_RUN_STARTUP_FAILED;
|
return KERNEL_RUN_STARTUP_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
exception_occured = exception_catch(&ee, eid);
|
jb = exception_push();
|
||||||
if(exception_occured)
|
if(__builtin_setjmp(jb)) {
|
||||||
|
*eid = exception_getid();
|
||||||
return KERNEL_RUN_EXCEPTION;
|
return KERNEL_RUN_EXCEPTION;
|
||||||
else {
|
} else {
|
||||||
rtio_init();
|
rtio_init();
|
||||||
flush_cpu_icache();
|
flush_cpu_icache();
|
||||||
k();
|
k();
|
||||||
|
|
Loading…
Reference in New Issue