[coroutine] Bus error on Mac OS X 10.5

I've downloaded the not-yet-Boost coroutine library [1] from the Boost Vault [2]. On a couple of Linux platforms I was able to build and run example/banana.cpp -- though I had to patch noreturn.hpp for gcc 3.3 [3]. On an Intel "fall 2008" MacBook Pro running OS X 10.5.6, with Apple gcc 4.0.1, I had to comment out the MAP_ANONYMOUS mmap() flag [4] -- I don't think that flag is available in Darwin. (Obviously that patch should test for MAP_ANONYMOUS rather than simply suppressing it.) Having done that, the 'banana' example program built -- but I get a bus error trying to run it. I did find an exchange on the Apple mailing list [5] in which Kevin Van Vechten recommends #defining _XOPEN_SOURCE before #include <ucontext.h>:
Why the bus error? What am I doing wrong?
This is a known issue where getcontext(3) is writing past the end of the ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ). As a workaround, define _XOPEN_SOURCE before including ucontext.h.
Unfortunately, adding such a #define [6] does not resolve my bus error. The article [7] in which I found ref [5] proposes a classic-C program [8] to illustrate use of getcontext() and swapcontext(). On my Mac, that program produces a seg fault with or without #define _XOPEN_SOURCE. So my apologies: this may very well not be a Boost issue, or even a pre-Boost issue. I'm very excited to try the coroutine library, but crashing on Macs is a show-stopper for us. Has anyone else succeeded in running it on a Mac? [1] http://www.crystalclearsoftware.com/soc/coroutine/index.html [2] http://www.boostpro.com/vault/index.php?action=downloadfile&filename=boost-c... [3] attached boost-coroutine.gcc33.patch [4] attached boost-coroutine.osx-mmap.patch [5] http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html [6] attached boost-coroutine.osx-context.patch [7] http://hjiang.net/archives/220 [8] attached swapcontext_test.c *** boost/coroutine/detail/noreturn.hpp~ Sun Aug 20 10:11:09 2006 --- boost/coroutine/detail/noreturn.hpp Fri Mar 27 17:00:00 2009 *************** *** 40,48 **** --- 40,54 ---- #if defined(__GNUC__) + #if __GNUC_MAJOR__ > 3 || (__GNUC_MAJOR__ == 3 && __GNUC_MINOR__ > 3) #define BOOST_COROUTINE_NORETURN(function) \ function __attribute__((__noreturn__)) \ /**/ + #else // gcc 3.3 + #define BOOST_COROUTINE_NORETURN(function) \ + function + /**/ + #endif // gcc 3.3 #elif defined (BOOST_MSVC) *** boost/coroutine/detail/posix_utility.hpp~ Sun Aug 20 13:11:09 2006 --- boost/coroutine/detail/posix_utility.hpp Fri Mar 27 18:52:17 2009 *************** *** 129,135 **** void * stack = ::mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, ! MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 ); --- 129,135 ---- void * stack = ::mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, ! MAP_PRIVATE /*|MAP_ANONYMOUS*/, -1, 0 ); *** boost/coroutine/detail/context_posix.hpp~ Sun Aug 20 13:11:09 2006 --- boost/coroutine/detail/context_posix.hpp Fri Mar 27 20:57:44 2009 *************** *** 42,47 **** --- 42,56 ---- * NOTE2: makecontext and friends are declared obsolescent in SuSv3, but * it is unlikely that they will be removed any time soon. */ + // NOTE3 (per http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html): + // > Why the bus error? What am I doing wrong? + // This is a known issue where getcontext(3) is writing past the end of the + // ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ). + // As a workaround, define _XOPEN_SOURCE before including ucontext.h. + // [While we could make that OSX-specific, it seems harmless enough?] + #ifndef _XOPEN_SOURCE + #define _XOPEN_SOURCE + #endif #include <ucontext.h> #include <boost/noncopyable.hpp> #include <boost/coroutine/exception.hpp> // From http://hjiang.net/archives/220 #include <signal.h> #include <stdio.h> // NOTE (per http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html): // > Why the bus error? What am I doing wrong? // This is a known issue where getcontext(3) is writing past the end of the // ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ). // As a workaround, define _XOPEN_SOURCE before including ucontext.h. // [While we could make that OSX-specific, it seems harmless enough?] #ifndef _XOPEN_SOURCE //#define _XOPEN_SOURCE #endif #include <ucontext.h> // Signals which routine should run. volatile int g_turn; void routineOne(ucontext_t* self, ucontext_t* other) { int numbers[] = {1, 2, 3}; int i; for (i = 0; i < sizeof(numbers)/sizeof(int); ++i) { printf("Routine one: %d\n", numbers[i]); // Call other with current continuation if (g_turn != 1) { g_turn = 1; swapcontext(self, other); } } } void routineTwo(ucontext_t* self, ucontext_t* other) { int numbers[] = {-1, -2, -3}; int i; for (i = 0; i < sizeof(numbers)/sizeof(int); ++i) { printf("Routine two: %d\n", numbers[i]); if (g_turn != 2) { g_turn = 2; swapcontext(self, other); } } } int main() { // Continuations ucontext_t cont_one; ucontext_t cont_two; ucontext_t cont_main; // one stack for each thread char stack_one[SIGSTKSZ]; char stack_two[SIGSTKSZ]; // Initialize the coutinuations. cont_one.uc_link = &cont_main; cont_one.uc_stack.ss_sp = stack_one; cont_one.uc_stack.ss_size = sizeof(stack_one); cont_two.uc_link = &cont_main; cont_two.uc_stack.ss_sp = stack_two; cont_two.uc_stack.ss_size = sizeof(stack_two); getcontext(&cont_one); makecontext(&cont_one, (void (*)())routineOne, 2, &cont_one, &cont_two); getcontext(&cont_two); makecontext(&cont_two, (void (*)())routineTwo, 2, &cont_two, &cont_one); g_turn = 0; // Call routineOne with current continuation. Continue from here // after routineOne finishes. getcontext(&cont_main); if (g_turn == 0) { setcontext(&cont_one); } return 0; }

Nat Goodspeed <nat@lindenlab.com> writes:
On an Intel "fall 2008" MacBook Pro running OS X 10.5.6, with Apple gcc 4.0.1, I had to comment out the MAP_ANONYMOUS mmap() flag [4] -- I don't think that flag is available in Darwin. (Obviously that patch should test for MAP_ANONYMOUS rather than simply suppressing it.)
Use MAP_ANON on Apple. It's been a while, but IIRC Apple doesn't support/export the latest POSIX spec. -tom

Nat Goodspeed wrote:
the 'banana' example program built -- but I get a bus error trying to run it.
I did find an exchange on the Apple mailing list [1] in which Kevin Van Vechten recommends #defining _XOPEN_SOURCE before #include <ucontext.h>.
Unfortunately, adding such a #define does not resolve my bus error.
banana.cpp now runs on my Mac! For closure, here's what I found. There were two crash issues. One is indeed fixed by #defining _XOPEN_SOURCE -- /if/ your #define precedes the first #include of sys/_structs.h! This was a little tricky to resolve, since many system headers end up pulling that in. This only matters in boost/coroutine/detail/context_posix.hpp, so I kept the #define there -- but test whether the system file has already been #included. If so, you get an #error to the effect that you must #include coroutine headers before anything that #includes <ucontext.h>. Then I had to move some internal #includes that were forcing that #error even when coroutine.hpp is first. Moving boost/coroutine/detail/context_posix.hpp before most other #includes revealed that it uses BOOST_ASSERT without #including <boost/assert.hpp>. I've added that #include. The other crash issue is that 8192 is way too small a default stack. On this platform, SIGSTKSZ is 131072, or 16x the hard-coded default_stack_size. I changed the definition of ucontext_context_impl::default_stack_size to SIGSTKSZ. I changed boost/coroutine/detail/posix_utility.hpp to reference MAP_ANON rather than MAP_ANONYMOUS in the __APPLE__ case -- thanks Tom! All these changes are in a patch file [2].
[1] http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html [2] attached boost-coroutine.patch
diff -cr orig/boost-coroutine/boost/coroutine/coroutine.hpp ./boost/coroutine/coroutine.hpp *** orig/boost-coroutine/boost/coroutine/coroutine.hpp Sun Aug 20 13:11:16 2006 --- ./boost/coroutine/coroutine.hpp Tue Apr 7 23:38:11 2009 *************** *** 28,33 **** --- 28,35 ---- #ifndef BOOST_COROUTINE_COROUTINE_HPP_20060512 #define BOOST_COROUTINE_COROUTINE_HPP_20060512 + // default_context_impl.hpp must be first for weird Apple bug + #include <boost/coroutine/detail/default_context_impl.hpp> #include <cstddef> #include <boost/preprocessor/repetition.hpp> #include <boost/tuple/tuple.hpp> *************** *** 37,43 **** #include <boost/call_traits.hpp> #include <boost/coroutine/detail/arg_max.hpp> #include <boost/coroutine/detail/coroutine_impl.hpp> - #include <boost/coroutine/detail/default_context_impl.hpp> #include <boost/coroutine/detail/is_callable.hpp> #include <boost/coroutine/detail/argument_packer.hpp> #include <boost/coroutine/detail/argument_unpacker.hpp> --- 39,44 ---- diff -cr orig/boost-coroutine/boost/coroutine/detail/context_posix.hpp ./boost/coroutine/detail/context_posix.hpp *** orig/boost-coroutine/boost/coroutine/detail/context_posix.hpp Sun Aug 20 13:11:09 2006 --- ./boost/coroutine/detail/context_posix.hpp Tue Apr 7 23:40:17 2009 *************** *** 28,39 **** #ifndef BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601 #define BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601 #include <boost/config.hpp> #if defined(_XOPEN_UNIX) && defined(_XOPEN_VERSION) && _XOPEN_VERSION >= 500 /* ! * makecontex based context implementation. Should be available on all * SuSv2 compliant UNIX systems. * NOTE: this implementation is not * optimal as the makecontext API saves and restore the signal mask. --- 28,55 ---- #ifndef BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601 #define BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601 + + // NOTE (per http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html): + // > Why the bus error? What am I doing wrong? + // This is a known issue where getcontext(3) is writing past the end of the + // ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ). + // As a workaround, define _XOPEN_SOURCE before including ucontext.h. + #if defined(__APPLE__) && ! defined(_XOPEN_SOURCE) + #define _XOPEN_SOURCE + // However, the above #define will only affect <ucontext.h> if it has not yet + // been #included by something else! + #if defined(_STRUCT_UCONTEXT) + #error You must #include coroutine headers before anything that #includes <ucontext.h> + #endif + #endif + #include <boost/config.hpp> + #include <boost/assert.hpp> #if defined(_XOPEN_UNIX) && defined(_XOPEN_VERSION) && _XOPEN_VERSION >= 500 /* ! * makecontext based context implementation. Should be available on all * SuSv2 compliant UNIX systems. * NOTE: this implementation is not * optimal as the makecontext API saves and restore the signal mask. *************** *** 43,48 **** --- 59,65 ---- * it is unlikely that they will be removed any time soon. */ #include <ucontext.h> + #include <signal.h> // SIGSTKSZ #include <boost/noncopyable.hpp> #include <boost/coroutine/exception.hpp> #include <boost/coroutine/detail/posix_utility.hpp> *************** *** 83,89 **** public: typedef ucontext_context_impl_base context_impl_base; ! enum {default_stack_size = 8192}; /** --- 100,106 ---- public: typedef ucontext_context_impl_base context_impl_base; ! enum {default_stack_size = SIGSTKSZ}; /** diff -cr orig/boost-coroutine/boost/coroutine/detail/posix_utility.hpp ./boost/coroutine/detail/posix_utility.hpp *** orig/boost-coroutine/boost/coroutine/detail/posix_utility.hpp Sun Aug 20 13:11:09 2006 --- ./boost/coroutine/detail/posix_utility.hpp Wed Apr 1 09:57:03 2009 *************** *** 129,135 **** --- 129,139 ---- void * stack = ::mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, + #if defined(__APPLE__) + MAP_PRIVATE|MAP_ANON, + #else // ! __APPLE__ MAP_PRIVATE|MAP_ANONYMOUS, + #endif // ! __APPLE__ -1, 0 ); diff -cr orig/boost-coroutine/boost/coroutine/future.hpp ./boost/coroutine/future.hpp *** orig/boost-coroutine/boost/coroutine/future.hpp Sun Aug 20 13:11:16 2006 --- ./boost/coroutine/future.hpp Tue Apr 7 23:38:42 2009 *************** *** 33,38 **** --- 33,40 ---- #ifndef BOOST_COROUTINE_WAIT_MAX #define BOOST_COROUTINE_WAIT_MAX 10 #endif + // default_context_impl.hpp must be first for weird Apple bug + #include <boost/coroutine/detail/default_context_impl.hpp> #include <boost/none.hpp> #include <boost/config.hpp> #include <boost/tuple/tuple.hpp> *************** *** 48,54 **** #include <boost/coroutine/detail/call_impl.hpp> #include <boost/coroutine/detail/wait_impl.hpp> #include <boost/coroutine/detail/future_impl.hpp> - #include <boost/coroutine/detail/default_context_impl.hpp> namespace boost { namespace coroutines { --- 50,55 ---- diff -cr orig/boost-coroutine/libs/coroutine/example/banana.cpp ./libs/coroutine/example/banana.cpp *** orig/boost-coroutine/libs/coroutine/example/banana.cpp Sun Aug 20 13:12:02 2006 --- ./libs/coroutine/example/banana.cpp Tue Apr 7 23:40:46 2009 *************** *** 26,35 **** // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <iostream> #include <string> #include <boost/bind.hpp> - #include <boost/coroutine/coroutine.hpp> namespace coroutines = boost::coroutines; using coroutines::coroutine; --- 26,35 ---- // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) + #include <boost/coroutine/coroutine.hpp> #include <iostream> #include <string> #include <boost/bind.hpp> namespace coroutines = boost::coroutines; using coroutines::coroutine;

Nat Goodspeed wrote:
banana.cpp now runs on my Mac! For closure, here's what I found.
I also got it to run on Debian sarge (linux32), Debian etch (linux64), Mac OS X 10.5 and Windows XP Pro. My internal #include reordering turned up another couple of dependencies on BOOST_ASSERT without the corresponding #include; I've added those to the attached cumulative patch file. This cumulative patch file also incorporates the gcc 3.3 workaround mentioned in an earlier mail, but omitted from the previous boost-coroutine.patch. Finally -- the Windows Fiber API isn't visible in <windows.h> unless you tweak _WIN32_WINNT to a magic number. This too is included in the attached patch file. diff -rc orig/boost-coroutine/boost/coroutine/coroutine.hpp ./boost/coroutine/coroutine.hpp *** orig/boost-coroutine/boost/coroutine/coroutine.hpp Sun Aug 20 13:11:16 2006 --- ./boost/coroutine/coroutine.hpp Tue Apr 7 23:38:11 2009 *************** *** 28,33 **** --- 28,35 ---- #ifndef BOOST_COROUTINE_COROUTINE_HPP_20060512 #define BOOST_COROUTINE_COROUTINE_HPP_20060512 + // default_context_impl.hpp must be first for weird Apple bug + #include <boost/coroutine/detail/default_context_impl.hpp> #include <cstddef> #include <boost/preprocessor/repetition.hpp> #include <boost/tuple/tuple.hpp> *************** *** 37,43 **** #include <boost/call_traits.hpp> #include <boost/coroutine/detail/arg_max.hpp> #include <boost/coroutine/detail/coroutine_impl.hpp> - #include <boost/coroutine/detail/default_context_impl.hpp> #include <boost/coroutine/detail/is_callable.hpp> #include <boost/coroutine/detail/argument_packer.hpp> #include <boost/coroutine/detail/argument_unpacker.hpp> --- 39,44 ---- diff -rc orig/boost-coroutine/boost/coroutine/detail/context_linux.hpp ./boost/coroutine/detail/context_linux.hpp *** orig/boost-coroutine/boost/coroutine/detail/context_linux.hpp Sun Aug 20 13:11:09 2006 --- ./boost/coroutine/detail/context_linux.hpp Wed Apr 8 01:10:03 2009 *************** *** 34,39 **** --- 34,40 ---- #include <cstddef> #include <boost/coroutine/detail/posix_utility.hpp> #include <boost/coroutine/detail/swap_context.hpp> + #include <boost/assert.hpp> /* * Defining BOOST_COROUTINE_INLINE_ASM will enable the inlin3 diff -rc orig/boost-coroutine/boost/coroutine/detail/context_posix.hpp ./boost/coroutine/detail/context_posix.hpp *** orig/boost-coroutine/boost/coroutine/detail/context_posix.hpp Sun Aug 20 13:11:09 2006 --- ./boost/coroutine/detail/context_posix.hpp Tue Apr 7 23:40:17 2009 *************** *** 28,39 **** #ifndef BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601 #define BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601 #include <boost/config.hpp> #if defined(_XOPEN_UNIX) && defined(_XOPEN_VERSION) && _XOPEN_VERSION >= 500 /* ! * makecontex based context implementation. Should be available on all * SuSv2 compliant UNIX systems. * NOTE: this implementation is not * optimal as the makecontext API saves and restore the signal mask. --- 28,55 ---- #ifndef BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601 #define BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601 + + // NOTE (per http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html): + // > Why the bus error? What am I doing wrong? + // This is a known issue where getcontext(3) is writing past the end of the + // ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ). + // As a workaround, define _XOPEN_SOURCE before including ucontext.h. + #if defined(__APPLE__) && ! defined(_XOPEN_SOURCE) + #define _XOPEN_SOURCE + // However, the above #define will only affect <ucontext.h> if it has not yet + // been #included by something else! + #if defined(_STRUCT_UCONTEXT) + #error You must #include coroutine headers before anything that #includes <ucontext.h> + #endif + #endif + #include <boost/config.hpp> + #include <boost/assert.hpp> #if defined(_XOPEN_UNIX) && defined(_XOPEN_VERSION) && _XOPEN_VERSION >= 500 /* ! * makecontext based context implementation. Should be available on all * SuSv2 compliant UNIX systems. * NOTE: this implementation is not * optimal as the makecontext API saves and restore the signal mask. *************** *** 43,48 **** --- 59,65 ---- * it is unlikely that they will be removed any time soon. */ #include <ucontext.h> + #include <signal.h> // SIGSTKSZ #include <boost/noncopyable.hpp> #include <boost/coroutine/exception.hpp> #include <boost/coroutine/detail/posix_utility.hpp> *************** *** 83,89 **** public: typedef ucontext_context_impl_base context_impl_base; ! enum {default_stack_size = 8192}; /** --- 100,106 ---- public: typedef ucontext_context_impl_base context_impl_base; ! enum {default_stack_size = SIGSTKSZ}; /** diff -rc orig/boost-coroutine/boost/coroutine/detail/context_windows.hpp ./boost/coroutine/detail/context_windows.hpp *** orig/boost-coroutine/boost/coroutine/detail/context_windows.hpp Sun Aug 20 13:11:09 2006 --- ./boost/coroutine/detail/context_windows.hpp Wed Apr 8 01:06:37 2009 *************** *** 28,37 **** #ifndef BOOST_COROUTINE_CONTEXT_WINDOWS_HPP_20060625 #define BOOST_COROUTINE_CONTEXT_WINDOWS_HPP_20060625 #include <windows.h> #include <winnt.h> #include <boost/config.hpp> ! #include <boost/config.hpp> #include <boost/noncopyable.hpp> #include <boost/coroutine/exception.hpp> #include <boost/coroutine/detail/swap_context.hpp> --- 28,40 ---- #ifndef BOOST_COROUTINE_CONTEXT_WINDOWS_HPP_20060625 #define BOOST_COROUTINE_CONTEXT_WINDOWS_HPP_20060625 + // This kludge is necessary to make CreateFiber, etc., visible + #define WIN32_LEAN_AND_MEAN + #define _WIN32_WINNT 0x0400 #include <windows.h> #include <winnt.h> #include <boost/config.hpp> ! #include <boost/assert.hpp> #include <boost/noncopyable.hpp> #include <boost/coroutine/exception.hpp> #include <boost/coroutine/detail/swap_context.hpp> diff -rc orig/boost-coroutine/boost/coroutine/detail/noreturn.hpp ./boost/coroutine/detail/noreturn.hpp *** orig/boost-coroutine/boost/coroutine/detail/noreturn.hpp Sun Aug 20 13:11:09 2006 --- ./boost/coroutine/detail/noreturn.hpp Wed Apr 8 01:07:46 2009 *************** *** 40,48 **** --- 40,54 ---- #if defined(__GNUC__) + #if __GNUC_MAJOR__ > 3 || (__GNUC_MAJOR__ == 3 && __GNUC_MINOR__ > 3) #define BOOST_COROUTINE_NORETURN(function) \ function __attribute__((__noreturn__)) \ /**/ + #else // gcc 3.3 + #define BOOST_COROUTINE_NORETURN(function) \ + function + /**/ + #endif // gcc 3.3 #elif defined (BOOST_MSVC) diff -rc orig/boost-coroutine/boost/coroutine/detail/posix_utility.hpp ./boost/coroutine/detail/posix_utility.hpp *** orig/boost-coroutine/boost/coroutine/detail/posix_utility.hpp Sun Aug 20 13:11:09 2006 --- ./boost/coroutine/detail/posix_utility.hpp Wed Apr 1 09:57:03 2009 *************** *** 129,135 **** --- 129,139 ---- void * stack = ::mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, + #if defined(__APPLE__) + MAP_PRIVATE|MAP_ANON, + #else // ! __APPLE__ MAP_PRIVATE|MAP_ANONYMOUS, + #endif // ! __APPLE__ -1, 0 ); diff -rc orig/boost-coroutine/boost/coroutine/future.hpp ./boost/coroutine/future.hpp *** orig/boost-coroutine/boost/coroutine/future.hpp Sun Aug 20 13:11:16 2006 --- ./boost/coroutine/future.hpp Tue Apr 7 23:38:42 2009 *************** *** 33,38 **** --- 33,40 ---- #ifndef BOOST_COROUTINE_WAIT_MAX #define BOOST_COROUTINE_WAIT_MAX 10 #endif + // default_context_impl.hpp must be first for weird Apple bug + #include <boost/coroutine/detail/default_context_impl.hpp> #include <boost/none.hpp> #include <boost/config.hpp> #include <boost/tuple/tuple.hpp> *************** *** 48,54 **** #include <boost/coroutine/detail/call_impl.hpp> #include <boost/coroutine/detail/wait_impl.hpp> #include <boost/coroutine/detail/future_impl.hpp> - #include <boost/coroutine/detail/default_context_impl.hpp> namespace boost { namespace coroutines { --- 50,55 ---- diff -rc orig/boost-coroutine/libs/coroutine/example/banana.cpp ./libs/coroutine/example/banana.cpp *** orig/boost-coroutine/libs/coroutine/example/banana.cpp Sun Aug 20 13:12:02 2006 --- ./libs/coroutine/example/banana.cpp Tue Apr 7 23:40:46 2009 *************** *** 26,35 **** // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <iostream> #include <string> #include <boost/bind.hpp> - #include <boost/coroutine/coroutine.hpp> namespace coroutines = boost::coroutines; using coroutines::coroutine; --- 26,35 ---- // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) + #include <boost/coroutine/coroutine.hpp> #include <iostream> #include <string> #include <boost/bind.hpp> namespace coroutines = boost::coroutines; using coroutines::coroutine;

Nat Goodspeed wrote:
banana.cpp now runs on my Mac!
Mine -- but not all target Macs, sigh! We have to support OS X 10.4 as well. To my distress, 10.4 does not have swapcontext() et al. The #else clause in boost/coroutine/detail/context_posix.hpp contains the following comment (along with an #error): /** * This is just a temporary placeholder. Context swapping can * be implemented on all most posix systems lacking *context using the * sigaltstack+longjmp trick. * Eventually it will be implemented, but for now just throw an error. * Most posix systems are at least SuSv2 compliant anyway. */ After a couple hours of searching, I have not yet turned up either an article or an example of the "sigaltstack + longjmp trick." Can anyone steer me to a reference implementation? I can't just hack something together on my own: my boss wants me to forget about coroutines in C++, and that would be a shame indeed. If I could adapt an implementation that already works, though, I might still pull this off. Many thanks!

On Wed, Apr 08, 2009 at 11:47:38PM -0400, Nat Goodspeed wrote:
After a couple hours of searching, I have not yet turned up either an article or an example of the "sigaltstack + longjmp trick." Can anyone steer me to a reference implementation? I can't just hack something
Yes, look up GNU Pth: http://www.gnu.org/software/pth/ There you will find also a link to the "Portable Multithreading" paper which describes the trick. You probably do not need to do very much, since GNU Pth already *does* provide *context() equivalents, though with a slightly different interface.

Zeljko Vrba wrote:
On Wed, Apr 08, 2009 at 11:47:38PM -0400, Nat Goodspeed wrote:
I have not yet turned up either an article or an example of the "sigaltstack + longjmp trick." Can anyone steer me to a reference implementation?
Yes, look up GNU Pth: http://www.gnu.org/software/pth/
You probably do not need to do very much, since GNU Pth already *does* provide *context() equivalents, though with a slightly different interface.
Many thanks! I've hacked in a Pth-based implementation, using those *context() workalikes, which appears to work on Mac OS X 10.4. You're probably about to ask me to post the hack, since it may be generally useful. ;-) I will, as soon as the dust settles a bit; I'm pulling all this together against an internal deadline.
participants (3)
-
Nat Goodspeed
-
tom fogal
-
Zeljko Vrba