enabled the compiler to support a class name as a namespace.

started adding code for event-driven IO handling
This commit is contained in:
hyunghwan.chung
2017-02-12 18:59:03 +00:00
parent 2c8eb87408
commit 4c13989947
17 changed files with 717 additions and 72 deletions

View File

@ -79,7 +79,7 @@ bin_PROGRAMS = moo
moo_SOURCES = main.c
moo_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
moo_LDFLAGS = $(LDFLAGS_LIB_COMMON)
moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo
moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo -lxcb
install-data-hook:

View File

@ -453,7 +453,7 @@ libmoo_la_LIBADD = $(LIBADD_LIB_COMMON) $(am__append_5)
moo_SOURCES = main.c
moo_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
moo_LDFLAGS = $(LDFLAGS_LIB_COMMON)
moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo
moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo -lxcb
all: moo-cfg.h
$(MAKE) $(AM_MAKEFLAGS) all-am

View File

@ -287,7 +287,13 @@ static int is_reserved_word (const moo_oocs_t* ucs)
VOCA_ERROR,
VOCA_THIS_CONTEXT,
VOCA_THIS_PROCESS,
VOCA_IF
VOCA_IF,
VOCA_ELSE,
VOCA_ELSIF,
VOCA_WHILE,
VOCA_DO,
VOCA_BREAK,
VOCA_CONTINUE
};
int i;
@ -2737,6 +2743,34 @@ oops:
return MOO_NULL;
}
static moo_oop_set_t add_nsdic_to_class (moo_t* moo, moo_oop_class_t c, const moo_oocs_t* name)
{
moo_oow_t tmp_count = 0;
moo_oop_t sym;
moo_oop_set_t ns;
moo_pushtmp (moo, (moo_oop_t*)&c); tmp_count++;
sym = moo_makesymbol (moo, name->ptr, name->len);
if (!sym) goto oops;
moo_pushtmp (moo, &sym); tmp_count++;
ns = moo_makedic (moo, moo->_namespace, NAMESPACE_SIZE);
if (!ns) goto oops;
/*moo_pushtmp (moo, &ns); tmp_count++;*/
c->nsdic = ns;
moo_poptmps (moo, tmp_count);
return ns;
oops:
moo_poptmps (moo, tmp_count);
return MOO_NULL;
}
static int preprocess_dotted_name (moo_t* moo, int dont_add_ns, int accept_pooldic_as_ns, const moo_oocs_t* fqn, const moo_ioloc_t* fqn_loc, moo_oocs_t* name, moo_oop_set_t* ns_oop)
{
const moo_ooch_t* ptr, * dot;
@ -2769,9 +2803,33 @@ static int preprocess_dotted_name (moo_t* moo, int dont_add_ns, int accept_poold
if (MOO_CLASSOF(moo, ass->value) == moo->_namespace ||
(seg.ptr == fqn->ptr && ass->value == (moo_oop_t)moo->sysdic))
{
/* ok */
/* ok - the current segment is a namespace name or
* it is the first segment and is System */
dic = (moo_oop_set_t)ass->value;
}
else if (MOO_CLASSOF(moo, ass->value) == moo->_class)
{
/* the segment is a class name. use the nsdic field.
* class X {}
* class X.Y {}
* when processing X in X.Y, this part is reached. */
dic = ((moo_oop_class_t)ass->value)->nsdic;
if ((moo_oop_t)dic == moo->_nil)
{
/* the nsdic field is still nil. no namespace dictionary
* has been attached to the class */
moo_oop_set_t t;
if (dont_add_ns) goto wrong_name;
/* attach a new namespace dictionary to the nsdic field
* of the class */
t = add_nsdic_to_class (moo, (moo_oop_class_t)ass->value, &seg);
if (!t) return -1;
dic = t;
}
}
else
{
if (accept_pooldic_as_ns && MOO_CLASSOF(moo, ass->value) == moo->_pool_dictionary)

View File

@ -32,10 +32,14 @@
#define PROC_STATE_SUSPENDED 0
#define PROC_STATE_TERMINATED -1
/* TODO: adjust these max semaphore pointer buffer capacity,
* proably depending on the object memory size? */
#define SEM_LIST_INC 256
#define SEM_HEAP_INC 256
#define SEM_IO_INC 256
#define SEM_LIST_MAX (SEM_LIST_INC * 1000)
#define SEM_HEAP_MAX (SEM_HEAP_INC * 1000)
#define SEM_IO_MAX (SEM_IO_INC * 1000)
#define SEM_HEAP_PARENT(x) (((x) - 1) / 2)
#define SEM_HEAP_LEFT(x) ((x) * 2 + 1)
@ -59,8 +63,7 @@
#define STORE_ACTIVE_SP(moo) STORE_SP(moo, (moo)->processor->active)
#define SWITCH_ACTIVE_CONTEXT(moo,v_ctx) \
do \
{ \
do { \
STORE_ACTIVE_IP (moo); \
(moo)->active_context = (v_ctx); \
(moo)->active_method = (moo_oop_method_t)(moo)->active_context->origin->method_or_nargs; \
@ -105,12 +108,27 @@
#endif
/* ------------------------------------------------------------------------- */
static MOO_INLINE int vm_startup (moo_t* moo)
{
if (moo->vmprim.vm_startup (moo) <= -1) return -1;
moo->vmprim.vm_gettime (moo, &moo->exec_start_time); /* raw time. no adjustment */
return 0;
}
static MOO_INLINE void vm_cleanup (moo_t* moo)
{
moo->vmprim.vm_gettime (moo, &moo->exec_end_time); /* raw time. no adjustment */
moo->vmprim.vm_cleanup (moo);
}
static MOO_INLINE void vm_gettime (moo_t* moo, moo_ntime_t* now)
{
moo->vmprim.vm_gettime (moo, now);
/* in vm_startup(), moo->exec_start_time has been set to the time of
* that moment. time returned here becomes relative to moo->exec_start_time
* and is kept small such that it can get reprensed in a small integer */
* that moment. time returned here get offset by moo->exec_start_time and
* thus becomes relative to it. this way, it is kept small such that it
* can be represented in a small integer with leaving almost zero chance
* of overflow. */
MOO_SUBNTIME (now, now, &moo->exec_start_time); /* now = now - exec_start_time */
}
@ -119,16 +137,9 @@ static MOO_INLINE void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
moo->vmprim.vm_sleep (moo, dur);
}
static MOO_INLINE void vm_startup (moo_t* moo)
static MOO_INLINE void vm_mux_wait (moo_t* moo, const moo_ntime_t* dur)
{
moo->vmprim.vm_startup (moo);
moo->vmprim.vm_gettime (moo, &moo->exec_start_time);
}
static MOO_INLINE void vm_cleanup (moo_t* moo)
{
vm_gettime (moo, &moo->exec_end_time);
moo->vmprim.vm_cleanup (moo);
moo->vmprim.mux_wait (moo, dur);
}
/* ------------------------------------------------------------------------- */
@ -539,10 +550,12 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
/* [NOTE] no GC must occur as 'proc' isn't protected with moo_pushtmp(). */
/* detach a process from a semaphore waiting list and
* make it runnable */
unchain_from_semaphore (moo, proc);
resume_process (moo, proc); /* TODO: error check */
/* return the resumed process */
/* return the resumed(runnable) process */
return proc;
}
}
@ -706,6 +719,8 @@ static void delete_from_sem_heap (moo_t* moo, moo_ooi_t index)
}
}
#if 0
/* unused */
static void update_sem_heap (moo_t* moo, moo_ooi_t index, moo_oop_semaphore_t newsem)
{
moo_oop_semaphore_t sem;
@ -721,6 +736,67 @@ static void update_sem_heap (moo_t* moo, moo_ooi_t index, moo_oop_semaphore_t ne
else
sift_down_sem_heap (moo, index);
}
#endif
static int add_to_sem_io (moo_t* moo, moo_oop_semaphore_t sem)
{
moo_ooi_t index;
if (moo->sem_io_count >= SEM_IO_MAX)
{
moo->errnum = MOO_ESHFULL;
return -1;
}
if (moo->sem_io_count >= moo->sem_io_capa)
{
moo_oow_t new_capa;
moo_oop_semaphore_t* tmp;
/* no overflow check when calculating the new capacity
* owing to SEM_IO_MAX check above */
new_capa = moo->sem_io_capa + SEM_IO_INC;
tmp = moo_reallocmem (moo, moo->sem_io, MOO_SIZEOF(moo_oop_semaphore_t) * new_capa);
if (!tmp) return -1;
moo->sem_io = tmp;
moo->sem_io_capa = new_capa;
}
MOO_ASSERT (moo, moo->sem_io_count <= MOO_SMOOI_MAX);
if (moo->vmprim.mux_add (moo) <= -1) /*TODO: pass data */
{
return -1;
}
index = moo->sem_io_count;
moo->sem_io[index] = sem;
sem->heap_index = MOO_SMOOI_TO_OOP(index);
moo->sem_io_count++;
return 0;
}
static void delete_from_sem_io (moo_t* moo, moo_ooi_t index)
{
moo_oop_semaphore_t sem, lastsem;
sem = moo->sem_io[index];
sem->io_index = MOO_SMOOI_TO_OOP(-1);
moo->vmprim.mux_del (moo); /* TODO: pass data... */
moo->sem_io_count--;
if (moo->sem_io_count > 0 && index != moo->sem_io_count)
{
/* move the last item to the deletion position */
lastsem = moo->sem_io[moo->sem_io_count];
lastsem->io_index = MOO_SMOOI_TO_OOP(index);
moo->sem_io[index] = lastsem;
}
}
static moo_oop_process_t start_initial_process (moo_t* moo, moo_oop_context_t c)
{
@ -1984,13 +2060,15 @@ static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs)
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
rcv = MOO_STACK_GETRCV(moo, nargs);
if (rcv != (moo_oop_t)moo->processor) return MOO_PF_FAILURE;
if (MOO_CLASSOF(moo,sem) != moo->_semaphore) return MOO_PF_FAILURE;
if (!MOO_OOP_IS_SMOOI(sec)) return MOO_PF_FAILURE;
/* ProcessScheduler>>signal:after: calls this primitive function. */
if (rcv != (moo_oop_t)moo->processor ||
MOO_CLASSOF(moo,sem) != moo->_semaphore ||
!MOO_OOP_IS_SMOOI(sec)) return MOO_PF_FAILURE;
if (MOO_OOP_IS_SMOOI(sem->heap_index) &&
sem->heap_index != MOO_SMOOI_TO_OOP(-1))
{
/* if the semaphore is already been added. remove it first */
delete_from_sem_heap (moo, MOO_OOP_TO_SMOOI(sem->heap_index));
MOO_ASSERT (moo, sem->heap_index == MOO_SMOOI_TO_OOP(-1));
@ -2002,7 +2080,7 @@ static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs)
}
/* this code assumes that the monotonic clock returns a small value
* that can fit into a SmallInteger, even after some additions... */
* that can fit into a SmallInteger, even after some additions. */
vm_gettime (moo, &now);
MOO_ADDNTIMESNS (&ft, &now, MOO_OOP_TO_SMOOI(sec), MOO_OOP_TO_SMOOI(nsec));
if (ft.sec < 0 || ft.sec > MOO_SMOOI_MAX)
@ -2024,6 +2102,42 @@ static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, sec, nsec;
moo_oop_semaphore_t sem;
MOO_ASSERT (moo, nargs == 3);
nsec = MOO_STACK_GETARG (moo, nargs, 2);
if (!MOO_OOP_IS_SMOOI(nsec)) return MOO_PF_FAILURE;
sec = MOO_STACK_GETARG(moo, nargs, 1);
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
rcv = MOO_STACK_GETRCV(moo, nargs);
/* ProcessScheduler>>signal:after: calls this primitive function. */
if (rcv != (moo_oop_t)moo->processor ||
MOO_CLASSOF(moo,sem) != moo->_semaphore ||
!MOO_OOP_IS_SMOOI(sec)) return MOO_PF_FAILURE;
if (MOO_OOP_IS_SMOOI(sem->io_index) &&
sem->io_index != MOO_SMOOI_TO_OOP(-1))
{
/* remove it if it's already added for IO */
delete_from_sem_io (moo, MOO_OOP_TO_SMOOI(sem->io_index));
MOO_ASSERT (moo, sem->io_index == MOO_SMOOI_TO_OOP(-1));
}
/* TOOD: sanity check on argument 2 and 3 */
sem->io_data = MOO_STACK_GETARG(moo, nargs, 1);
sem->io_mask = MOO_STACK_GETARG(moo, nargs, 2);
if (add_to_sem_io (moo, sem) <= -1) return MOO_PF_HARD_FAILURE;
MOO_STACK_SETRETTORCV (moo, nargs); /* ^self */
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
{
/* remove a semaphore from processor's signal scheduling */
@ -2050,6 +2164,13 @@ static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
MOO_ASSERT (moo, sem->heap_index == MOO_SMOOI_TO_OOP(-1));
}
if (MOO_OOP_IS_SMOOI(sem->io_index) &&
sem->io_index != MOO_SMOOI_TO_OOP(-1))
{
delete_from_sem_io (moo, MOO_OOP_TO_SMOOI(sem->heap_index));
MOO_ASSERT (moo, sem->io_index == MOO_SMOOI_TO_OOP(-1));
}
MOO_STACK_SETRETTORCV (moo, nargs); /* ^self */
return MOO_PF_SUCCESS;
}
@ -2564,6 +2685,7 @@ static pf_t pftab[] =
{ 1, 1, pf_processor_schedule, "_processor_schedule" },
{ 2, 3, pf_processor_add_timed_semaphore, "_processor_add_timed_semaphore" },
{ 3, 3, pf_processor_add_io_semaphore, "_processor_add_io_semaphore" },
{ 1, 1, pf_processor_remove_semaphore, "_processor_remove_semaphore" },
{ 2, 2, pf_processor_return_to, "_processor_return_to" },
@ -2918,7 +3040,9 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
{
if (moo->sem_heap_count > 0)
{
/* handle timed semaphores */
moo_ntime_t ft, now;
vm_gettime (moo, &now);
do
@ -2956,24 +3080,32 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
MOO_ASSERT (moo, proc == moo->processor->runnable_head);
wake_new_process (moo, proc);
wake_new_process (moo, proc); /* switch to running */
moo->proc_switched = 1;
}
}
else if (moo->processor->active == moo->nil_process)
{
/* no running process */
MOO_SUBNTIME (&ft, &ft, (moo_ntime_t*)&now);
vm_sleep (moo, &ft); /* TODO: change this to i/o multiplexer??? */
if (moo->sem_io_count > 0)
vm_mux_wait (moo, &ft);
else
vm_sleep (moo, &ft); /* TODO: change this to i/o multiplexer??? */
vm_gettime (moo, &now);
}
else
{
/* there is a running process. go on */
break;
}
}
while (moo->sem_heap_count > 0);
while (moo->sem_heap_count > 0 && !moo->abort_req);
}
if (moo->sem_io_count > 0) vm_mux_wait (moo, MOO_NULL);
if (moo->processor->active == moo->nil_process)
{
/* no more waiting semaphore and no more process */
@ -3034,11 +3166,13 @@ int moo_execute (moo_t* moo)
MOO_ASSERT (moo, moo->active_context != MOO_NULL);
vm_startup (moo);
if (vm_startup(moo) <= -1) goto oops;
vm_startup_called = 1;
moo->proc_switched = 0;
while (1)
moo->proc_switched = 0;
moo->abort_req = 0;
while (!moo->abort_req)
{
if (switch_process_if_needed(moo) == 0) break; /* no more runnable process */
@ -4157,7 +4291,6 @@ int moo_execute (moo_t* moo)
}
done:
vm_cleanup (moo);
#if defined(MOO_PROFILE_VM)
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_INFO, "TOTAL_INST_COUTNER = %zu\n", inst_counter);
@ -4169,6 +4302,11 @@ oops:
return -1;
}
int moo_abort (moo_t* moo)
{
moo->abort_req = 1;
}
int moo_invoke (moo_t* moo, const moo_oocs_t* objname, const moo_oocs_t* mthname)
{
int n;

View File

@ -626,6 +626,11 @@ void moo_gc (moo_t* moo)
moo->sem_heap[i] = (moo_oop_semaphore_t)moo_moveoop (moo, (moo_oop_t)moo->sem_heap[i]);
}
for (i = 0; i < moo->sem_io_count; i++)
{
moo->sem_io[i] = (moo_oop_semaphore_t)moo_moveoop (moo, (moo_oop_t)moo->sem_io[i]);
}
for (i = 0; i < moo->tmp_count; i++)
{
*moo->tmp_stack[i] = moo_moveoop (moo, *moo->tmp_stack[i]);

View File

@ -75,6 +75,8 @@
# if defined(HAVE_SIGNAL_H)
# include <signal.h>
# endif
# include <sys/epoll.h>
#endif
#if !defined(MOO_DEFAULT_PFMODPREFIX)
@ -118,6 +120,8 @@ struct xtn_t
const char* source_path; /* main source file */
#if defined(_WIN32)
HANDLE waitable_timer;
#else
int ep; /* epoll */
#endif
};
@ -616,6 +620,56 @@ if (mask & MOO_LOG_GC) return; /* don't show gc logs */
/* ========================================================================= */
static int vm_startup (moo_t* moo)
{
#if defined(_WIN32)
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
xtn->waitable_timer = CreateWaitableTimer(MOO_NULL, TRUE, MOO_NULL);
#else
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
xtn->ep = epoll_create1 (EPOLL_CLOEXEC);
if (xtn->ep == -1)
{
MOO_DEBUG0 (moo, "Cannot create epoll\n");
moo_syserrtoerrnum (errno);
goto oops;
}
return 0;
oops:
if (xtn->ep >= 0)
{
close (xtn->ep);
xtn->ep = -1;
}
return -1;
#endif
}
static void vm_cleanup (moo_t* moo)
{
#if defined(_WIN32)
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
if (xtn->waitable_timer)
{
CloseHandle (xtn->waitable_timer);
xtn->waitable_timer = MOO_NULL;
}
#else
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
if (xtn->ep)
{
close (xtn->ep);
xtn->ep = -1;
}
#endif
}
static void vm_gettime (moo_t* moo, moo_ntime_t* now)
{
#if defined(_WIN32)
@ -729,6 +783,7 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
}
#else
struct timespec ts;
ts.tv_sec = dur->sec;
ts.tv_nsec = dur->nsec;
@ -736,26 +791,43 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
#endif
}
static void vm_startup (moo_t* moo)
static int mux_add (moo_t* moo)
{
#if defined(_WIN32)
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
xtn->waitable_timer = CreateWaitableTimer(MOO_NULL, TRUE, MOO_NULL);
#endif
}
struct epoll_event ev;
static void vm_cleanup (moo_t* moo)
{
#if defined(_WIN32)
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
if (xtn->waitable_timer)
ev.events = EPOLLIN | EPOLLOUT;
ev.data.u64 = 10;
/*
if (epoll_ctl (xtn->ep, EPOLL_CTL_DEL, 000, &ev) == -1)
{
CloseHandle (xtn->waitable_timer);
xtn->waitable_timer = MOO_NULL;
moo_syserrtoerrnum (errno);
return -1;
}
#endif
*/
return 0;
}
static void mux_del (moo_t* moo)
{
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
struct epoll_event ev;
/* epoll_ctl (xtn->ep, EPOLL_CTL_DEL, 00, &ev);*/
}
static void mux_wait (moo_t* moo, const moo_ntime_t* dur)
{
xtn_t* xtn = (xtn_t*)moo_getxtn(moo);
int tmout = 0;
if (dur) tmout = MOO_SECNSEC_TO_MSEC(dur->sec, dur->nsec);
/*
if (epoll_wait (xtn->ep, xtn->evt_ptr, xtn->evt_capa, tmout) > 0)
{
}
*/
}
/* ========================================================================= */
static moo_t* g_moo = MOO_NULL;
@ -902,10 +974,14 @@ int main (int argc, char* argv[])
vmprim.dl_close = dl_close;
vmprim.dl_getsym = dl_getsym;
vmprim.log_write = log_write;
vmprim.vm_gettime = vm_gettime;
vmprim.vm_sleep = vm_sleep;
vmprim.vm_startup = vm_startup;
vmprim.vm_cleanup = vm_cleanup;
vmprim.vm_gettime = vm_gettime;
vmprim.vm_sleep = vm_sleep;
vmprim.mux_add = mux_add;
vmprim.mux_del = mux_del;
vmprim.mux_wait = mux_wait;
#if defined(USE_LTDL)
lt_dlinit ();

View File

@ -157,6 +157,13 @@ void moo_fini (moo_t* moo)
moo->sem_heap_count = 0;
}
if (moo->sem_io)
{
moo_freemem (moo, moo->sem_io);
moo->sem_io_capa = 0;
moo->sem_io_count = 0;
}
for (cb = moo->cblist; cb; cb = cb->next)
{
if (cb->fini) cb->fini (moo);

View File

@ -442,7 +442,7 @@ struct moo_set_t
moo_oop_oop_t bucket; /* Array */
};
#define MOO_CLASS_NAMED_INSTVARS 11
#define MOO_CLASS_NAMED_INSTVARS 12
typedef struct moo_class_t moo_class_t;
typedef struct moo_class_t* moo_oop_class_t;
struct moo_class_t
@ -469,6 +469,9 @@ struct moo_class_t
* [1] - class methods, MethodDictionary */
moo_oop_set_t mthdic[MOO_METHOD_TYPE_COUNT];
/* dictionary used for namespacing */
moo_oop_set_t nsdic;
/* indexed part afterwards */
moo_oop_t slot[1]; /* class instance variables and class variables. */
};
@ -648,7 +651,7 @@ struct moo_context_t
typedef struct moo_process_t moo_process_t;
typedef struct moo_process_t* moo_oop_process_t;
#define MOO_SEMAPHORE_NAMED_INSTVARS 6
#define MOO_SEMAPHORE_NAMED_INSTVARS 9
typedef struct moo_semaphore_t moo_semaphore_t;
typedef struct moo_semaphore_t* moo_oop_semaphore_t;
@ -673,12 +676,18 @@ struct moo_process_t
struct moo_semaphore_t
{
MOO_OBJ_HEADER;
moo_oop_t count; /* SmallInteger */
moo_oop_process_t waiting_head;
moo_oop_process_t waiting_tail;
moo_oop_t heap_index; /* index to the heap */
moo_oop_t heap_ftime_sec; /* firing time */
moo_oop_t heap_ftime_nsec; /* firing time */
moo_oop_t io_index;
moo_oop_t io_data;
moo_oop_t io_mask; /* SmallInteger */
};
#define MOO_PROCESS_SCHEDULER_NAMED_INSTVARS 5
@ -733,28 +742,36 @@ enum moo_vmprim_opendl_flag_t
};
typedef enum moo_vmprim_opendl_flag_t moo_vmprim_opendl_flag_t;
typedef void* (*moo_vmprim_opendl_t) (moo_t* moo, const moo_ooch_t* name, int flags);
typedef void (*moo_vmprim_closedl_t) (moo_t* moo, void* handle);
typedef void* (*moo_vmprim_getdlsym_t) (moo_t* moo, void* handle, const moo_ooch_t* name);
typedef void* (*moo_vmprim_dlopen_t) (moo_t* moo, const moo_ooch_t* name, int flags);
typedef void (*moo_vmprim_dlclose_t) (moo_t* moo, void* handle);
typedef void* (*moo_vmprim_dlsym_t) (moo_t* moo, void* handle, const moo_ooch_t* name);
typedef void (*moo_log_write_t) (moo_t* moo, moo_oow_t mask, const moo_ooch_t* msg, moo_oow_t len);
typedef void (*moo_vmprim_sleep_t) (moo_t* moo, const moo_ntime_t* duration);
typedef void (*moo_vmprim_gettime_t) (moo_t* moo, moo_ntime_t* now);
typedef void (*moo_vmprim_startup_t) (moo_t* moo);
typedef int (*moo_vmprim_startup_t) (moo_t* moo);
typedef void (*moo_vmprim_cleanup_t) (moo_t* moo);
typedef void (*moo_vmprim_gettime_t) (moo_t* moo, moo_ntime_t* now);
typedef void (*moo_vmprim_sleep_t) (moo_t* moo, const moo_ntime_t* duration);
typedef int (*moo_vmprim_muxadd_t) (moo_t* moo);
typedef void (*moo_vmprim_muxdel_t) (moo_t* moo);
typedef void (*moo_vmprim_muxwait_t) (moo_t* moo, const moo_ntime_t* duration);
struct moo_vmprim_t
{
moo_vmprim_opendl_t dl_open;
moo_vmprim_closedl_t dl_close;
moo_vmprim_getdlsym_t dl_getsym;
moo_vmprim_dlopen_t dl_open;
moo_vmprim_dlclose_t dl_close;
moo_vmprim_dlsym_t dl_getsym;
moo_log_write_t log_write;
moo_vmprim_gettime_t vm_gettime;
moo_vmprim_sleep_t vm_sleep;
moo_vmprim_startup_t vm_startup;
moo_vmprim_cleanup_t vm_cleanup;
moo_vmprim_startup_t vm_startup;
moo_vmprim_cleanup_t vm_cleanup;
moo_vmprim_gettime_t vm_gettime;
moo_vmprim_sleep_t vm_sleep;
moo_vmprim_muxadd_t mux_add;
moo_vmprim_muxdel_t mux_del;
moo_vmprim_muxwait_t mux_wait;
};
typedef struct moo_vmprim_t moo_vmprim_t;
@ -958,11 +975,18 @@ struct moo_t
moo_oow_t sem_list_count;
moo_oow_t sem_list_capa;
/* semaphores sorted according to time-out */
/* semaphores sorted according to time-out.
* organize entries using heap as the earliest entry
* needs to be checked first */
moo_oop_semaphore_t* sem_heap;
moo_oow_t sem_heap_count;
moo_oow_t sem_heap_capa;
/* semaphores for I/O handling. plain array */
moo_oop_semaphore_t* sem_io;
moo_oow_t sem_io_count;
moo_oow_t sem_io_capa;
moo_oop_t* tmp_stack[256]; /* stack for temporaries */
moo_oow_t tmp_count;
@ -977,6 +1001,7 @@ struct moo_t
moo_ooi_t ip;
int proc_switched; /* TODO: this is temporary. implement something else to skip immediate context switching */
int switch_proc;
int abort_req;
moo_ntime_t exec_start_time;
moo_ntime_t exec_end_time;
/* =============================================================