lwp: test for working swapcontext() and friends
authorChas Williams (CONTRACTOR) <chas@cmf.nrl.navy.mil>
Sat, 19 Feb 2011 15:19:24 +0000 (10:19 -0500)
committerDerrick Brashear <shadow@dementia.org>
Tue, 22 Feb 2011 08:56:40 +0000 (00:56 -0800)
The USE_UCONTEXT was a temporary fix until someone wrote a reasonable
test of the user context swapping functions.  While these are present
on many operating systems, they simply aren't complete.  This test
correctly fails on IRIX, MacOS and some versions of Linux (in particular,
ppc 32-bit binaries on a 64-bit processor).

Change-Id: Ie2f340d661002c8f3c78dddbaf755257cb4ca286
Reviewed-on: http://gerrit.openafs.org/4018
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

src/cf/ucontext.m4 [new file with mode: 0644]

diff --git a/src/cf/ucontext.m4 b/src/cf/ucontext.m4
new file mode 100644 (file)
index 0000000..e6c7025
--- /dev/null
@@ -0,0 +1,52 @@
+dnl Test getcontext() and makecontext() to ensure that we are able to
+dnl copy the current user context, modify it with our own private stack
+dnl and return to the original user context.
+dnl
+AC_DEFUN([OPENAFS_WORKING_UCONTEXT],[
+  AC_MSG_CHECKING([if user context manipulation is complete])
+  AC_TRY_RUN([
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UCONTEXT_H
+#include <ucontext.h>
+#endif
+
+#define STACK_SIZE 16384
+
+static ucontext_t main_context, thread_context;
+static char *alt_stack;
+
+static void
+thread(void)
+{
+       unsigned long stack_ptr;
+       unsigned long offset;
+
+       offset = (unsigned long) &stack_ptr - (unsigned long) alt_stack;
+       if (offset > STACK_SIZE)
+               exit(EXIT_FAILURE);
+       swapcontext(&thread_context, &main_context);
+       /* should never get here */
+       exit(EXIT_FAILURE);
+}
+
+int
+main(int argc, char **argv)
+{
+       if (getcontext(&thread_context) == -1)
+               exit(EXIT_FAILURE);
+       alt_stack = malloc(STACK_SIZE);
+       if (!alt_stack)
+               exit(EXIT_FAILURE);
+       thread_context.uc_stack.ss_sp = alt_stack;
+       thread_context.uc_stack.ss_size = STACK_SIZE;
+       makecontext(&thread_context, thread, 0);
+
+       if (swapcontext(&main_context, &thread_context) == -1)
+               exit(EXIT_FAILURE);
+
+       free(alt_stack);
+       exit(EXIT_SUCCESS);
+}],AC_MSG_RESULT([yes])
+   AC_DEFINE([HAVE_WORKING_SWAPCONTEXT],[1],[user context manipulation is complete]),
+   AC_MSG_RESULT([no]))])