27#ifndef MRBC_SCHEDULER_EXIT
28#define MRBC_SCHEDULER_EXIT 0
31#define VM2TCB(p) ((mrbc_tcb *)((uint8_t *)p - offsetof(mrbc_tcb, vm)))
32#define MRBC_MUTEX_TRACE(...) ((void)0)
38#define NUM_TASK_QUEUE 4
40#define q_dormant_ (task_queue_[0])
41#define q_ready_ (task_queue_[1])
42#define q_waiting_ (task_queue_[2])
43#define q_suspended_ (task_queue_[3])
67 static const uint8_t conv_tbl[] = { 0, 1, 2, 0, 3 };
80 while( p->
next != NULL ) {
99 static const uint8_t conv_tbl[] = { 0, 1, 2, 0, 3 };
102 if( *pp_q == p_tcb ) {
110 if( p->
next == p_tcb ) {
119 assert(!
"Not found target task in queue.");
138#if defined(__EMSCRIPTEN__)
139#include <emscripten.h>
148 if( (tcb != NULL) && (tcb->
timeslice != 0) ) {
155 int flag_preemption = 0;
160 while( tcb != NULL ) {
206 if( !tcb )
return NULL;
208 memset(tcb, 0, size);
209#if defined(MRBC_DEBUG)
210 memcpy( tcb->obj_mark_,
"TCB", 4 );
213 tcb->
state = task_state;
230 if( !tcb )
return NULL;
289 if( (tcb->
name[i] = *name++) == 0 )
break;
307 if( strcmp( tcb->
name, name ) == 0 )
goto RETURN_TCB;
356#if MRBC_SCHEDULER_EXIT
367 tcb->
timeslice = MRBC_TIMESLICE_TICK_COUNT;
369#if !defined(MRBC_NO_TIMER)
380 if( ret_vm_run != 0 )
break;
389 if( ret_vm_run != 0 ) {
397 if( ret_vm_run != 1 ) ret = ret_vm_run;
438#if defined(__EMSCRIPTEN__)
452 tcb->
timeslice = MRBC_TIMESLICE_TICK_COUNT;
457 if (ret_vm_run != 0) {
533 switch( tcb->
state ) {
623 int flag_to_ready_state = (tcb->
reason == 0);
698 if( mutex == NULL ) {
700 if( mutex == NULL )
return NULL;
724 if( mutex->
lock == 0 ) {
734 if( mutex->
tcb == tcb ) {
765 if( !mutex->
lock )
return 1;
766 if( mutex->
tcb != tcb )
return 2;
824 if( mutex->
lock == 0 ) {
1012 tcb = *(
mrbc_tcb **)v[0].instance->data;
1055 tcb = *(
mrbc_tcb **)v[0].instance->data;
1063 if( n < 0 || n > 255 ) {
1086 tcb = *(
mrbc_tcb **)v[0].instance->data;
1100 static const char *status_name[] =
1101 {
"DORMANT",
"READY",
"WAITING ",
"",
"SUSPENDED" };
1102 static const char *reason_name[] =
1103 {
"",
"SLEEP",
"MUTEX",
"",
"JOIN" };
1131 tcb = *(
mrbc_tcb **)v[0].instance->data;
1165 tcb = *(
mrbc_tcb **)v[0].instance->data;
1264 const char *byte_code;
1270 if( argc >= 1 && v[1].tt !=
MRBC_TT_STRING )
goto ERROR_ARGUMENT;
1385 if( r == 0 )
return;
1388 assert(!
"Mutex recursive lock.");
1399 if( r == 0 )
return;
1402 assert(!
"Mutex unlock error. not owner or not locked.");
1469#include "_autogen_class_rrt0.h"
1481 static uint8_t flag_hal_init_called = 0;
1483 if( !flag_hal_init_called ) {
1485 flag_hal_init_called = 1;
1498 for(
int i = 0; i <
sizeof(rrt0_cls)/
sizeof(rrt0_cls[0]); i++ ) {
1524 if( p_tcb == NULL )
return;
1527 for(
const mrbc_tcb *t = p_tcb; t; t = t->next ) {
1529 t->name[0] ? t->name :
"(noname)" );
1535 for(
const mrbc_tcb *t = p_tcb; t; t = t->next ) {
1547 for(
const mrbc_tcb *t = p_tcb; t; t = t->next ) {
1555 (t1.
state & 0x02)?
'R':
'-',
1556 (t1.
state & 0x01)?
'r':
'-' );
1558 mrbc_printf(
" s%04b r%03b ", t->state, t->reason);
1564 for(
const mrbc_tcb *t = p_tcb; t; t = t->next ) {
1565 mrbc_printf(
" ts:%-2d fp:%d ", t->timeslice, t->vm.flag_preemption);
void * mrbc_raw_alloc(unsigned int size)
void mrbc_init_alloc(void *ptr, unsigned int size)
void mrbc_cleanup_alloc(void)
int mrbc_array_push(mrbc_value *ary, mrbc_value *set_val)
mrbc_value mrbc_array_new(struct VM *vm, int size)
static char * mrbc_string_cstr(const mrbc_value *v)
static mrbc_value mrbc_string_new_cstr(struct VM *vm, const char *src)
static int mrbc_string_append_cstr(mrbc_value *s1, const char *s2)
mrbc_value mrbc_instance_new(struct VM *vm, mrbc_class *cls, int size)
void mrbc_init_class(void)
void mrbc_define_method(struct VM *vm, mrbc_class *cls, const char *name, mrbc_func_t cfunc)
struct RClass mrbc_class
Class object.
void mrbc_printf(const char *fstr,...)
void mrbc_raise(struct VM *vm, struct RClass *exc_cls, const char *msg)
void mrbc_print_vm_exception(const struct VM *vm)
mrbc_value mrbc_exception_new(struct VM *vm, struct RClass *exc_cls, const void *message, int len)
void mrbc_init_global(void)
int mrbc_set_const(mrbc_sym sym_id, mrbc_value *v)
int mrbc_load_mrb(struct VM *vm, const void *bytecode)
Include at once the necessary header files.
void mrbc_join_task(mrbc_tcb *tcb, const mrbc_tcb *tcb_join)
static volatile uint32_t wakeup_tick_
void mrbc_set_task_name(mrbc_tcb *tcb, const char *name)
void mrbc_init(void *heap_ptr, unsigned int size)
void mrbc_terminate_task(mrbc_tcb *tcb)
void mrbc_resume_task(mrbc_tcb *tcb)
int mrbc_mutex_unlock(mrbc_mutex *mutex, mrbc_tcb *tcb)
mrbc_tcb * mrbc_tcb_new(int regs_size, enum MrbcTaskState task_state, int priority)
mrbc_tcb * mrbc_find_task(const char *name)
mrbc_tcb * mrbc_create_task(const void *byte_code, mrbc_tcb *tcb)
static void q_delete_task(mrbc_tcb *p_tcb)
static void q_insert_task(mrbc_tcb *p_tcb)
mrbc_mutex * mrbc_mutex_init(mrbc_mutex *mutex)
void mrbc_change_priority(mrbc_tcb *tcb, int priority)
void mrbc_sleep_ms(mrbc_tcb *tcb, uint32_t ms)
int mrbc_mutex_trylock(mrbc_mutex *mutex, mrbc_tcb *tcb)
int mrbc_mutex_lock(mrbc_mutex *mutex, mrbc_tcb *tcb)
static volatile uint32_t tick_
#define MRBC_MUTEX_TRACE(...)
void mrbc_suspend_task(mrbc_tcb *tcb)
void mrbc_wakeup_task(mrbc_tcb *tcb)
void mrbc_relinquish(mrbc_tcb *tcb)
static void preempt_running_task(void)
int mrbc_start_task(mrbc_tcb *tcb)
static mrbc_tcb * task_queue_[NUM_TASK_QUEUE]
static void c_sleep(mrbc_vm *vm, mrbc_value v[], int argc)
int mrbc_delete_task(mrbc_tcb *tcb)
struct RTcb mrbc_tcb
Task control block.
@ TASKSTATE_SUSPENDED
Suspended.
@ TASKSTATE_WAITING
Waiting.
@ TASKSTATE_RUNNING
Running.
@ TASKSTATE_DORMANT
Domant.
static const int MRBC_TASK_DEFAULT_STATE
struct RMutex mrbc_mutex
Mutex.
#define MRBC_TASK_NAME_LEN
#define MRBC_MUTEX_INITIALIZER
static const int MRBC_TASK_DEFAULT_PRIORITY
struct RMethod * method_link
pointer to method link.
struct RClass * super
pointer to super class.
mrbc_sym sym_id
class name's symbol ID
uint8_t data[]
extended data
struct RInstance * instance
uint8_t priority
task priority. initial value.
char name[MRBC_TASK_NAME_LEN+1]
task name (optional)
const struct RTcb * tcb_join
joined task.
uint8_t priority_preemption
task priority. effective value.
uint8_t state
task state. defined in MrbcTaskState.
volatile uint8_t timeslice
time slice counter.
uint8_t reason
sub state. defined in MrbcTaskReason.
uint32_t wakeup_tick
wakeup time for sleep state.
struct RTcb * next
daisy chain in task queue.
uint16_t regs_size
size of regs[]
volatile int8_t flag_preemption
mrbc_value exception
Raised exception or nil.
unsigned int flag_permanence
void mrbc_cleanup_symbol(void)
static void mrbc_decref(mrbc_value *v)
#define SET_BOOL_RETURN(n)
#define SET_INT_RETURN(n)
#define MRBC_PTR_TO_UINT32(p)
static void mrbc_incref(mrbc_value *v)
@ MRBC_TT_INTEGER
Integer.
@ MRBC_TT_EXCEPTION
Exception.
struct RObject mrbc_value
void mrbc_vm_end(struct VM *vm)
mrbc_vm * mrbc_vm_open(struct VM *vm)
void mrbc_vm_begin(struct VM *vm)
void mrbc_cleanup_vm(void)
int mrbc_vm_run(struct VM *vm)
void mrbc_vm_close(struct VM *vm)
struct VM mrbc_vm
Virtual Machine.
Global configuration of mruby/c VM's.