From 3d0bcf970e0ea3960cc0183bf4ddb4b750abe9dd Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Sun, 24 Dec 2017 17:36:20 +0000 Subject: [PATCH] changed to support a pair of semaphores on a single handle for input and output respectively --- moo/Makefile.in | 13 +- moo/aclocal.m4 | 1 + moo/configure | 646 +++++++++++++++++++++++++++++++++++++++++ moo/configure.ac | 2 + moo/kernel/Process.moo | 2 +- moo/kernel/Socket.moo | 7 +- moo/lib/Makefile.am | 4 +- moo/lib/Makefile.in | 19 +- moo/lib/err.c | 2 +- moo/lib/exec.c | 347 ++++++++++++---------- moo/lib/gc.c | 5 +- moo/lib/main.c | 57 ++-- moo/lib/moo-cfg.h.in | 10 + moo/lib/moo.c | 7 +- moo/lib/moo.h | 28 +- moo/mod/Makefile.am | 2 + moo/mod/Makefile.in | 13 +- moo/mod/sck.c | 2 +- 18 files changed, 960 insertions(+), 207 deletions(-) diff --git a/moo/Makefile.in b/moo/Makefile.in index 25711f0..0df30b7 100644 --- a/moo/Makefile.in +++ b/moo/Makefile.in @@ -90,10 +90,11 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/argz.m4 \ $(top_srcdir)/m4/ax_cxx_namespace.m4 \ - $(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ @@ -294,6 +295,9 @@ PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ QUADMATH_LIBS = @QUADMATH_LIBS@ RANLIB = @RANLIB@ SED = @SED@ @@ -316,6 +320,7 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ diff --git a/moo/aclocal.m4 b/moo/aclocal.m4 index 721bcba..3bc7808 100644 --- a/moo/aclocal.m4 +++ b/moo/aclocal.m4 @@ -1210,6 +1210,7 @@ AC_SUBST([am__untar]) m4_include([m4/argz.m4]) m4_include([m4/ax_cxx_namespace.m4]) m4_include([m4/ax_numval.m4]) +m4_include([m4/ax_pthread.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltdl.m4]) m4_include([m4/ltoptions.m4]) diff --git a/moo/configure b/moo/configure index 5cb9d44..52d631a 100755 --- a/moo/configure +++ b/moo/configure @@ -680,6 +680,10 @@ QUADMATH_LIBS UNICOWS_LIBS TERMINAL_LIBS DYNCALL_LIBS +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CC +ax_pthread_config LIBM WIN32_FALSE WIN32_TRUE @@ -17982,6 +17986,648 @@ esac LIBM=$LIBM + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + if test "x$PTHREAD_CC" != "x"; then : + CC="$PTHREAD_CC" +fi + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5 +$as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5 +$as_echo "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;} +fi +rm -f conftest* + + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; +esac + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +if test "x$GCC" = "xyes"; then : + ax_pthread_flags="-pthread -pthreads $ax_pthread_flags" +fi + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +if test "x$ax_pthread_check_macro" = "x--"; then : + ax_pthread_check_cond=0 +else + ax_pthread_check_cond="!defined($ax_pthread_check_macro)" +fi + +# Are we compiling with Clang? + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5 +$as_echo_n "checking whether $CC is Clang... " >&6; } +if ${ax_cv_PTHREAD_CLANG+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then : + ax_cv_PTHREAD_CLANG=yes +fi +rm -f conftest* + + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5 +$as_echo "$ax_cv_PTHREAD_CLANG" >&6; } +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +ax_pthread_clang_warning=no + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5 +$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; } +if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + if test "x$ax_pthread_try" = "xunknown"; then : + break +fi + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void){return 0;} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_link="$ax_pthread_2step_ac_link" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void){return 0;} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + if test "x$ax_pthread_try" = "x"; then : + ax_pthread_try=no +fi + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5 +$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; } + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -mt,pthread) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with -mt -lpthread" >&5 +$as_echo_n "checking whether pthreads work with -mt -lpthread... " >&6; } + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5 +$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; } + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ax_pthread_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ax_pthread_config"; then + ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ax_pthread_config="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" +fi +fi +ax_pthread_config=$ac_cv_prog_ax_pthread_config +if test -n "$ax_pthread_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 +$as_echo "$ax_pthread_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$ax_pthread_config" = "xno"; then : + continue +fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5 +$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; } + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; } +int +main () +{ +pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test "x$ax_pthread_ok" = "xyes"; then : + break +fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } +if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int attr = $ax_pthread_attr; return attr /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5 +$as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; } + if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"; then : + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR +_ACEOF + + ax_pthread_joinable_attr_defined=yes + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5 +$as_echo_n "checking whether more special flags are required for pthreads... " >&6; } +if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5 +$as_echo "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; } + if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"; then : + PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 +$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; } +if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int i = PTHREAD_PRIO_INHERIT; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_PTHREAD_PRIO_INHERIT=yes +else + ax_cv_PTHREAD_PRIO_INHERIT=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 +$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } + if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"; then : + +$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h + + ax_pthread_prio_inherit_defined=yes + +fi + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + case "x/$CC" in #( + x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) : + #handle absolute path differently from PATH based program lookup + case "x$CC" in #( + x/*) : + if as_fn_executable_p ${CC}_r; then : + PTHREAD_CC="${CC}_r" +fi ;; #( + *) : + for ac_prog in ${CC}_r +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PTHREAD_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PTHREAD_CC" && break +done +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + ;; +esac ;; #( + *) : + ;; +esac + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + +$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h + + : +else + ax_pthread_ok=no + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_memset" >&5 $as_echo_n "checking for __builtin_memset... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/moo/configure.ac b/moo/configure.ac index d547d06..5959859 100644 --- a/moo/configure.ac +++ b/moo/configure.ac @@ -107,6 +107,8 @@ dnl check the math library (check if -lm is needed) LT_LIB_M AC_SUBST(LIBM, $LIBM) +AX_PTHREAD() + dnl check some compiler builtins AC_MSG_CHECKING([for __builtin_memset]) AC_LINK_IFELSE( diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 32320d9..9b1b7a1 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -60,7 +60,7 @@ class Semaphore(Object) fireTimeNsec := 0, ioIndex := -1, ioHandle := nil, - ioMask := 0. + ioMask := nil. var(#get,#set) signalAction := nil. diff --git a/moo/kernel/Socket.moo b/moo/kernel/Socket.moo index 0d141da..77fdc75 100644 --- a/moo/kernel/Socket.moo +++ b/moo/kernel/Socket.moo @@ -8,7 +8,7 @@ class Socket(Object) from 'sck' method(#primitive) open(domain, type, proto). method(#primitive) _close. - method(#primitive) connect(a,b,c). + method(#primitive) _connect(a,b,c). method(#primitive) endConnect. method(#primitive) readBytes: bytes. @@ -89,7 +89,7 @@ extend Socket System signal: s2 afterSecs: 10. System addAsyncSemaphore: s1. System addAsyncSemaphore: s2. - self connect(1, 2, 3). + self _connect(1, 2, 3). ] ifCurtailed: [ ## rollback sa value: s2. @@ -167,6 +167,7 @@ class MyObject(Object) if (state) { sck writeBytes: #[ $h, $e, $l, $l, $o ]. + } else { @@ -179,7 +180,9 @@ class MyObject(Object) 'CONNECTED NOW.............' dump. ##s onOutputDo: outact. s writeBytes: #[ $h $e $l $l $o ]. + s watchInput. + s watchOutput. } else { diff --git a/moo/lib/Makefile.am b/moo/lib/Makefile.am index dc9f30e..5455127 100644 --- a/moo/lib/Makefile.am +++ b/moo/lib/Makefile.am @@ -1,5 +1,7 @@ AUTOMAKE_OPTIONS = nostdinc +AM_CFLAGS = $(PTHREAD_CFLAGS) + CPPFLAGS_ALL_COMMON = \ -I$(abs_builddir) \ -I$(abs_srcdir) \ @@ -97,7 +99,7 @@ bin_PROGRAMS = moo moo_SOURCES = main.c moo_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) moo_LDFLAGS = $(LDFLAGS_LIB_COMMON) -moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo -lpthread +moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo $(PTHREAD_LIBS) if ENABLE_STATIC_MODULE moo_DEPENDENCIES = libmoo.la endif diff --git a/moo/lib/Makefile.in b/moo/lib/Makefile.in index e23282a..e3fc826 100644 --- a/moo/lib/Makefile.in +++ b/moo/lib/Makefile.in @@ -102,7 +102,8 @@ host_triplet = @host@ @ENABLE_MOD_X11_TRUE@@ENABLE_STATIC_MODULE_TRUE@am__append_12 = -lmoo-x11 @ENABLE_MOD_X11_TRUE@@ENABLE_STATIC_MODULE_TRUE@am__append_13 = $(abs_builddir)/../mod/libmoo-x11.la bin_PROGRAMS = moo$(EXEEXT) -@ENABLE_STATIC_MODULE_FALSE@moo_DEPENDENCIES = $(am__DEPENDENCIES_3) +@ENABLE_STATIC_MODULE_FALSE@moo_DEPENDENCIES = $(am__DEPENDENCIES_3) \ +@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_1) subdir = lib DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/moo-cfg.h.in $(top_srcdir)/ac/depcomp \ @@ -110,10 +111,11 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/argz.m4 \ $(top_srcdir)/m4/ax_cxx_namespace.m4 \ - $(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -334,6 +336,9 @@ PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ QUADMATH_LIBS = @QUADMATH_LIBS@ RANLIB = @RANLIB@ SED = @SED@ @@ -356,6 +361,7 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -401,6 +407,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = nostdinc +AM_CFLAGS = $(PTHREAD_CFLAGS) CPPFLAGS_ALL_COMMON = \ -I$(abs_builddir) \ -I$(abs_srcdir) \ @@ -459,7 +466,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 -lpthread +moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo $(PTHREAD_LIBS) @ENABLE_STATIC_MODULE_TRUE@moo_DEPENDENCIES = libmoo.la all: moo-cfg.h $(MAKE) $(AM_MAKEFLAGS) all-am diff --git a/moo/lib/err.c b/moo/lib/err.c index 468b0bf..b604b5f 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -309,7 +309,7 @@ void moo_seterrwithsyserr (moo_t* moo, int syserr) { moo_bch_t msgbuf[64]; strerror_r (syserr, msgbuf, MOO_COUNTOF(msgbuf)); - moo_seterrbfmt (moo, moo_syserr_to_errnum(errno), "%s", msgbuf); + moo_seterrbfmt (moo, moo_syserr_to_errnum(errno), "%hs", msgbuf); } /* -------------------------------------------------------------------------- diff --git a/moo/lib/exec.c b/moo/lib/exec.c index f246cd5..23d59d9 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -53,10 +53,10 @@ static MOO_INLINE const char* proc_state_to_string (int state) * proably depending on the object memory size? */ #define SEM_LIST_INC 256 #define SEM_HEAP_INC 256 -#define SEM_IO_INC 256 +#define SEM_IO_TUPLE_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_IO_TUPLE_MAX (SEM_IO_TUPLE_INC * 1000) #define SEM_HEAP_PARENT(x) (((x) - 1) / 2) #define SEM_HEAP_LEFT(x) ((x) * 2 + 1) @@ -123,7 +123,7 @@ static MOO_INLINE const char* proc_state_to_string (int state) # define __PRIMITIVE_NAME__ (&__FUNCTION__[0]) #endif -static void signal_io_semaphore (moo_t* moo, moo_ooi_t mask, void* ctx); +static void signal_io_semaphore (moo_t* moo, /*moo_ooi_t io_handle,*/ moo_ooi_t mask, void* data); static int send_message (moo_t* moo, moo_oop_char_t selector, int to_super, moo_ooi_t nargs); static int send_message_with_str (moo_t* moo, const moo_ooch_t* nameptr, moo_oow_t namelen, int to_super, moo_ooi_t nargs); @@ -757,6 +757,7 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem) } /* if the semaphore belongs to a semaphore group and the control reaches + * here, no process is waiting on the semaphore group. however, a process * may still be waiting on the semaphore. If a process waits on a semaphore * group and another process wait on a semaphore that belongs to the @@ -829,6 +830,7 @@ static MOO_INLINE void await_semaphore (moo_t* moo, moo_oop_semaphore_t sem) if ((moo_oop_t)semgrp != moo->_nil && count == 0) { + int sems_idx; /* TODO: if i disallow individual wait on a semaphore in a group, * this membership manipulation is redundant */ @@ -1023,6 +1025,7 @@ static void delete_from_sem_heap (moo_t* moo, moo_ooi_t index) MOO_ASSERT (moo, index >= 0 && index < moo->sem_heap_count); sem = moo->sem_heap[index]; + sem->heap_index = MOO_SMOOI_TO_OOP(-1); moo->sem_heap_count--; @@ -1059,90 +1062,162 @@ static void update_sem_heap (moo_t* moo, moo_ooi_t index, moo_oop_semaphore_t ne } #endif -static int add_to_sem_io (moo_t* moo, moo_oop_semaphore_t sem) +static int add_to_sem_io (moo_t* moo, moo_oop_semaphore_t sem, moo_ooi_t io_handle, moo_ooi_t io_mask) { moo_ooi_t index; - int n; + int n, tuple_added = 0; + moo_ooi_t new_mask; - if (moo->sem_io_count >= SEM_IO_MAX) + MOO_ASSERT (moo, (sem->io_index == (moo_oop_t)moo->_nil) || (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index == MOO_SMOOI_TO_OOP(-1))); + MOO_ASSERT (moo, sem->io_handle == (moo_oop_t)moo->_nil); + MOO_ASSERT (moo, sem->io_mask == (moo_oop_t)moo->_nil); + + MOO_ASSERT (moo, io_mask == MOO_SEMAPHORE_IO_MASK_INPUT || io_mask == MOO_SEMAPHORE_IO_MASK_OUTPUT); // TOOD: consider changing this to an error + + if (io_handle < 0 || io_handle >= MOO_COUNTOF(moo->sem_io_map)) /* TODO: change the condition when sem_io_map changes to a dynamic structure */ { - moo_seterrnum (moo, MOO_ESHFULL); + moo_seterrbfmt (moo, MOO_EINVAL, "handle %zd out of supported range", io_handle); return -1; } - if (moo->sem_io_count >= moo->sem_io_capa) + index = moo->sem_io_map[io_handle]; /* TODO: make it dynamic */ + if (index <= -1) { - moo_oow_t new_capa; - moo_oop_semaphore_t* tmp; + if (moo->sem_io_tuple_count >= SEM_IO_TUPLE_MAX) + { + moo_seterrbfmt (moo, MOO_ESHFULL, "too many IO semaphore tuples"); /* TODO: change error code */ + return -1; + } - /* 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; + if (moo->sem_io_tuple_count >= moo->sem_io_tuple_capa) + { + moo_oow_t new_capa; + moo_sem_tuple_t* tmp; - moo->sem_io = tmp; - moo->sem_io_capa = new_capa; - } + /* no overflow check when calculating the new capacity + * owing to SEM_IO_TUPLE_MAX check above */ + new_capa = moo->sem_io_tuple_capa + SEM_IO_TUPLE_INC; + tmp = moo_reallocmem (moo, moo->sem_io, MOO_SIZEOF(moo_sem_tuple_t) * new_capa); + if (!tmp) return -1; - MOO_ASSERT (moo, moo->sem_io_count <= MOO_SMOOI_MAX); - MOO_ASSERT (moo, sem->io_index == MOO_SMOOI_TO_OOP(-1)); + MOO_MEMSET (&tmp[moo->sem_io_tuple_capa], 0, MOO_SIZEOF(moo_sem_tuple_t) * (new_capa - moo->sem_io_tuple_capa)); + moo->sem_io = tmp; + moo->sem_io_tuple_capa = new_capa; + } - index = moo->sem_io_count; - moo->sem_io[index] = sem; - sem->io_index = MOO_SMOOI_TO_OOP(index); - moo->sem_io_count++; + MOO_ASSERT (moo, moo->sem_io_tuple_count <= MOO_SMOOI_MAX); + index = moo->sem_io_tuple_count; - moo_pushtmp (moo, (moo_oop_t*)&sem); - n = moo->vmprim.vm_muxadd (moo, sem); - moo_poptmp (moo); - if (n <= -1) - { - /* roll back */ - sem->io_index = MOO_SMOOI_TO_OOP(-1); - moo->sem_io_count--; + tuple_added = 1; + + new_mask = io_mask; + + moo_pushtmp (moo, (moo_oop_t*)&sem); + n = moo->vmprim.vm_muxadd(moo, io_handle, new_mask, (void*)index); + moo_poptmp (moo); } else { - /* update the number of IO semaphores in a group if necessary */ - if ((moo_oop_t)sem->group != moo->_nil) + new_mask = moo->sem_io[index].mask; /* existing mask */ + new_mask |= io_mask; + + if (new_mask == moo->sem_io[index].mask) { - moo_ooi_t count; - count = MOO_OOP_TO_SMOOI(sem->group->sem_io_count); - count++; - sem->group->sem_io_count = MOO_SMOOI_TO_OOP(count); + moo_oop_semaphore_t oldsem; + + if (moo->sem_io[index].mask & MOO_SEMAPHORE_IO_MASK_INPUT) + oldsem = moo->sem_io[index].in; + else + oldsem = moo->sem_io[index].out; + + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(oldsem->io_index) && MOO_OOP_TO_SMOOI(oldsem->io_index) == index); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(oldsem->io_handle)); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(oldsem->io_mask)); + moo_seterrbfmt (moo, MOO_EINVAL, "handle %zd already linked with a semaphore", MOO_OOP_TO_SMOOI(oldsem->io_handle)); + return -1; } + + moo_pushtmp (moo, (moo_oop_t*)&sem); + n = moo->vmprim.vm_muxmod(moo, io_handle, new_mask, index); + moo_poptmp (moo); } - return n; -} - -static MOO_INLINE int modify_in_sem_io (moo_t* moo, moo_oop_semaphore_t sem) -{ - return moo->vmprim.vm_muxmod (moo, sem); -} - -static int delete_from_sem_io (moo_t* moo, moo_ooi_t index) -{ - moo_oop_semaphore_t sem; - int x; - - MOO_ASSERT (moo, index >= 0 && index < moo->sem_io_count); - sem = moo->sem_io[index]; - MOO_ASSERT (moo, index == MOO_OOP_TO_SMOOI(sem->io_index)); - - moo_pushtmp (moo, (moo_oop_t*)&sem); - x = moo->vmprim.vm_muxdel (moo, sem); - moo_poptmp (moo); - if (x <= -1) + if (n <= -1) { - MOO_DEBUG2 (moo, "Failed to delete IO semaphore at index %zd on handle %zd\n", index, MOO_OOP_TO_SMOOI(sem->io_handle)); + MOO_DEBUG3 (moo, "Failed to add IO semaphore at index %zd on handle %zd mask %zx\n", index, io_handle, io_mask); return -1; } - MOO_DEBUG2 (moo, "Deleted IO semaphore at index %zd on handle %zd\n", index, MOO_OOP_TO_SMOOI(sem->io_handle)); + MOO_DEBUG3 (moo, "Added IO semaphore at index %zd on handle %zd mask %zx\n", index, io_handle, io_mask); + moo->sem_io_map[io_handle] = index; + + sem->io_index = MOO_SMOOI_TO_OOP(index); + sem->io_handle = MOO_SMOOI_TO_OOP(io_handle); + sem->io_mask = MOO_SMOOI_TO_OOP(io_mask); + + moo->sem_io[index].mask = new_mask; + /* successfully added the handle to the system multiplexer */ + if (io_mask == MOO_SEMAPHORE_IO_MASK_INPUT) + { + moo->sem_io[index].in = sem; + } + else /*if (io_mask == MOO_SEMAPHORE_IO_MASK_OUTPUT)*/ + { + moo->sem_io[index].out = sem; + } + moo->sem_io_count++; + if (tuple_added) moo->sem_io_tuple_count++; + + /* update the number of IO semaphores in a group if necessary */ + if ((moo_oop_t)sem->group != moo->_nil) + { + moo_ooi_t count; + count = MOO_OOP_TO_SMOOI(sem->group->sem_io_count); + count++; + sem->group->sem_io_count = MOO_SMOOI_TO_OOP(count); + } + + return 0; +} + +static int delete_from_sem_io (moo_t* moo, moo_oop_semaphore_t sem) +{ + moo_ooi_t index; + moo_ooi_t new_mask, io_handle; + int x; + + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_index)); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_handle)); + index = MOO_OOP_TO_SMOOI(sem->io_index); + MOO_ASSERT (moo, index >= 0 && index < moo->sem_io_count); + + new_mask = moo->sem_io[index].mask; + new_mask &= ~MOO_OOP_TO_SMOOI(sem->io_mask); /* calculate the new mask after deletion */ + new_mask &= MOO_SEMAPHORE_IO_MASK_INPUT | MOO_SEMAPHORE_IO_MASK_OUTPUT; /* for sanity */ + + io_handle = MOO_OOP_TO_SMOOI(sem->io_handle); + if (io_handle < 0 || io_handle >= MOO_COUNTOF(moo->sem_io_map)) /* TODO: change the condition when sem_io_map changes to a dynamic structure */ + { + moo_seterrbfmt (moo, MOO_EINVAL, "handle %zd out of supported range", io_handle); + return -1; + } + + moo_pushtmp (moo, (moo_oop_t*)&sem); + x = new_mask? moo->vmprim.vm_muxmod(moo, io_handle, new_mask, (void*)index): + moo->vmprim.vm_muxdel(moo, io_handle); + moo_poptmp (moo); + if (x <= -1) + { + MOO_DEBUG2 (moo, "Failed to delete IO semaphore at index %zd on handle %zd - %js\n", index, sem->io_handle); + return -1; + } + + MOO_DEBUG3 (moo, "Deleted IO semaphore at index %zd on handle %zd mask %zx\n", index, io_handle, MOO_OOP_TO_SMOOI(sem->io_mask)); sem->io_index = MOO_SMOOI_TO_OOP(-1); + sem->io_mask = moo->_nil; + sem->io_handle = moo->_nil; moo->sem_io_count--; + if ((moo_oop_t)sem->group != moo->_nil) { moo_ooi_t count; @@ -1152,73 +1227,76 @@ static int delete_from_sem_io (moo_t* moo, moo_ooi_t index) sem->group->sem_io_count = MOO_SMOOI_TO_OOP(count); } - if (/*moo->sem_io_count > 0 &&*/ index != moo->sem_io_count) + if (new_mask) { - moo_oop_semaphore_t lastsem; + moo->sem_io[index].mask = new_mask; + } + else + { + moo->sem_io_map[io_handle] = -1; - /* move the last item to the deletion position for compaction */ - lastsem = moo->sem_io[moo->sem_io_count]; - lastsem->io_index = MOO_SMOOI_TO_OOP(index); - moo->sem_io[index] = lastsem; + moo->sem_io_tuple_count--; - moo_pushtmp (moo, (moo_oop_t*)&lastsem); - x = moo->vmprim.vm_muxmod (moo, lastsem); - moo_poptmp (moo); - - if (x <= -1) + if (/*moo->sem_io_count > 0 &&*/ index != moo->sem_io_count) { - /* unfortunately, i can't roll back gracefully. i nullify the delete slot instead of compaction */ - MOO_LOG3 (moo, MOO_LOG_WARN, "Warning - IO sempahore migration failure from %zd to %zd on handle %zd - expect VM memory waste\n", moo->sem_io_count, MOO_OOP_TO_SMOOI(lastsem->io_index), MOO_OOP_TO_SMOOI(lastsem->io_handle)); - - lastsem->io_index = MOO_SMOOI_TO_OOP(moo->sem_io_count); - moo->sem_io[moo->sem_io_count] = lastsem; - moo->sem_io_count++; - moo->sem_io[index] = (moo_oop_semaphore_t)moo->_nil; - } - else - { - MOO_DEBUG3 (moo, "Migrated IO semaphore from index %zd to %zd on handle %zd\n", moo->sem_io_count, MOO_OOP_TO_SMOOI(lastsem->io_index), MOO_OOP_TO_SMOOI(lastsem->io_handle)); + moo->sem_io[index] = moo->sem_io[moo->sem_io_count]; + if (moo->sem_io[index].mask & MOO_SEMAPHORE_IO_MASK_INPUT) + moo->sem_io[index].in->io_index = MOO_SMOOI_TO_OOP(index); + if (moo->sem_io[index].mask & MOO_SEMAPHORE_IO_MASK_OUTPUT) + moo->sem_io[index].out->io_index = MOO_SMOOI_TO_OOP(index); } } return 0; } -static void signal_io_semaphore (moo_t* moo, moo_ooi_t mask, void* ctx) +static void _signal_io_semaphore (moo_t* moo, moo_oop_semaphore_t sem) +{ + moo_oop_process_t proc; + + proc = signal_semaphore (moo, sem); + + if (moo->processor->active == moo->nil_process && (moo_oop_t)proc != moo->_nil) + { + /* this is the only runnable process. + * switch the process to the running state. + * it uses wake_process() instead of + * switch_to_process() as there is no running + * process at this moment */ + MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE)); + MOO_ASSERT (moo, proc == moo->processor->runnable.first); + + #if 0 + wake_process (moo, proc); /* switch to running */ + moo->proc_switched = 1; + #else + switch_to_process_from_nil (moo, proc); + #endif + } +} + +static void signal_io_semaphore (moo_t* moo, /*moo_ooi_t io_handle,*/ moo_ooi_t mask, void* ctx) { moo_oow_t sem_io_index = (moo_oow_t)ctx; /* TODO: sanity check on the index. conditional handling on mask */ - if (sem_io_index < moo->sem_io_count) + + if (sem_io_index < moo->sem_io_count /*&& + io_handle >= 0 && io_handle < MOO_COUNTOF(moo->sem_io_map) && + moo->sem_io_map[io_handle] == sem_io_index*/) { moo_oop_semaphore_t sem; - moo_oop_process_t proc; - sem = moo->sem_io[sem_io_index]; - if ((moo_oop_t)sem == moo->_nil) + sem = moo->sem_io[sem_io_index].in; + if (sem && (mask & (MOO_SEMAPHORE_IO_MASK_INPUT | MOO_SEMAPHORE_IO_MASK_HANGUP | MOO_SEMAPHORE_IO_MASK_ERROR))) { - /* it's a nullified slot for migration failure in delete_from_sem_io() */ - goto invalid_semaphore; + _signal_io_semaphore (moo, sem); } - proc = signal_semaphore (moo, sem); - - if (moo->processor->active == moo->nil_process && (moo_oop_t)proc != moo->_nil) + sem = moo->sem_io[sem_io_index].out; + if (sem && (mask & MOO_SEMAPHORE_IO_MASK_OUTPUT)) { - /* this is the only runnable process. - * switch the process to the running state. - * it uses wake_process() instead of - * switch_to_process() as there is no running - * process at this moment */ - MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE)); - MOO_ASSERT (moo, proc == moo->processor->runnable.first); - - #if 0 - wake_process (moo, proc); /* switch to running */ - moo->proc_switched = 1; - #else - switch_to_process_from_nil (moo, proc); - #endif + _signal_io_semaphore (moo, sem); } } else @@ -2392,7 +2470,6 @@ static moo_pfrc_t __system_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, moo_oo fd = MOO_STACK_GETARG(moo, nargs, 1); sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0); - if (!moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore)) { moo_seterrbfmt (moo, MOO_EINVAL, "parameter not a kind of semaphore - %O", sem); @@ -2401,49 +2478,26 @@ static moo_pfrc_t __system_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, moo_oo if (!MOO_OOP_IS_SMOOI(fd)) { - moo_seterrbfmt (moo, MOO_EINVAL, "IO handle not a small integer - %O", fd); + moo_seterrbfmt (moo, MOO_EINVAL, "handle not a small integer - %O", fd); return MOO_PF_FAILURE; } - - if (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index != MOO_SMOOI_TO_OOP(-1) && sem->io_handle == fd) + if (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index != MOO_SMOOI_TO_OOP(-1)) { - moo_ooi_t old_mask; + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_handle) && MOO_OOP_TO_SMOOI(sem->io_handle) >= 0); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_mask) && MOO_OOP_TO_SMOOI(sem->io_mask) > 0); - /* the semaphore is already linked with the requested IO handle */ - - old_mask = MOO_OOP_TO_SMOOI(sem->io_mask); - if (old_mask != mask) - { - sem->io_mask = MOO_SMOOI_TO_OOP(mask); - if (modify_in_sem_io(moo, sem) <= -1) - { - sem->io_mask = MOO_SMOOI_TO_OOP(old_mask); - moo_seterrbfmt (moo, moo->errnum, "cannot modify the handle %zd in the multiplexer", MOO_OOP_TO_SMOOI(sem->io_handle)); - return MOO_PF_FAILURE; - } - } + moo_seterrbfmt (moo, MOO_EINVAL, "semaphore already linked with a handle %zd", MOO_OOP_TO_SMOOI(sem->io_handle)); + return MOO_PF_FAILURE; } - else - { - 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 */ - if (delete_from_sem_io(moo, MOO_OOP_TO_SMOOI(sem->io_index)) <= -1) - { - moo_seterrbfmt (moo, moo->errnum, "cannot delete the handle %zd from the multiplexer", MOO_OOP_TO_SMOOI(sem->io_handle)); - return MOO_PF_FAILURE; - } - MOO_ASSERT (moo, sem->io_index == MOO_SMOOI_TO_OOP(-1)); - } - sem->io_handle = fd; - sem->io_mask = MOO_SMOOI_TO_OOP(mask); - if (add_to_sem_io(moo, sem) <= -1) - { - moo_seterrbfmt (moo, moo->errnum, "cannot add the handle %zd to the multiplexer", MOO_OOP_TO_SMOOI(sem->io_handle)); - return MOO_PF_FAILURE; - } + /*sem->io_handle = fd; + sem->io_mask = MOO_SMOOI_TO_OOP(mask);*/ + if (add_to_sem_io(moo, sem, MOO_OOP_TO_SMOOI(fd), mask) <= -1) + { + moo_copyoocstr (moo->errmsg.buf2, MOO_COUNTOF(moo->errmsg.buf2), moo->errmsg.buf); + moo_seterrbfmt (moo, moo->errnum, "cannot add the handle %zd to the multiplexer - %js", MOO_OOP_TO_SMOOI(fd), moo->errmsg.buf2); + return MOO_PF_FAILURE; } MOO_STACK_SETRETTORCV (moo, nargs); /* ^self */ @@ -2500,9 +2554,10 @@ static moo_pfrc_t pf_system_remove_semaphore (moo_t* moo, moo_ooi_t nargs) if (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index != MOO_SMOOI_TO_OOP(-1)) { /* the semaphore is associated with IO */ - if (delete_from_sem_io (moo, MOO_OOP_TO_SMOOI(sem->io_index)) <= -1) + if (delete_from_sem_io (moo, sem) <= -1) { - moo_seterrbfmt (moo, moo->errnum, "cannot delete the handle %zd from the multiplexer", MOO_OOP_TO_SMOOI(sem->io_handle)); + moo_copyoocstr (moo->errmsg.buf2, MOO_COUNTOF(moo->errmsg.buf2), moo->errmsg.buf); + moo_seterrbfmt (moo, moo->errnum, "cannot delete the handle %zd from the multiplexer - %js", MOO_OOP_TO_SMOOI(sem->io_handle), moo->errmsg.buf2); return MOO_PF_FAILURE; } diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 2db98a1..8b063fe 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -898,7 +898,10 @@ void moo_gc (moo_t* moo) 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]); + if (moo->sem_io[i].in) + moo->sem_io[i].in = (moo_oop_semaphore_t)moo_moveoop (moo, (moo_oop_t)moo->sem_io[i].in); + if (moo->sem_io[i].out) + moo->sem_io[i].out = (moo_oop_semaphore_t)moo_moveoop (moo, (moo_oop_t)moo->sem_io[i].out); } moo->sem_gcfin = (moo_oop_semaphore_t)moo_moveoop (moo, (moo_oop_t)moo->sem_gcfin); diff --git a/moo/lib/main.c b/moo/lib/main.c index b75da65..2518921 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -855,7 +855,7 @@ static MOO_INLINE void destroy_poll_data_space (moo_t* moo) #endif -static int _add_poll_fd (moo_t* moo, int fd, int event_mask, moo_oow_t event_data) +static int _add_poll_fd (moo_t* moo, int fd, int event_mask, void* event_data) { #if defined(USE_DEVPOLL) xtn_t* xtn = (xtn_t*)moo_getxtn(moo); @@ -869,7 +869,7 @@ static int _add_poll_fd (moo_t* moo, int fd, int event_mask, moo_oow_t event_dat ev.revents = 0; if (write (xtn->ep, &ev, MOO_SIZEOF(ev)) != MOO_SIZEOF(ev)) { - moo_syserr_to_errnum (errno); + moo_seterrwithsyserr (moo, errno); MOO_DEBUG2 (moo, "Cannot add file descriptor %d to devpoll - %hs\n", fd, strerror(errno)); return -1; } @@ -890,9 +890,10 @@ static int _add_poll_fd (moo_t* moo, int fd, int event_mask, moo_oow_t event_dat ev.events |= EPOLLET; #endif ev.data.ptr = (void*)event_data; - if (epoll_ctl (xtn->ep, EPOLL_CTL_ADD, fd, &ev) == -1) + if (epoll_ctl(xtn->ep, EPOLL_CTL_ADD, fd, &ev) == -1) { - moo_syserr_to_errnum (errno); + + moo_seterrwithsyserr (moo, errno); MOO_DEBUG2 (moo, "Cannot add file descriptor %d to epoll - %hs\n", fd, strerror(errno)); return -1; } @@ -1050,7 +1051,7 @@ static int _del_poll_fd (moo_t* moo, int fd) } -static int _mod_poll_fd (moo_t* moo, int fd, int event_mask, moo_oow_t event_data) +static int _mod_poll_fd (moo_t* moo, int fd, int event_mask, void* event_data) { #if defined(USE_DEVPOLL) @@ -1073,7 +1074,7 @@ static int _mod_poll_fd (moo_t* moo, int fd, int event_mask, moo_oow_t event_dat ev.data.ptr = (void*)event_data; if (epoll_ctl (xtn->ep, EPOLL_CTL_MOD, fd, &ev) == -1) { - moo_syserr_to_errnum (errno); + moo_seterrwithsyserr (moo, errno); MOO_DEBUG2 (moo, "Cannot modify file descriptor %d in epoll - %hs\n", fd, strerror(errno)); return -1; } @@ -1213,7 +1214,7 @@ static int vm_startup (moo_t* moo) if (flag >= 0) fcntl (xtn->p[1], F_SETFL, flag | O_NONBLOCK); #endif - if (_add_poll_fd(moo, xtn->p[0], XPOLLIN, MOO_TYPE_MAX(moo_oow_t)) <= -1) goto oops; + if (_add_poll_fd(moo, xtn->p[0], XPOLLIN, (void*)MOO_TYPE_MAX(moo_oow_t)) <= -1) goto oops; pthread_mutex_init (&xtn->ev.mtx, MOO_NULL); pthread_cond_init (&xtn->ev.cnd, MOO_NULL); @@ -1381,57 +1382,45 @@ static void vm_gettime (moo_t* moo, moo_ntime_t* now) #endif -static int vm_muxadd (moo_t* moo, moo_oop_semaphore_t sem) +static int vm_muxadd (moo_t* moo, moo_ooi_t io_handle, moo_ooi_t mask, void* ctx) { - moo_ooi_t mask; int event_mask; - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_index)); - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_handle)); - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_mask)); - - mask = MOO_OOP_TO_SMOOI(sem->io_mask); event_mask = 0; /*EPOLLET; */ /* TODO: use edge trigger(EPOLLLET)? */ if (mask & MOO_SEMAPHORE_IO_MASK_INPUT) event_mask |= XPOLLIN; if (mask & MOO_SEMAPHORE_IO_MASK_OUTPUT) event_mask |= XPOLLOUT; if (event_mask == 0) { - MOO_DEBUG2 (moo, " Invalid semaphore mask %zd on handle %zd\n", mask, MOO_OOP_TO_SMOOI(sem->io_handle)); - moo_seterrnum (moo, MOO_EINVAL); + MOO_DEBUG2 (moo, " Invalid semaphore mask %zd on handle %zd\n", mask, io_handle); + moo_seterrbfmt (moo, MOO_EINVAL, "invalid semaphore mask %zd on handle %zd", mask, io_handle); return -1; } - return _add_poll_fd (moo, MOO_OOP_TO_SMOOI(sem->io_handle), event_mask, MOO_OOP_TO_SMOOI(sem->io_index)); + return _add_poll_fd (moo, io_handle, event_mask, ctx); } -static int vm_muxmod (moo_t* moo, moo_oop_semaphore_t sem) +static int vm_muxmod (moo_t* moo, moo_ooi_t io_handle, moo_ooi_t mask, void* ctx) { - moo_ooi_t mask; int event_mask; - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_index)); - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_handle)); - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_mask)); - - mask = MOO_OOP_TO_SMOOI(sem->io_mask); event_mask = 0; /*EPOLLET; */ /* TODO: use edge trigger(EPOLLLET)? */ if (mask & MOO_SEMAPHORE_IO_MASK_INPUT) event_mask |= XPOLLIN; if (mask & MOO_SEMAPHORE_IO_MASK_OUTPUT) event_mask |= XPOLLOUT; if (event_mask == 0) { - MOO_DEBUG2 (moo, " Invalid semaphore mask %zd on handle %zd\n", mask, MOO_OOP_TO_SMOOI(sem->io_handle)); - moo_seterrnum (moo, MOO_EINVAL); + MOO_DEBUG2 (moo, " Invalid semaphore mask %zd on handle %zd\n", mask, io_handle); + moo_seterrbfmt (moo, MOO_EINVAL, "invalid semaphore mask %zd on handle %zd", mask, io_handle); return -1; } - return _mod_poll_fd (moo, MOO_OOP_TO_SMOOI(sem->io_handle), event_mask, MOO_OOP_TO_SMOOI(sem->io_index)); + return _mod_poll_fd (moo, io_handle, event_mask, ctx); } -static int vm_muxdel (moo_t* moo, moo_oop_semaphore_t sem) +static int vm_muxdel (moo_t* moo, moo_ooi_t io_handle) { - return _del_poll_fd (moo, MOO_OOP_TO_SMOOI(sem->io_handle)); + return _del_poll_fd (moo, io_handle); } #if defined(USE_THREAD) @@ -2163,12 +2152,12 @@ int main (int argc, char* argv[]) moo_bci_t c; static moo_bopt_lng_t lopt[] = { - { ":log", 'l' }, - { ":memsize", 'm' }, + { ":log", 'l' }, + { ":memsize", 'm' }, #if !defined(NDEBUG) - { ":debug", '\0' }, /* NOTE: there is no short option for --debug */ + { ":debug", '\0' }, /* NOTE: there is no short option for --debug */ #endif - { MOO_NULL, '\0' } + { MOO_NULL, '\0' } }; static moo_bopt_t opt = { @@ -2207,6 +2196,7 @@ int main (int argc, char* argv[]) break; case '\0': + #if !defined(NDEBUG) if (moo_compbcstr(opt.lngopt, "debug") == 0) { @@ -2214,6 +2204,7 @@ int main (int argc, char* argv[]) break; } #endif + goto print_usage; case ':': diff --git a/moo/lib/moo-cfg.h.in b/moo/lib/moo-cfg.h.in index 916e9db..a0e1a0d 100644 --- a/moo/lib/moo-cfg.h.in +++ b/moo/lib/moo-cfg.h.in @@ -172,6 +172,12 @@ /* Define if libtool can extract symbol lists from object files. */ #undef HAVE_PRELOADED_SYMBOLS +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Have PTHREAD_PRIO_INHERIT. */ +#undef HAVE_PTHREAD_PRIO_INHERIT + /* Define to 1 if you have the `quadmath_snprintf' function. */ #undef HAVE_QUADMATH_SNPRINTF @@ -483,6 +489,10 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + /* The size of `char', as computed by sizeof. */ #undef SIZEOF_CHAR diff --git a/moo/lib/moo.c b/moo/lib/moo.c index aa4b0c7..139fe14 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -85,6 +85,7 @@ static void fill_bigint_tables (moo_t* moo) int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_oow_t heapsz, const moo_vmprim_t* vmprim) { int modtab_inited = 0; + int i; MOO_MEMSET (moo, 0, MOO_SIZEOF(*moo)); moo->mmgr = mmgr; @@ -130,6 +131,9 @@ int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_oow_t heapsz, const moo_vmprim_t moo->proc_map_free_first = -1; moo->proc_map_free_last = -1; + + for (i = 0; i < MOO_COUNTOF(moo->sem_io_map); i++) moo->sem_io_map[i] = -1; + return 0; oops: @@ -178,7 +182,8 @@ void moo_fini (moo_t* moo) if (moo->sem_io) { moo_freemem (moo, moo->sem_io); - moo->sem_io_capa = 0; + moo->sem_io_tuple_capa = 0; + moo->sem_io_tuple_count = 0; moo->sem_io_count = 0; moo->sem_io_wait_count = 0; } diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 35d8dca..fa22b01 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -123,7 +123,7 @@ enum moo_trait_t MOO_NOGC = (1 << 8), /* wait for running process when exiting from the main method */ - MOO_AWAIT_PROCS = (1 << 9) + MOO_AWAIT_PROCS = (1 << 9), }; typedef enum moo_trait_t moo_trait_t; @@ -823,6 +823,7 @@ struct moo_semaphore_t moo_oop_t io_mask; /* SmallInteger */ moo_oop_t signal_action; + moo_oop_semaphore_group_t group; /* nil or belonging semaphore group */ struct { @@ -925,9 +926,9 @@ 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 int (*moo_vmprim_muxadd_t) (moo_t* moo, moo_oop_semaphore_t sem); -typedef int (*moo_vmprim_muxmod_t) (moo_t* moo, moo_oop_semaphore_t sem); -typedef int (*moo_vmprim_muxdel_t) (moo_t* moo, moo_oop_semaphore_t sem); +typedef int (*moo_vmprim_muxadd_t) (moo_t* moo, moo_ooi_t io_handle, moo_ooi_t mask, void* ctx); +typedef int (*moo_vmprim_muxmod_t) (moo_t* moo, moo_ooi_t io_handle, moo_ooi_t mask, void* ctx); +typedef int (*moo_vmprim_muxdel_t) (moo_t* moo, moo_ooi_t sem); typedef void (*moo_vmprim_muxwait_cb_t) (moo_t* moo, moo_ooi_t mask, void* ctx); typedef void (*moo_vmprim_muxwait_t) (moo_t* moo, const moo_ntime_t* duration, moo_vmprim_muxwait_cb_t muxwcb); @@ -1097,6 +1098,14 @@ struct moo_sbuf_t }; typedef struct moo_sbuf_t moo_sbuf_t; +struct moo_sem_tuple_t +{ + moo_oop_semaphore_t in; + moo_oop_semaphore_t out; + moo_ooi_t mask; +}; +typedef struct moo_sem_tuple_t moo_sem_tuple_t; + typedef struct moo_finalizable_t moo_finalizable_t; struct moo_finalizable_t { @@ -1123,6 +1132,7 @@ struct moo_t struct { + moo_ooch_t buf2[2048]; moo_ooch_t buf[2048]; moo_oow_t len; } errmsg; @@ -1242,11 +1252,17 @@ struct moo_t moo_oow_t sem_heap_capa; /* semaphores for I/O handling. plain array */ - moo_oop_semaphore_t* sem_io; + /*moo_oop_semaphore_t* sem_io;*/ + moo_sem_tuple_t* sem_io; + moo_oow_t sem_io_tuple_count; + moo_oow_t sem_io_tuple_capa; + moo_oow_t sem_io_count; - moo_oow_t sem_io_capa; moo_oow_t sem_io_wait_count; + moo_ooi_t sem_io_map[10240]; /* TODO: make it dynamic */ + + /* semaphore to notify finalizable objects */ moo_oop_semaphore_t sem_gcfin; int sem_gcfin_sigreq; diff --git a/moo/mod/Makefile.am b/moo/mod/Makefile.am index 8382a0e..a956e49 100644 --- a/moo/mod/Makefile.am +++ b/moo/mod/Makefile.am @@ -1,5 +1,7 @@ AUTOMAKE_OPTIONS = nostdinc +##AM_CFLAGS = $(PTHREAD_CFLAGS) + CPPFLAGS_COMMON = \ -I$(abs_builddir) \ -I$(abs_builddir)/../lib \ diff --git a/moo/mod/Makefile.in b/moo/mod/Makefile.in index 5e5582c..1a42df7 100644 --- a/moo/mod/Makefile.in +++ b/moo/mod/Makefile.in @@ -97,10 +97,11 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/argz.m4 \ $(top_srcdir)/m4/ax_cxx_namespace.m4 \ - $(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltdl.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -360,6 +361,9 @@ PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ QUADMATH_LIBS = @QUADMATH_LIBS@ RANLIB = @RANLIB@ SED = @SED@ @@ -382,6 +386,7 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ diff --git a/moo/mod/sck.c b/moo/mod/sck.c index 5add543..63fd994 100644 --- a/moo/mod/sck.c +++ b/moo/mod/sck.c @@ -133,7 +133,7 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) struct sockaddr_in sin; memset (&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; -sin.sin_addr.s_addr = inet_addr ("192.168.1.143"); +sin.sin_addr.s_addr = inet_addr ("192.168.1.145"); sin.sin_port = htons(12345); do {