scmno****@osdn*****
scmno****@osdn*****
Tue Jun 5 01:57:16 JST 2018
changeset a3a4a2ce7c55 in quipu/quipu details: http://hg.osdn.jp/view/quipu/quipu?cmd=changeset;node=a3a4a2ce7c55 user: Agustina Arzille <avarz****@riseu*****> date: Mon Jun 04 13:57:06 2018 -0300 description: Switch from signals to generic events for GC diffstat: Makefile | 2 +- array.cpp | 2 +- bvector.cpp | 2 +- compiler.cpp | 4 +- continuation.cpp | 2 +- event.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ event.h | 45 +++++++++++++++++++++++++++++ function.cpp | 2 +- interp.cpp | 61 +++++++++++++++++++++------------------ interp.h | 34 +++++++++++----------- io.cpp | 1 - memory.cpp | 69 +++++--------------------------------------- memory.h | 4 ++ quipu.h | 2 +- signals.cpp | 70 --------------------------------------------- signals.h | 41 -------------------------- symbol.cpp | 4 +- table.cpp | 2 +- tree.cpp | 2 +- 19 files changed, 206 insertions(+), 229 deletions(-) diffs (truncated from 799 to 300 lines): diff -r 86d6195e06d0 -r a3a4a2ce7c55 Makefile --- a/Makefile Sun Jun 03 19:20:52 2018 +0000 +++ b/Makefile Mon Jun 04 13:57:06 2018 -0300 @@ -23,7 +23,7 @@ function.o \ continuation.o \ bytecode.o \ - signals.o \ + event.o \ initop.o \ compiler.o diff -r 86d6195e06d0 -r a3a4a2ce7c55 array.cpp --- a/array.cpp Sun Jun 03 19:20:52 2018 +0000 +++ b/array.cpp Mon Jun 04 13:57:06 2018 -0300 @@ -28,7 +28,7 @@ if (!nelems) qp_return (empty_array.as_obj ()); - intr_guard ig (interp); + evh_guard eg (interp); array *ret = array::alloc_raw (nelems); for (uint32_t i = 0; i < nelems; ++i) diff -r 86d6195e06d0 -r a3a4a2ce7c55 bvector.cpp --- a/bvector.cpp Sun Jun 03 19:20:52 2018 +0000 +++ b/bvector.cpp Mon Jun 04 13:57:06 2018 -0300 @@ -30,7 +30,7 @@ return (this->empty); } - intr_guard ig (interp); + evh_guard eg (interp); bvector *ret = (bvector *)alloch (nbytes + this->hsize + 1, this->rtype); diff -r 86d6195e06d0 -r a3a4a2ce7c55 compiler.cpp --- a/compiler.cpp Sun Jun 03 19:20:52 2018 +0000 +++ b/compiler.cpp Mon Jun 04 13:57:06 2018 -0300 @@ -2392,13 +2392,13 @@ interp->raise2 ("type-error", "apply: object is not callable"); OP_(IRTJMP): - interp->handle_intrs (); + interp->handle_evs (); OP_(JMP): ip += (int16_t)get16 (ip); NEXT_OP; OP_(IRTJMPL): - interp->handle_intrs (); + interp->handle_evs (); OP_(JMPL): ip += (int32_t)get32 (ip); NEXT_OP; diff -r 86d6195e06d0 -r a3a4a2ce7c55 continuation.cpp --- a/continuation.cpp Sun Jun 03 19:20:52 2018 +0000 +++ b/continuation.cpp Mon Jun 04 13:57:06 2018 -0300 @@ -79,7 +79,7 @@ object continuation::make (interpreter *interp, uint32_t lastf) { - intr_guard ig (interp); + evh_guard eg (interp); continuation *ret = alloc_raw (); ret->value = UNBOUND; diff -r 86d6195e06d0 -r a3a4a2ce7c55 event.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event.cpp Mon Jun 04 13:57:06 2018 -0300 @@ -0,0 +1,86 @@ +#include "event.h" +#include "thread.h" +#include "function.h" +#include "memory.h" + +QP_DECLS_BEGIN + +static object ev_handlers[QP_NSIG]; +static atomic_t evh_lock; + +#ifdef QP_PLATFORM_UNIX + +static object +sigint_handler (interpreter *interp, object *, int) +{ + interp->raise2 ("intr-error", "thread was interrupted"); + return (UNBOUND); +} + +static void +sighandler (int sig) +{ + interpreter::self()->set_ev (sig); +} + +#endif + +object add_evhandler (interpreter *interp, unsigned int ev, object fct) +{ + if (--ev >= NPENDEV) + qp_return (UNBOUND); + + QP_MT_BEGIN (lwlock_grab (&evh_lock)); + interp->retval = ev_handlers[ev]; + ev_handlers[ev] = fct; + QP_MT_END (lwlock_drop (&evh_lock)); + + return (interp->retval); +} + +object get_evhandler (interpreter *interp, unsigned int ev) +{ + if (--ev >= NPENDEV) + qp_return (UNBOUND); + + qp_return (ev_handlers[ev]); +} + +static bool +do_init_events (interpreter *interp) +{ + lwlock_init (&evh_lock); + for (unsigned int i = 0; i < NPENDEV; ++i) + ev_handlers[i] = UNBOUND; + +#ifdef QP_PLATFORM_UNIX + + static native_function sigint_fct; + sigint_fct.flags = native_function::native_flag; + sigint_fct.type = typecode::FCT; + sigint_fct.fct = sigint_handler; + sigint_fct.name = "sigint-handler"; + ev_handlers[SIGINT - 1] = sigint_fct.as_obj (); + + struct sigaction sa; + sigfillset (&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = sighandler; + sigaction (SIGINT, &sa, 0); + +#endif + + static native_function gcreq_fct; + gcreq_fct.flags = native_function::native_flag; + gcreq_fct.type = typecode::FCT; + gcreq_fct.fct = gcreq_handler; + gcreq_fct.name = "gc-request"; + ev_handlers[GCREQ_EV - 1] = gcreq_fct.as_obj (); + + return (true); +} + +QP_EXPORT init_op init_symbols; +init_op init_event (do_init_events, "events", &init_symbols); + +QP_DECLS_END diff -r 86d6195e06d0 -r a3a4a2ce7c55 event.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event.h Mon Jun 04 13:57:06 2018 -0300 @@ -0,0 +1,45 @@ +#ifndef __QP_SIGNALS__ +#define __QP_SIGNALS__ 1 + +#include "defs.h" +#include "initop.h" +#include <csignal> + +QP_DECLS_BEGIN + +class interpreter; + +const int QP_NSIG = +#ifdef NSIG + NSIG; +#elif defined (_NSIG) + _NSIG; +#elif defined (SIGMAX) + SIGMAX + 1; +#elif defined (SIG_MAX) + SIG_MAX + 1; +#elif defined (_SIGMAX) + _SIGMAX + 1; +#else + 8 * sizeof (sigset_t) + 1; +#endif + +const int THREXIT_EV = QP_NSIG + 1; +const int PROCEXIT_EV = QP_NSIG + 2; +const int GCREQ_EV = QP_NSIG + 3; + +// All signals + the three above. +const int NPENDEV = QP_NSIG + 3; + +// Install the event handler FCT for event EV. +object add_evhandler (interpreter *__interp, unsigned int __ev, object __fct); + +// Get the event handler for event EV. +object get_evhandler (interpreter *__interp, unsigned int __ev); + +// Init OP for the event subsystem. +QP_EXPORT init_op init_event; + +QP_DECLS_END + +#endif diff -r 86d6195e06d0 -r a3a4a2ce7c55 function.cpp --- a/function.cpp Sun Jun 03 19:20:52 2018 +0000 +++ b/function.cpp Mon Jun 04 13:57:06 2018 -0300 @@ -13,7 +13,7 @@ object alloc_fct (interpreter *interp, uint32_t flags) { - intr_guard ig (interp); + evh_guard eg (interp); function *fp = (function *)alloch (sizeof (*fp), typecode::FCT); fp->bcode = fp->vals = NIL; fp->env = fp->name = NIL; diff -r 86d6195e06d0 -r a3a4a2ce7c55 interp.cpp --- a/interp.cpp Sun Jun 03 19:20:52 2018 +0000 +++ b/interp.cpp Mon Jun 04 13:57:06 2018 -0300 @@ -21,7 +21,6 @@ self->prev = headp; headp->next->prev = self; this->value = val; - atomic_mfence_rel (); self->prev->next = self; } @@ -70,9 +69,9 @@ double dvt = monotonic_time (); this->rand_seed = hashbuf (&dvt, sizeof (dvt)); - memset (this->sigpend_mask, 0, sizeof (this->sigpend_mask)); - this->nsigpend = 0; - this->intr_active = true; + memset (this->pendev_mask, 0, sizeof (this->pendev_mask)); + this->npendev = 0; + this->evh_active = true; this->values.init_head (); this->hooks.init_head (); @@ -92,7 +91,7 @@ void interpreter::growstk (uint32_t n) { - intr_guard g (this); + evh_guard eg (this); uint32_t sp = this->stkdiff (), size = sp + n; if (qp_likely (size < this->nstack)) return; @@ -120,9 +119,7 @@ object interpreter::pop () { - this->retval = *(this->stkend - 1); - atomic_mfence_rel (); - return (--this->stkend, this->retval); + return (this->retval = *--this->stkend); } void interpreter::cleanup_talloc (interp_tbuf *tp) @@ -167,6 +164,12 @@ static thread_local interpreter *self_interp; +#else + +static interpreter *self_interp; + +#endif + interpreter* interpreter::self () { return (self_interp); @@ -177,6 +180,8 @@ self_interp = interp; } +#ifndef QP_NO_THREADS + /* We cannot use the internal lightweight locks here, because it may * cause a deadlock when contending against the gc-triggering thread. * Instead, we use a simple spinlock, since we shouldn't hold this @@ -209,9 +214,11 @@ atomic_mfence_rel (); } +#endif + void interpreter::begin_blocking () { - this->handle_intrs (); + this->handle_evs (); this->lock (); this->state = INTERP_BLOCKING; this->unlock (); @@ -235,8 +242,6 @@ this->unlock (); }