implemented sleep interruption, sort of...
This commit is contained in:
parent
48734c71a7
commit
4254ea0abe
@ -219,9 +219,9 @@ static MOO_INLINE void vm_gettime (moo_t* moo, moo_ntime_t* now)
|
|||||||
MOO_SUB_NTIME (now, now, &moo->exec_start_time); /* now = now - exec_start_time */
|
MOO_SUB_NTIME (now, now, &moo->exec_start_time); /* now = now - exec_start_time */
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
|
static MOO_INLINE int vm_sleep (moo_t* moo, const moo_ntime_t* dur)
|
||||||
{
|
{
|
||||||
moo->vmprim.vm_sleep (moo, dur);
|
return moo->vmprim.vm_sleep(moo, dur);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE void vm_muxwait (moo_t* moo, const moo_ntime_t* dur)
|
static MOO_INLINE void vm_muxwait (moo_t* moo, const moo_ntime_t* dur)
|
||||||
@ -4878,9 +4878,10 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
{
|
{
|
||||||
moo_oop_process_t proc;
|
moo_oop_process_t proc;
|
||||||
|
|
||||||
|
signal_timed:
|
||||||
/* waited long enough. signal the semaphore */
|
/* waited long enough. signal the semaphore */
|
||||||
|
|
||||||
proc = signal_semaphore (moo, moo->sem_heap[0]);
|
proc = signal_semaphore(moo, moo->sem_heap[0]);
|
||||||
/* [NOTE] no moo_pushvolat() on proc. no GC must occur
|
/* [NOTE] no moo_pushvolat() on proc. no GC must occur
|
||||||
* in the following line until it's used for
|
* in the following line until it's used for
|
||||||
* wake_process() below. */
|
* wake_process() below. */
|
||||||
@ -4931,9 +4932,17 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int halting;
|
||||||
|
|
||||||
/* no running process, no io semaphore */
|
/* no running process, no io semaphore */
|
||||||
if ((moo_oop_t)moo->sem_gcfin != moo->_nil && moo->sem_gcfin_sigreq) goto signal_sem_gcfin;
|
if ((moo_oop_t)moo->sem_gcfin != moo->_nil && moo->sem_gcfin_sigreq) goto signal_sem_gcfin;
|
||||||
vm_sleep (moo, &ft);
|
halting = vm_sleep(moo, &ft);
|
||||||
|
|
||||||
|
if (halting)
|
||||||
|
{
|
||||||
|
vm_gettime (moo, &now);
|
||||||
|
goto signal_timed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
vm_gettime (moo, &now);
|
vm_gettime (moo, &now);
|
||||||
}
|
}
|
||||||
|
@ -1201,7 +1201,7 @@ typedef void (*moo_vmprim_muxwait_t) (
|
|||||||
moo_vmprim_muxwait_cb_t muxwcb
|
moo_vmprim_muxwait_cb_t muxwcb
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef void (*moo_vmprim_sleep_t) (
|
typedef int (*moo_vmprim_sleep_t) (
|
||||||
moo_t* moo,
|
moo_t* moo,
|
||||||
const moo_ntime_t* duration
|
const moo_ntime_t* duration
|
||||||
);
|
);
|
||||||
|
@ -380,8 +380,9 @@ struct xtn_t
|
|||||||
pthread_mutex_t mtx;
|
pthread_mutex_t mtx;
|
||||||
pthread_cond_t cnd;
|
pthread_cond_t cnd;
|
||||||
pthread_cond_t cnd2;
|
pthread_cond_t cnd2;
|
||||||
int halting;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int halting;
|
||||||
} ev;
|
} ev;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2477,7 +2478,7 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c
|
|||||||
if (!xtn->iothr.up)
|
if (!xtn->iothr.up)
|
||||||
{
|
{
|
||||||
xtn->iothr.up = 1;
|
xtn->iothr.up = 1;
|
||||||
if (pthread_create (&xtn->iothr.thr, MOO_NULL, iothr_main, moo) != 0)
|
if (pthread_create(&xtn->iothr.thr, MOO_NULL, iothr_main, moo) != 0)
|
||||||
{
|
{
|
||||||
MOO_LOG2 (moo, MOO_LOG_WARN, "Warning: pthread_create failure - %d, %hs\n", errno, strerror(errno));
|
MOO_LOG2 (moo, MOO_LOG_WARN, "Warning: pthread_create failure - %d, %hs\n", errno, strerror(errno));
|
||||||
xtn->iothr.up = 0;
|
xtn->iothr.up = 0;
|
||||||
@ -2511,7 +2512,7 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c
|
|||||||
ts.tv_nsec = ns.nsec;
|
ts.tv_nsec = ns.nsec;
|
||||||
|
|
||||||
pthread_mutex_lock (&xtn->ev.mtx);
|
pthread_mutex_lock (&xtn->ev.mtx);
|
||||||
if (xtn->ev.len <= 0 && !xtn->ev.halting)
|
if (xtn->ev.len <= 0)
|
||||||
{
|
{
|
||||||
/* the event buffer is still empty */
|
/* the event buffer is still empty */
|
||||||
pthread_cond_timedwait (&xtn->ev.cnd2, &xtn->ev.mtx, &ts);
|
pthread_cond_timedwait (&xtn->ev.cnd2, &xtn->ev.mtx, &ts);
|
||||||
@ -2725,10 +2726,13 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
|
static int vm_sleep (moo_t* moo, const moo_ntime_t* dur)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
|
||||||
xtn_t* xtn = GET_XTN(moo);
|
xtn_t* xtn = GET_XTN(moo);
|
||||||
|
|
||||||
|
if (MOO_UNLIKELY(xtn->ev.halting)) return xtn->ev.halting;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
if (xtn->waitable_timer)
|
if (xtn->waitable_timer)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
@ -2751,9 +2755,10 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
|
|||||||
#elif defined(macintosh)
|
#elif defined(macintosh)
|
||||||
|
|
||||||
/* TODO: ... */
|
/* TODO: ... */
|
||||||
|
# error NOT IMPLEMENTED
|
||||||
|
|
||||||
#elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__))
|
#elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__))
|
||||||
|
{
|
||||||
clock_t c;
|
clock_t c;
|
||||||
|
|
||||||
c = clock ();
|
c = clock ();
|
||||||
@ -2771,30 +2776,35 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
|
|||||||
# error UNSUPPORTED CLOCKS_PER_SEC
|
# error UNSUPPORTED CLOCKS_PER_SEC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TODO: handle clock overvlow */
|
/* TODO: handle clock overvlow */
|
||||||
/* TODO: check if there is abortion request or interrupt */
|
/* TODO: check if there is abortion request or interrupt */
|
||||||
while (c > clock())
|
while (c > clock())
|
||||||
{
|
{
|
||||||
_halt_cpu();
|
_halt_cpu();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#else
|
#elif defined(USE_THREAD)
|
||||||
#if defined(USE_THREAD)
|
|
||||||
/* the sleep callback is called only if there is no IO semaphore
|
/* the sleep callback is called only if there is no IO semaphore
|
||||||
* waiting. so i can safely call vm_muxwait() without a muxwait callback
|
* waiting. so i can safely call vm_muxwait() without a muxwait callback
|
||||||
* when USE_THREAD is true */
|
* when USE_THREAD is true */
|
||||||
vm_muxwait (moo, dur, MOO_NULL);
|
vm_muxwait (moo, dur, MOO_NULL);
|
||||||
#elif defined(HAVE_NANOSLEEP)
|
|
||||||
|
#elif defined(HAVE_NANOSLEEP)
|
||||||
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
ts.tv_sec = dur->sec;
|
ts.tv_sec = dur->sec;
|
||||||
ts.tv_nsec = dur->nsec;
|
ts.tv_nsec = dur->nsec;
|
||||||
nanosleep (&ts, MOO_NULL);
|
nanosleep (&ts, MOO_NULL);
|
||||||
#elif defined(HAVE_USLEEP)
|
}
|
||||||
|
|
||||||
|
#elif defined(HAVE_USLEEP)
|
||||||
usleep (MOO_SECNSEC_TO_USEC(dur->sec, dur->nsec));
|
usleep (MOO_SECNSEC_TO_USEC(dur->sec, dur->nsec));
|
||||||
#else
|
|
||||||
# error UNSUPPORT SLEEP
|
#else
|
||||||
#endif
|
# error UNSUPPORTED SLEEP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static moo_ooi_t vm_getsigfd (moo_t* moo)
|
static moo_ooi_t vm_getsigfd (moo_t* moo)
|
||||||
@ -3692,18 +3702,11 @@ static void fini_moo (moo_t* moo)
|
|||||||
|
|
||||||
static void halting_moo (moo_t* moo)
|
static void halting_moo (moo_t* moo)
|
||||||
{
|
{
|
||||||
#if defined(USE_THREAD)
|
|
||||||
xtn_t* xtn = GET_XTN(moo);
|
xtn_t* xtn = GET_XTN(moo);
|
||||||
xtn->ev.halting = 1;
|
xtn->ev.halting = 1; /* once set, vm_sleep() is supposed to return without waiting */
|
||||||
pthread_mutex_unlock (&xtn->ev.mtx);
|
|
||||||
pthread_cond_signal (&xtn->ev.cnd2);
|
|
||||||
pthread_mutex_unlock (&xtn->ev.mtx);
|
|
||||||
#else
|
|
||||||
# error NOT IMPLEMENTED YET
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moo_t* moo_openstd (moo_oow_t xtnsize, const moo_cfgstd_t* cfg, moo_errinf_t* errinfo)
|
moo_t* moo_openstd (moo_oow_t xtnsize, const moo_cfgstd_t* cfg, moo_errinf_t* errinfo)
|
||||||
{
|
{
|
||||||
moo_t* moo;
|
moo_t* moo;
|
||||||
moo_vmprim_t vmprim;
|
moo_vmprim_t vmprim;
|
||||||
|
Loading…
Reference in New Issue
Block a user