Compare commits

..
3 Commits
5 changed files with 97 additions and 67 deletions
+12 -12
View File
@@ -303,19 +303,19 @@ typedef void(*signal_handler_t)(int);
#if defined(_WIN32) || defined(__DOS__) || defined(__OS2__) #if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
static void handle_sigint (int sig) static void handle_sigint (int sig)
{ {
if (g_hak) hak_abort (g_hak); if (g_hak) hak_abort(g_hak);
} }
#elif defined(macintosh) #elif defined(macintosh)
/* TODO */ /* TODO */
#elif defined(SA_SIGINFO) #elif defined(SA_SIGINFO)
static void handle_sigint (int sig, siginfo_t* siginfo, void* ctx) static void handle_sigint (int sig, siginfo_t* siginfo, void* ctx)
{ {
if (g_hak) hak_abort (g_hak); if (g_hak) hak_abort(g_hak);
} }
#else #else
static void handle_sigint (int sig) static void handle_sigint (int sig)
{ {
if (g_hak) hak_abort (g_hak); if (g_hak) hak_abort(g_hak);
} }
#endif #endif
@@ -328,7 +328,7 @@ static void set_signal (int sig, signal_handler_t handler)
#else #else
struct sigaction sa; struct sigaction sa;
memset (&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
/*sa.sa_handler = handler;*/ /*sa.sa_handler = handler;*/
#if defined(SA_SIGINFO) #if defined(SA_SIGINFO)
sa.sa_flags = SA_SIGINFO; sa.sa_flags = SA_SIGINFO;
@@ -336,16 +336,16 @@ static void set_signal (int sig, signal_handler_t handler)
#else #else
sa.sa_handler = handler; sa.sa_handler = handler;
#endif #endif
sigemptyset (&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigaction (sig, &sa, NULL); sigaction(sig, &sa, NULL);
#endif #endif
} }
static void set_signal_to_default (int sig) static void set_signal_to_default (int sig)
{ {
#if defined(_WIN32) || defined(__DOS__) || defined(__OS2__) #if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
signal (sig, SIG_DFL); signal(sig, SIG_DFL);
#elif defined(macintosh) #elif defined(macintosh)
/* TODO: implement this */ /* TODO: implement this */
#else #else
@@ -354,27 +354,27 @@ static void set_signal_to_default (int sig)
memset (&sa, 0, sizeof(sa)); memset (&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL; sa.sa_handler = SIG_DFL;
sa.sa_flags = 0; sa.sa_flags = 0;
sigemptyset (&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigaction (sig, &sa, NULL); sigaction(sig, &sa, NULL);
#endif #endif
} }
static void set_signal_to_ignore (int sig) static void set_signal_to_ignore (int sig)
{ {
#if defined(_WIN32) || defined(__DOS__) || defined(__OS2__) #if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
signal (sig, SIG_IGN); signal(sig, SIG_IGN);
#elif defined(macintosh) #elif defined(macintosh)
/* TODO: implement this */ /* TODO: implement this */
#else #else
struct sigaction sa; struct sigaction sa;
memset (&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN; sa.sa_handler = SIG_IGN;
sa.sa_flags = 0; sa.sa_flags = 0;
sigemptyset (&sa.sa_mask); sigemptyset (&sa.sa_mask);
sigaction (sig, &sa, NULL); sigaction(sig, &sa, NULL);
#endif #endif
} }
+46 -7
View File
@@ -835,7 +835,7 @@ static void switch_to_process (hak_t* hak, hak_oop_process_t proc, int new_state
/* the new process must be in the runnable state */ /* the new process must be in the runnable state */
HAK_ASSERT(hak, proc->state == HAK_SMOOI_TO_OOP(HAK_PROCESS_STATE_RUNNABLE) || HAK_ASSERT(hak, proc->state == HAK_SMOOI_TO_OOP(HAK_PROCESS_STATE_RUNNABLE) ||
proc->state == HAK_SMOOI_TO_OOP(HAK_PROCESS_STATE_WAITING)); proc->state == HAK_SMOOI_TO_OOP(HAK_PROCESS_STATE_WAITING));
sleep_active_process(hak, new_state_for_old_active); sleep_active_process(hak, new_state_for_old_active);
wake_process(hak, proc); wake_process(hak, proc);
@@ -1341,7 +1341,6 @@ static void yield_process (hak_t* hak, hak_oop_process_t proc)
} }
} }
static int async_signal_semaphore (hak_t* hak, hak_oop_semaphore_t sem) static int async_signal_semaphore (hak_t* hak, hak_oop_semaphore_t sem)
{ {
#if 0 #if 0
@@ -5640,8 +5639,13 @@ hak_pfrc_t hak_pf_process_resume (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs)
return HAK_PF_FAILURE; return HAK_PF_FAILURE;
} }
/* [SPECIAL CASE]
* resume_process changes the the active process.
* calling this after resume_process() pollutes a wrong stack. place it here */
HAK_STACK_SETRET(hak, nargs, prc);
resume_process(hak, prc); resume_process(hak, prc);
return HAK_PF_SUCCESS; return HAK_PF_SUCCESS;
} }
hak_pfrc_t hak_pf_process_suspend (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) hak_pfrc_t hak_pf_process_suspend (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs)
@@ -5662,8 +5666,13 @@ hak_pfrc_t hak_pf_process_suspend (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs)
prc = hak->processor->active; prc = hak->processor->active;
} }
/* [SPECIAL CASE]
* suspend_process changes the the active process.
* calling this after suspend_process() pollutes a wrong stack. place it here */
HAK_STACK_SETRET(hak, nargs, prc);
suspend_process(hak, prc); suspend_process(hak, prc);
return HAK_PF_SUCCESS; return HAK_PF_SUCCESS;
} }
hak_pfrc_t hak_pf_process_terminate (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) hak_pfrc_t hak_pf_process_terminate (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs)
@@ -5684,20 +5693,35 @@ hak_pfrc_t hak_pf_process_terminate (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs
prc = hak->processor->active; prc = hak->processor->active;
} }
/* [SPECIAL CASE]
* terminate_process changes the the active process.
* calling this after terminate_process() pollutes a wrong stack. place it here */
HAK_STACK_SETRET(hak, nargs, prc);
terminate_process(hak, prc); terminate_process(hak, prc);
return HAK_PF_SUCCESS; return HAK_PF_SUCCESS;
} }
hak_pfrc_t hak_pf_process_terminate_all (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) hak_pfrc_t hak_pf_process_terminate_all (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs)
{ {
/* [SPECIAL CASE]
* terminate_all_processes changes the the active process.
* calling this after terminate_all_processes() pollutes a wrong stack. place it here */
HAK_STACK_SETRET(hak, nargs, hak->_nil);
terminate_all_processes(hak); terminate_all_processes(hak);
return HAK_PF_SUCCESS; return HAK_PF_SUCCESS;
} }
hak_pfrc_t hak_pf_process_yield (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs) hak_pfrc_t hak_pf_process_yield (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs)
{ {
/* [SPECIAL CASE]
* yield_process changes the the active process.
* calling this after yield_process() pollutes a wrong stack. place it here */
HAK_STACK_SETRET(hak, nargs, hak->_nil);
yield_process(hak, hak->processor->active); yield_process(hak, hak->processor->active);
return HAK_PF_SUCCESS; return HAK_PF_SUCCESS;
} }
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
@@ -5715,7 +5739,22 @@ hak_pfrc_t hak_pf_semaphore_new (hak_t* hak, hak_mod_t* mod, hak_ooi_t nargs)
return HAK_PF_FAILURE; return HAK_PF_FAILURE;
} }
sem->count = HAK_SMOOI_TO_OOP(0); if (nargs >= 1)
{
hak_oop_t tmp;
tmp = (hak_oop_semaphore_t)HAK_STACK_GETARG(hak, nargs, 0);
if (!HAK_OOP_IS_SMOOI(tmp))
{
hak_seterrbfmt(hak, HAK_EINVAL, "invalid semaphore count - %O", tmp);
return HAK_PF_FAILURE;
}
sem->count = tmp;
}
else
{
sem->count = HAK_SMOOI_TO_OOP(0);
}
/* TODO: sem->signal_action? */ /* TODO: sem->signal_action? */
/* other fields are all set to nil */ /* other fields are all set to nil */
+15 -38
View File
@@ -356,7 +356,7 @@
* about async-signal-safety - the spinlock is built out of atomics and is safe * about async-signal-safety - the spinlock is built out of atomics and is safe
* by that measure - but about reentrancy: a signal delivered to the thread * by that measure - but about reentrancy: a signal delivered to the thread
* that already holds the lock would spin, or block, on a lock that thread can * that already holds the lock would spin, or block, on a lock that thread can
* no longer reach the end of. post_sig_to_all_haks() therefore walk the chain without it. * no longer reach the end of. post_sig_to_all_haks() therefore walks the chain without it.
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#if defined(USE_THREAD) #if defined(USE_THREAD)
@@ -2104,6 +2104,8 @@ kqueue_syserr:
#elif defined(USE_SELECT) #elif defined(USE_SELECT)
# define MUXEVT_FD(e) ((e).fd) # define MUXEVT_FD(e) ((e).fd)
# define MUXEVT_MASK(e) ((e).events) # define MUXEVT_MASK(e) ((e).events)
#else
# error UNSUPPORTED
#endif #endif
/* Drop multiplexer events already sitting in the buffer for this descriptor. /* Drop multiplexer events already sitting in the buffer for this descriptor.
@@ -2453,20 +2455,7 @@ static void vm_muxwait (hak_t* hak, const hak_ntime_t* dur, hak_vmprim_muxwait_c
{ {
--n; --n;
#if defined(USE_DEVPOLL) if (MUXEVT_FD(xtn->ev.buf[n]) == xtn->iothr.p[0])
if (xtn->ev.buf[n].fd == xtn->iothr.p[0])
#elif defined(USE_KQUEUE)
if (xtn->ev.buf[n].ident == xtn->iothr.p[0])
#elif defined(USE_EPOLL)
/*if (xtn->ev.buf[n].data.ptr == (void*)HAK_TYPE_MAX(hak_oow_t))*/
if (xtn->ev.buf[n].data.fd == xtn->iothr.p[0])
#elif defined(USE_POLL)
if (xtn->ev.buf[n].fd == xtn->iothr.p[0])
#elif defined(USE_SELECT)
if (xtn->ev.buf[n].fd == xtn->iothr.p[0])
#else
# error UNSUPPORTED
#endif
{ {
hak_uint8_t u8; hak_uint8_t u8;
while (read(xtn->iothr.p[0], &u8, HAK_SIZEOF(u8)) > 0) while (read(xtn->iothr.p[0], &u8, HAK_SIZEOF(u8)) > 0)
@@ -2480,21 +2469,15 @@ static void vm_muxwait (hak_t* hak, const hak_ntime_t* dur, hak_vmprim_muxwait_c
int revents; int revents;
hak_ooi_t mask; hak_ooi_t mask;
#if defined(USE_DEVPOLL) #if defined(USE_KQUEUE)
revents = xtn->ev.buf[n].revents;
#elif defined(USE_KQUEUE)
revents = 0; revents = 0;
/* it's "if .. else if" because kqueue filter is either READ or WRITE. */ /* it's "if .. else if" because kqueue filter is either READ or WRITE. */
if (xtn->ev.buf[n].filter == EVFILT_READ) revents |= XPOLLIN; if (xtn->ev.buf[n].filter == EVFILT_READ) revents |= XPOLLIN;
else if (xtn->ev.buf[n].filter == EVFILT_WRITE) revents |= XPOLLOUT; else if (xtn->ev.buf[n].filter == EVFILT_WRITE) revents |= XPOLLOUT;
if (xtn->ev.buf[n].flags & EV_EOF) revents |= XPOLLHUP; if (xtn->ev.buf[n].flags & EV_EOF) revents |= XPOLLHUP;
if (xtn->ev.buf[n].flags & EV_ERROR) revents |= XPOLLERR; if (xtn->ev.buf[n].flags & EV_ERROR) revents |= XPOLLERR;
#elif defined(USE_EPOLL) #else
revents = xtn->ev.buf[n].events; revents = MUXEVT_MASK(xtn->ev.buf[n]);
#elif defined(USE_POLL)
revents = xtn->ev.buf[n].revents;
#elif defined(USE_SELECT)
revents = xtn->ev.buf[n].events;
#endif #endif
mask = 0; mask = 0;
@@ -2503,19 +2486,7 @@ static void vm_muxwait (hak_t* hak, const hak_ntime_t* dur, hak_vmprim_muxwait_c
if (revents & XPOLLERR) mask |= HAK_SEMAPHORE_IO_MASK_ERROR; if (revents & XPOLLERR) mask |= HAK_SEMAPHORE_IO_MASK_ERROR;
if (revents & XPOLLHUP) mask |= HAK_SEMAPHORE_IO_MASK_HANGUP; if (revents & XPOLLHUP) mask |= HAK_SEMAPHORE_IO_MASK_HANGUP;
#if defined(USE_DEVPOLL) muxwcb(hak, MUXEVT_FD(xtn->ev.buf[n]), mask);
muxwcb(hak, xtn->ev.buf[n].fd, mask);
#elif defined(USE_KQUEUE)
muxwcb(hak, xtn->ev.buf[n].ident, mask);
#elif defined(USE_EPOLL)
muxwcb(hak, xtn->ev.buf[n].data.fd, mask);
#elif defined(USE_POLL)
muxwcb(hak, xtn->ev.buf[n].fd, mask);
#elif defined(USE_SELECT)
muxwcb(hak, xtn->ev.buf[n].fd, mask);
#else
# error UNSUPPORTED
#endif
} }
} }
while (n > 0); while (n > 0);
@@ -2864,6 +2835,7 @@ static void dispatch_siginfo (int sig, siginfo_t* si, void* ctx)
if (g_sig_state[sig].handler != (hak_uintptr_t)SIG_IGN && if (g_sig_state[sig].handler != (hak_uintptr_t)SIG_IGN &&
g_sig_state[sig].handler != (hak_uintptr_t)SIG_DFL) g_sig_state[sig].handler != (hak_uintptr_t)SIG_DFL)
{ {
/* execute the current handler */
((sig_handler_t)g_sig_state[sig].handler)(sig); ((sig_handler_t)g_sig_state[sig].handler)(sig);
} }
@@ -2871,6 +2843,9 @@ static void dispatch_siginfo (int sig, siginfo_t* si, void* ctx)
g_sig_state[sig].old_handler != (hak_uintptr_t)SIG_IGN && g_sig_state[sig].old_handler != (hak_uintptr_t)SIG_IGN &&
g_sig_state[sig].old_handler != (hak_uintptr_t)SIG_DFL) g_sig_state[sig].old_handler != (hak_uintptr_t)SIG_DFL)
{ {
/* execute the original remembered handler */
/* TODO: if the runtime has installed its own signal handler, proably this one must not be called.
* when the runtime registers a single handler, it may optionally request that the previous one should also be invoked? */
((void(*)(int, siginfo_t*, void*))g_sig_state[sig].old_handler)(sig, si, ctx); ((void(*)(int, siginfo_t*, void*))g_sig_state[sig].old_handler)(sig, si, ctx);
} }
} }
@@ -3137,8 +3112,10 @@ static HAK_INLINE void post_sig_to_all_haks (int signo)
{ {
xtn_t* xtn = GET_XTN(hak); xtn_t* xtn = GET_XTN(hak);
hak_uint8_t u8; hak_uint8_t u8;
/*hak_abortstd(hak);*/
u8 = signo & 0xFF; u8 = signo & 0xFF;
/* write a byte of signal number. vm_getsig() reads this when
* it's invoked by the vm */
write(xtn->sigfd.p[1], &u8, HAK_SIZEOF(u8)); write(xtn->sigfd.p[1], &u8, HAK_SIZEOF(u8));
hak = xtn->next; hak = xtn->next;
} }
+7 -1
View File
@@ -606,6 +606,7 @@ static hak_pfinfo_t pfinfos[] =
{ "cons", { HAK_PFBASE_FUNC, pf_core_cons, 2, 2 } }, { "cons", { HAK_PFBASE_FUNC, pf_core_cons, 2, 2 } },
{ "current-process", { HAK_PFBASE_FUNC, hak_pf_process_current, 0, 0 } }, { "current-process", { HAK_PFBASE_FUNC, hak_pf_process_current, 0, 0 } },
{ "eqk?", { HAK_PFBASE_FUNC, hak_pf_eqk, 2, 2 } }, { "eqk?", { HAK_PFBASE_FUNC, hak_pf_eqk, 2, 2 } },
{ "eql?", { HAK_PFBASE_FUNC, hak_pf_eql, 2, 2 } }, { "eql?", { HAK_PFBASE_FUNC, hak_pf_eql, 2, 2 } },
{ "eqv?", { HAK_PFBASE_FUNC, hak_pf_eqv, 2, 2 } }, { "eqv?", { HAK_PFBASE_FUNC, hak_pf_eqv, 2, 2 } },
@@ -621,8 +622,10 @@ static hak_pfinfo_t pfinfos[] =
{ "primAt", { HAK_PFBASE_FUNC, pf_core_prim_at, 2, 2 } }, { "primAt", { HAK_PFBASE_FUNC, pf_core_prim_at, 2, 2 } },
{ "primAtPut", { HAK_PFBASE_FUNC, pf_core_prim_at_put, 3, 3 } }, { "primAtPut", { HAK_PFBASE_FUNC, pf_core_prim_at_put, 3, 3 } },
{ "resume", { HAK_PFBASE_FUNC, hak_pf_process_resume, 1, 1 } }, { "resume", { HAK_PFBASE_FUNC, hak_pf_process_resume, 1, 1 } },
{ "sem-new", { HAK_PFBASE_FUNC, hak_pf_semaphore_new, 0, 0 } },
{ "sem-new", { HAK_PFBASE_FUNC, hak_pf_semaphore_new, 0, 1 } },
{ "sem-signal", { HAK_PFBASE_FUNC, hak_pf_semaphore_signal, 1, 3 } }, { "sem-signal", { HAK_PFBASE_FUNC, hak_pf_semaphore_signal, 1, 3 } },
{ "sem-signal-on-input", { HAK_PFBASE_FUNC, hak_pf_semaphore_signal_on_input, 2, 2 } }, { "sem-signal-on-input", { HAK_PFBASE_FUNC, hak_pf_semaphore_signal_on_input, 2, 2 } },
{ "sem-signal-on-output", { HAK_PFBASE_FUNC, hak_pf_semaphore_signal_on_output, 2, 2 } }, { "sem-signal-on-output", { HAK_PFBASE_FUNC, hak_pf_semaphore_signal_on_output, 2, 2 } },
@@ -632,13 +635,16 @@ static hak_pfinfo_t pfinfos[] =
{ "semgr-new", { HAK_PFBASE_FUNC, hak_pf_semaphore_group_new, 0, 0 } }, { "semgr-new", { HAK_PFBASE_FUNC, hak_pf_semaphore_group_new, 0, 0 } },
{ "semgr-remove", { HAK_PFBASE_FUNC, hak_pf_semaphore_group_remove_semaphore, 1, 2 } }, { "semgr-remove", { HAK_PFBASE_FUNC, hak_pf_semaphore_group_remove_semaphore, 1, 2 } },
{ "semgr-wait", { HAK_PFBASE_FUNC, hak_pf_semaphore_group_wait, 1, 1 } }, { "semgr-wait", { HAK_PFBASE_FUNC, hak_pf_semaphore_group_wait, 1, 1 } },
{ "slice", { HAK_PFBASE_FUNC, pf_core_slice, 3, 3 } }, { "slice", { HAK_PFBASE_FUNC, pf_core_slice, 3, 3 } },
{ "smooiToChar", { HAK_PFBASE_FUNC, pf_core_smooi_to_char, 1, 1 } }, { "smooiToChar", { HAK_PFBASE_FUNC, pf_core_smooi_to_char, 1, 1 } },
{ "sqrt", { HAK_PFBASE_FUNC, hak_pf_number_sqrt, 1, 1 } }, { "sqrt", { HAK_PFBASE_FUNC, hak_pf_number_sqrt, 1, 1 } },
{ "suspend", { HAK_PFBASE_FUNC, hak_pf_process_suspend, 0, 1 } }, { "suspend", { HAK_PFBASE_FUNC, hak_pf_process_suspend, 0, 1 } },
{ "terminate", { HAK_PFBASE_FUNC, hak_pf_process_terminate, 0, 1 } }, { "terminate", { HAK_PFBASE_FUNC, hak_pf_process_terminate, 0, 1 } },
{ "terminate-all", { HAK_PFBASE_FUNC, hak_pf_process_terminate_all, 0, 0 } }, { "terminate-all", { HAK_PFBASE_FUNC, hak_pf_process_terminate_all, 0, 0 } },
{ "yield", { HAK_PFBASE_FUNC, hak_pf_process_yield, 0, 0 } }, { "yield", { HAK_PFBASE_FUNC, hak_pf_process_yield, 0, 0 } },
{ "~=", { HAK_PFBASE_FUNC, hak_pf_number_ne, 2, 2 } }, { "~=", { HAK_PFBASE_FUNC, hak_pf_number_ne, 2, 2 } },
}; };
+17 -9
View File
@@ -13,27 +13,35 @@ class[#uncopyable] Semaphore: Object(
_grm_next _grm_next
) { ) {
fun[#class] new() { fun[#class] new() {
return (core.sem-new) return (core.sem-new 0)
}
fun[#class] forMutex() {
return (core.sem-new 1)
}
fun signal() {
return (core.sem-signal self 0 0)
} }
fun signalAfter(secs nsecs) { fun signalAfter(secs nsecs) {
core.sem-signal self secs nsecs return (core.sem-signal self secs nsecs)
} }
fun signalOnInput(handle) { fun signalOnInput(handle) {
core.sem-signal-on-input self handle return (core.sem-signal-on-input self handle)
} }
fun signalOnOutput(handle) { fun signalOnOutput(handle) {
core.sem-signal-on-output self handle return (core.sem-signal-on-output self handle)
} }
fun unsignal() { fun unsignal() {
core.sem-unsignal self return (core.sem-unsignal self)
} }
fun wait() { fun wait() {
core.sem-wait self return (core.sem-wait self)
} }
} }
@@ -52,14 +60,14 @@ class[#uncopyable] SemaphoreGroup: Object(
} }
fun add(sem) { fun add(sem) {
core.semgr-add self sem return (core.semgr-add self sem)
} }
fun remove(sem) { fun remove(sem) {
core.semgr-remove self sem return (core.semgr-remove self sem)
} }
fun wait() { fun wait() {
core.semgr-wait self return (core.semgr-wait self)
} }
} }