experimenting with event driven mechanism

This commit is contained in:
hyunghwan.chung
2017-02-18 13:31:47 +00:00
parent be677dd53a
commit 607e6c8502
7 changed files with 144 additions and 42 deletions

View File

@ -99,6 +99,7 @@ static struct voca_t
{ 8, { '#','i','n','c','l','u','d','e' } },
{ 7, { '#','l','i','w','o','r','d' } },
{ 6, { 'm','e','t','h','o','d' } },
{ 7, { '#','n','a','t','i','v','e' } },
{ 3, { 'n','i','l' } },
{ 8, { '#','p','o','i','n','t','e','r' } },
{ 7, { 'p','o','o','l','d','i','c' } },
@ -144,6 +145,7 @@ enum voca_id_t
VOCA_INCLUDE_S,
VOCA_LIWORD_S,
VOCA_METHOD,
VOCA_NATIVE_S,
VOCA_NIL,
VOCA_POINTER_S,
VOCA_POOLDIC,
@ -5773,6 +5775,7 @@ static int compile_method_definition (moo_t* moo)
{
/* clear data required to compile a method */
moo->c->mth.type = MOO_METHOD_INSTANCE;
moo->c->mth.native = 0;
moo->c->mth.text.len = 0;
moo->c->mth.assignees.len = 0;
moo->c->mth.binsels.len = 0;
@ -5794,6 +5797,7 @@ static int compile_method_definition (moo_t* moo)
if (TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN)
{
/* process method modifiers */
next_modifier:
GET_TOKEN (moo);
if (is_token_symbol(moo, VOCA_CLASS_S))
@ -5802,6 +5806,17 @@ static int compile_method_definition (moo_t* moo)
moo->c->mth.type = MOO_METHOD_CLASS;
GET_TOKEN (moo);
}
else if (is_token_symbol(moo, VOCA_NATIVE_S))
{
/* method(#native) */
moo->c->mth.native = 1;
GET_TOKEN (moo);
}
if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA)
{
goto next_modifier;
}
if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
{
@ -5815,27 +5830,40 @@ static int compile_method_definition (moo_t* moo)
if (compile_method_name(moo) <= -1) return -1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE)
if (moo->c->mth.native)
{
/* { expected */
set_syntax_error (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD)
{
/* . expected */
set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
}
else
{
if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE)
{
/* { expected */
set_syntax_error (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
GET_TOKEN (moo);
if (compile_method_temporaries(moo) <= -1 ||
compile_method_primitive(moo) <= -1 ||
compile_method_statements(moo) <= -1) return -1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
{
/* } expected */
set_syntax_error (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
}
GET_TOKEN (moo);
if (compile_method_temporaries(moo) <= -1 ||
compile_method_primitive(moo) <= -1 ||
compile_method_statements(moo) <= -1) return -1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
{
/* } expected */
set_syntax_error (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
GET_TOKEN (moo);
/* add a compiled method to the method dictionary */
if (add_compiled_method(moo) <= -1) return -1;

View File

@ -557,6 +557,8 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
unchain_from_semaphore (moo, proc);
resume_process (moo, proc); /* TODO: error check */
if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count--;
/* return the resumed(runnable) process */
return proc;
}
@ -587,6 +589,8 @@ static void await_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
MOO_ASSERT (moo, sem->waiting_tail == proc);
if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count++;
MOO_ASSERT (moo, moo->processor->active != proc);
}
}
@ -789,7 +793,6 @@ MOO_DEBUG1 (moo, "ADDED TO SEM IO => sem_io_count => %d\n", (int)moo->sem_io_cou
static void delete_from_sem_io (moo_t* moo, moo_ooi_t index)
{
moo_oop_semaphore_t sem, lastsem;
sem = moo->sem_io[index];
@ -835,6 +838,7 @@ static void signal_io_semaphore (moo_t* moo, int mask, void* ctx)
wake_new_process (moo, proc); /* switch to running */
moo->proc_switched = 1;
}
}
else
{
@ -2172,17 +2176,17 @@ static moo_pfrc_t __processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, int
static moo_pfrc_t pf_processor_add_input_semaphore (moo_t* moo, moo_ooi_t nargs)
{
return __processor_add_io_semaphore (moo, nargs, 1);
return __processor_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_INPUT);
}
static moo_pfrc_t pf_processor_add_output_semaphore (moo_t* moo, moo_ooi_t nargs)
{
return __processor_add_io_semaphore (moo, nargs, 2);
return __processor_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_OUTPUT);
}
static moo_pfrc_t pf_processor_add_inoutput_semaphore (moo_t* moo, moo_ooi_t nargs)
{
return __processor_add_io_semaphore (moo, nargs, 3);
return __processor_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_INPUT | MOO_SEMAPHORE_IO_MASK_OUTPUT);
}
static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
@ -3156,7 +3160,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
/* no running process */
MOO_SUBNTIME (&ft, &ft, (moo_ntime_t*)&now);
if (moo->sem_io_count > 0)
if (moo->sem_io_wait_count > 0)
{
MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_WAIT()\n");
vm_mux_wait (moo, &ft);
@ -3177,7 +3181,11 @@ MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_SLEEP()\n");
while (moo->sem_heap_count > 0 && !moo->abort_req);
}
if (moo->sem_io_count > 0) vm_mux_wait (moo, MOO_NULL);
if (moo->sem_io_wait_count > 0)
{
MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_WAIT 222()\n");
vm_mux_wait (moo, MOO_NULL);
}
if (moo->processor->active == moo->nil_process)
{
@ -3239,6 +3247,13 @@ int moo_execute (moo_t* moo)
MOO_ASSERT (moo, moo->active_context != MOO_NULL);
/* TODO: initialize semaphore stuffs
* sem_heap
* sem_io.
* sem_list.
* these can be dirty if this function is called again esepcially after failure.
*/
if (vm_startup(moo) <= -1) goto oops;
vm_startup_called = 1;

View File

@ -832,9 +832,10 @@ static int mux_add (moo_t* moo, moo_oop_semaphore_t sem)
MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_mask));
mask = MOO_OOP_TO_SMOOI(sem->io_mask);
ev.events = 0;
if (mask & 1) ev.events |= EPOLLIN; /*TODO: define io mask constants... */
if (mask & 2) ev.events |= EPOLLOUT;
ev.events = EPOLLET; /* edge trigger */
if (mask & MOO_SEMAPHORE_IO_MASK_INPUT) ev.events |= EPOLLIN; /*TODO: define io mask constants... */
if (mask & MOO_SEMAPHORE_IO_MASK_OUTPUT) ev.events |= EPOLLOUT;
/* don't check MOO_SEMAPHORE_IO_MASK_ERROR and MOO_SEMAPHORE_IO_MASK_HANGUP as it's implicitly enabled by epoll() */
ev.data.ptr = (void*)MOO_OOP_TO_SMOOI(sem->io_index);
if (ev.events == 0)
@ -882,10 +883,10 @@ static void mux_wait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_cb_
--n;
mask = 0;
if (ev[n].events & EPOLLIN) mask |= 1; /* TODO define constants for IO Mask */
if (ev[n].events & EPOLLOUT) mask |= 2;
if (ev[n].events & EPOLLERR) mask |= 4;
if (ev[n].events & EPOLLHUP) mask |= 8;
if (ev[n].events & EPOLLIN) mask |= MOO_SEMAPHORE_IO_MASK_INPUT; /* TODO define constants for IO Mask */
if (ev[n].events & EPOLLOUT) mask |= MOO_SEMAPHORE_IO_MASK_OUTPUT;
if (ev[n].events & EPOLLERR) mask |= MOO_SEMAPHORE_IO_MASK_ERROR;
if (ev[n].events & EPOLLHUP) mask |= MOO_SEMAPHORE_IO_MASK_HANGUP;
muxwcb (moo, mask, ev[n].data.ptr);
}

View File

@ -475,6 +475,7 @@ struct moo_compiler_t
struct
{
moo_method_type_t type;
int native;
/* method source text */
moo_oocs_t text;

View File

@ -162,6 +162,7 @@ void moo_fini (moo_t* moo)
moo_freemem (moo, moo->sem_io);
moo->sem_io_capa = 0;
moo->sem_io_count = 0;
moo->sem_io_wait_count = 0;
}
for (cb = moo->cblist; cb; cb = cb->next)
@ -173,6 +174,7 @@ void moo_fini (moo_t* moo)
moo_rbt_fini (&moo->modtab);
/* TOOD: persistency? storing objects to image file? */
moo_killheap (moo, moo->newheap);
moo_killheap (moo, moo->curheap);
moo_killheap (moo, moo->permheap);

View File

@ -684,6 +684,11 @@ struct moo_process_t
moo_oop_t slot[1]; /* process stack */
};
#define MOO_SEMAPHORE_IO_MASK_INPUT 1
#define MOO_SEMAPHORE_IO_MASK_OUTPUT 2
#define MOO_SEMAPHORE_IO_MASK_HANGUP 4
#define MOO_SEMAPHORE_IO_MASK_ERROR 8
struct moo_semaphore_t
{
MOO_OBJ_HEADER;
@ -1004,6 +1009,7 @@ struct moo_t
moo_oop_semaphore_t* sem_io;
moo_oow_t sem_io_count;
moo_oow_t sem_io_capa;
moo_oow_t sem_io_wait_count;
moo_oop_t* tmp_stack[256]; /* stack for temporaries */
moo_oow_t tmp_count;