X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/59a1aff0fbe12fa74b7d0b9fb46492fa7a822acc..6137018268142ce0a772f64287953a44a5186b2b:/acmacro/context.m4 diff --git a/acmacro/context.m4 b/acmacro/context.m4 index d0836c1e4e..17dff0777b 100644 --- a/acmacro/context.m4 +++ b/acmacro/context.m4 @@ -1,18 +1,402 @@ dnl AC_CHECK_UCONTEXT: Check whether ucontext are working -dnl it uses AC_RUN and assume the worse while cross-compiling - -AC_DEFUN([AC_CHECK_UCONTEXT], - [ -AC_MSG_CHECKING([whether ucontext'es exist and are usable...]) -AC_RUN_IFELSE(AC_LANG_PROGRAM([#include ], - [ucontext_t uc; - if (getcontext (&uc) != 0) return -1; - ]), - AC_MSG_RESULT(yes) - ac_check_ucontext=yes, - AC_MSG_RESULT(no) - ac_check_ucontext=no, - AC_MSG_RESULT(assuming the worse in cross-compilation) - ac_check_ucontext=no) +dnl Most of the code is stolen from the GNU pth autoconf macros by +dnl Ralf S. Engelschall. +dnl # ``"Reuse an expert's code" is the right +dnl # advice for most people. But it's a useless +dnl # advice for the experts writing the code +dnl # in the first place.' +dnl # -- Dan J. Bernstein +dnl +dnl OK, you're definitely the expert on this point... :) + +dnl ## +dnl ## Display Configuration Headers +dnl ## +dnl ## configure.ac: +dnl ## AC_MSG_PART() +dnl ## + +m4_define(AC_MSG_PART,[dnl +if test ".$enable_subdir" != .yes; then + AC_MSG_RESULT() + AC_MSG_RESULT(${TB}$1:${TN}) +fi +])dnl + +dnl ## +dnl ## Display a message under --verbose +dnl ## +dnl ## configure.ac: +dnl ## AC_MSG_VERBOSE() +dnl ## + +m4_define(AC_MSG_VERBOSE,[dnl +if test ".$verbose" = .yes; then + AC_MSG_RESULT([ $1]) +fi +]) + +dnl ## +dnl ## Do not display message for a command +dnl ## +dnl ## configure.ac: +dnl ## AC_MSG_SILENT(...) +dnl ## + +m4_define(AC_FD_TMP, 9) +m4_define(AC_MSG_SILENT,[dnl +exec AC_FD_TMP>&AC_FD_MSG AC_FD_MSG>/dev/null +$1 +exec AC_FD_MSG>&AC_FD_TMP AC_FD_TMP>&- +]) + +dnl ## +dnl ## Check for direction of stack growth +dnl ## +dnl ## configure.ac: +dnl ## AC_CHECK_STACKGROWTH() +dnl ## acconfig.h: +dnl ## #undef +dnl ## source.c: +dnl ## #include "config.h" +dnl ## #if < 0 +dnl ## ...stack grow down... +dnl ## #else +dnl ## ...stack grow up... +dnl ## #endif +dnl ## + +AC_DEFUN([AC_CHECK_STACKGROWTH],[dnl +AC_MSG_CHECKING(for direction of stack growth) +AC_CACHE_VAL(ac_cv_check_stackgrowth, [ +cross_compiling=no +AC_TRY_RUN( +changequote(<<, >>)dnl +<< +#include +#include +static int iterate = 10; +static int growsdown(int *x) +{ + auto int y; + y = (x > &y); + if (--iterate > 0) + y = growsdown(&y); + if (y != (x > &y)) + exit(1); + return y; +} +int main(int argc, char *argv[]) +{ + FILE *f; + auto int x; + if ((f = fopen("conftestval", "w")) == NULL) + exit(1); + fprintf(f, "%s\n", growsdown(&x) ? "down" : "up");; + fclose(f); + exit(0); +} +>> +changequote([, ])dnl +, +ac_cv_check_stackgrowth=`cat conftestval`, +ac_cv_check_stackgrowth=down, +ac_cv_check_stackgrowth=down +)dnl +])dnl +AC_MSG_RESULT([$ac_cv_check_stackgrowth]) +if test ".$ac_cv_check_stackgrowth" = ".down"; then + val="-1" +else + val="+1" +fi +AC_DEFINE_UNQUOTED($1, $val, [define for stack growth]) +]) + +dnl ## +dnl ## Check whether SVR4/SUSv2 makecontext(2), swapcontext(2) and +dnl ## friends can be used for user-space context switching +dnl ## +dnl ## configure.ac: +dnl ## AC_CHECK_MCSC(, ) +dnl ## + +AC_DEFUN([AC_CHECK_MCSC], [ +AC_MSG_CHECKING(for usable SVR4/SUSv2 makecontext(2)/swapcontext(2)) +AC_CACHE_VAL(ac_cv_check_mcsc, [ +AC_TRY_RUN([ + +#include +#include +#include + +ucontext_t uc_child; +ucontext_t uc_main; + +void child(void *arg) +{ + if (arg != (void *)12345) + exit(1); + if (swapcontext(&uc_child, &uc_main) != 0) + exit(1); +} + +int main(int argc, char *argv[]) +{ + FILE *fp; + void *stack; + + /* the default is that it fails */ + if ((fp = fopen("conftestval", "w")) == NULL) + exit(1); + fprintf(fp, "no\n"); + fclose(fp); + + /* configure a child user-space context */ + if ((stack = malloc(64*1024)) == NULL) + exit(1); + if (getcontext(&uc_child) != 0) + exit(1); + uc_child.uc_link = NULL; + uc_child.uc_stack.ss_sp = (char *)stack+(32*1024); + uc_child.uc_stack.ss_size = 32*1024; + uc_child.uc_stack.ss_flags = 0; + makecontext(&uc_child, child, 2, (void *)12345); + + /* switch into the user context */ + if (swapcontext(&uc_main, &uc_child) != 0) + exit(1); + + /* Fine, child came home */ + if ((fp = fopen("conftestval", "w")) == NULL) + exit(1); + fprintf(fp, "yes\n"); + fclose(fp); + + /* die successfully */ + exit(0); +} +], +ac_cv_check_mcsc=`cat conftestval`, +ac_cv_check_mcsc=no, +ac_cv_check_mcsc=no +)dnl +])dnl +AC_MSG_RESULT([$ac_cv_check_mcsc]) +if test ".$ac_cv_check_mcsc" = .yes; then + ifelse([$1], , :, [$1]) +else + ifelse([$2], , :, [$2]) +fi +])dnl + +dnl ## +dnl ## Check how stacks have to be setup for the functions +dnl ## sigstack(2), sigaltstack(2) and makecontext(2). +dnl ## +dnl ## configure.ac: +dnl ## AC_CHECK_STACKSETUP(sigstack|sigaltstack|makecontext, , ) +dnl ## acconfig.h: +dnl ## #undef HAVE_{SIGSTACK|SIGALTSTACK|MAKECONTEXT} +dnl ## #undef HAVE_STACK_T +dnl ## header.h.in: +dnl ## @@ +dnl ## @@ +dnl ## source.c: +dnl ## #include "header.h" +dnl ## xxx.sp_ss = (skaddr, sksize); +dnl ## xxx.sp_size = (skaddr, sksize); +dnl ## + +AC_DEFUN([AC_CHECK_STACKSETUP],[dnl +dnl # check for consistent usage +ifelse($1,[sigstack],,[ +ifelse($1,[sigaltstack],,[ +ifelse($1,[makecontext],,[ +errprint(__file__:__line__: [AC_CHECK_STACKSETUP: only sigstack, sigaltstack and makecontext supported +])])])]) +dnl # we require the C compiler and the standard headers +AC_REQUIRE([AC_HEADER_STDC])dnl +dnl # we at least require the function to check +AC_CHECK_FUNCS($1) +dnl # sigaltstack on some platforms uses stack_t instead of struct sigaltstack +ifelse($1, sigaltstack, [ + AC_ONCE(stacksetup_stack_t, [ + AC_CHECK_TYPEDEF(stack_t, signal.h) + ]) +]) +dnl # display processing header +AC_MSG_CHECKING(for stack setup via $1) +dnl # but cache the whole results +AC_CACHE_VAL(ac_cv_stacksetup_$1,[ +if test ".$ac_cv_func_$1" = .no; then + dnl # no need to check anything when function is already missing + ac_cv_stacksetup_$1="N.A.:/*N.A.*/,/*N.A.*/" +else + dnl # setup compile environment + OCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -DTEST_$1" + cross_compiling=no + dnl # compile and run the test program + AC_TRY_RUN([ +#include +#include +#include +#if defined(TEST_sigstack) || defined(TEST_sigaltstack) +#include +#include +#include +#endif +#if defined(TEST_makecontext) +#include +#endif +union alltypes { + long l; + double d; + void *vp; + void (*fp)(void); + char *cp; +}; +static volatile char *handler_addr = (char *)0xDEAD; +#if defined(TEST_sigstack) || defined(TEST_sigaltstack) +static volatile int handler_done = 0; +void handler(int sig) +{ + char garbage[1024]; + int i; + auto int dummy; + for (i = 0; i < 1024; i++) + garbage[i] = 'X'; + handler_addr = (char *)&dummy; + handler_done = 1; + return; +} +#endif +#if defined(TEST_makecontext) +static ucontext_t uc_handler; +static ucontext_t uc_main; +void handler(void) +{ + char garbage[1024]; + int i; + auto int dummy; + for (i = 0; i < 1024; i++) + garbage[i] = 'X'; + handler_addr = (char *)&dummy; + swapcontext(&uc_handler, &uc_main); + return; +} +#endif +int main(int argc, char *argv[]) +{ + FILE *f; + char *skaddr; + char *skbuf; + int sksize; + char result[1024]; + int i; + sksize = 32768; + skbuf = (char *)malloc(sksize*2+2*sizeof(union alltypes)); + if (skbuf == NULL) + exit(1); + for (i = 0; i < sksize*2+2*sizeof(union alltypes); i++) + skbuf[i] = 'A'; + skaddr = skbuf+sizeof(union alltypes); +#if defined(TEST_sigstack) || defined(TEST_sigaltstack) + { + struct sigaction sa; +#if defined(TEST_sigstack) + struct sigstack ss; +#elif defined(TEST_sigaltstack) && defined(HAVE_STACK_T) + stack_t ss; +#else + struct sigaltstack ss; +#endif +#if defined(TEST_sigstack) + ss.ss_sp = (void *)(skaddr + sksize); + ss.ss_onstack = 0; + if (sigstack(&ss, NULL) < 0) + exit(1); +#elif defined(TEST_sigaltstack) + ss.ss_sp = (void *)(skaddr + sksize); + ss.ss_size = sksize; + ss.ss_flags = 0; + if (sigaltstack(&ss, NULL) < 0) + exit(1); +#endif + memset((void *)&sa, 0, sizeof(struct sigaction)); + sa.sa_handler = handler; + sa.sa_flags = SA_ONSTACK; + sigemptyset(&sa.sa_mask); + sigaction(SIGUSR1, &sa, NULL); + kill(getpid(), SIGUSR1); + while (!handler_done) + /*nop*/; + } +#endif +#if defined(TEST_makecontext) + { + if (getcontext(&uc_handler) != 0) + exit(1); + uc_handler.uc_link = NULL; + uc_handler.uc_stack.ss_sp = (void *)(skaddr + sksize); + uc_handler.uc_stack.ss_size = sksize; + uc_handler.uc_stack.ss_flags = 0; + makecontext(&uc_handler, handler, 1); + swapcontext(&uc_main, &uc_handler); + } +#endif + if (handler_addr == (char *)0xDEAD) + exit(1); + if (handler_addr < skaddr+sksize) { + /* stack was placed into lower area */ + if (*(skaddr+sksize) != 'A') + sprintf(result, "(skaddr)+(sksize)-%d,(sksize)-%d", + sizeof(union alltypes), sizeof(union alltypes)); + else + strcpy(result, "(skaddr)+(sksize),(sksize)"); + } + else { + /* stack was placed into higher area */ + if (*(skaddr+sksize*2) != 'A') + sprintf(result, "(skaddr),(sksize)-%d", sizeof(union alltypes)); + else + strcpy(result, "(skaddr),(sksize)"); + } + if ((f = fopen("conftestval", "w")) == NULL) + exit(1); + fprintf(f, "%s\n", result); + fclose(f); + exit(0); +} +],[ +dnl # test successully passed +ac_cv_stacksetup_$1=`cat conftestval` +ac_cv_stacksetup_$1="ok:$ac_cv_stacksetup_$1" +],[ +dnl # test failed +ac_cv_stacksetup_$1='guessed:(skaddr),(sksize)' +],[ +dnl # cross-platform => failed +ac_cv_stacksetup_$1='guessed:(skaddr),(sksize)' +]) +dnl # restore original compile environment +CFLAGS="$OCFLAGS" +])dnl +fi +dnl # extract result ingredients of single cached result value +type=`echo $ac_cv_stacksetup_$1 | sed -e 's;:.*$;;'` +addr=`echo $ac_cv_stacksetup_$1 | sed -e 's;^.*:;;' -e 's;,.*$;;'` +size=`echo $ac_cv_stacksetup_$1 | sed -e 's;^.*:;;' -e 's;^.*,;;'` +dnl # export result ingredients +$2="#define $2(skaddr,sksize) ($addr)" +$3="#define $3(skaddr,sksize) ($size)" +AC_SUBST($2)dnl +AC_SUBST($3)dnl +dnl # display result indicator +AC_MSG_RESULT([$type]) +dnl # display results in detail +AC_MSG_VERBOSE([$]$2) +AC_MSG_VERBOSE([$]$3) ])