Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78114 - in trunk: boost/context libs/context/example libs/context/performance libs/context/src libs/context/src/asm libs/context/test
From: oliver.kowalke_at_[hidden]
Date: 2012-04-21 15:05:08


Author: olli
Date: 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
New Revision: 78114
URL: http://svn.boost.org/trac/boost/changeset/78114

Log:
context: remove start_fcontext; context linking removed

Text files modified:
   trunk/boost/context/fcontext.hpp | 7 +-
   trunk/libs/context/example/jump.cpp | 2
   trunk/libs/context/example/link.cpp | 3
   trunk/libs/context/example/transfer.cpp | 3
   trunk/libs/context/performance/Jamfile.v2 | 1
   trunk/libs/context/performance/performance.cpp | 31 +++++++++-
   trunk/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S | 40 ++-----------
   trunk/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm | 26 +++-----
   trunk/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S | 15 +---
   trunk/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S | 15 +---
   trunk/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S | 16 +---
   trunk/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S | 109 -------------------------------------
   trunk/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S | 116 ---------------------------------------
   trunk/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm | 51 +++++-----------
   trunk/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S | 29 +++------
   trunk/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S | 33 ++++------
   trunk/libs/context/src/fcontext.cpp | 8 --
   trunk/libs/context/test/test_context.cpp | 62 +++++++-------------
   18 files changed, 132 insertions(+), 435 deletions(-)

Modified: trunk/boost/context/fcontext.hpp
==============================================================================
--- trunk/boost/context/fcontext.hpp (original)
+++ trunk/boost/context/fcontext.hpp 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -67,9 +67,10 @@
 
 }
 
-extern "C" BOOST_CONTEXT_DECL intptr_t BOOST_CONTEXT_CALLDECL start_fcontext( fcontext_t * ofc, fcontext_t const* nfc);
-extern "C" BOOST_CONTEXT_DECL intptr_t BOOST_CONTEXT_CALLDECL jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp);
-extern "C" BOOST_CONTEXT_DECL void BOOST_CONTEXT_CALLDECL make_fcontext( fcontext_t * fc, void (* fn)( intptr_t), intptr_t vp);
+extern "C" BOOST_CONTEXT_DECL
+intptr_t BOOST_CONTEXT_CALLDECL jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp, bool preserve_fpu = true);
+extern "C" BOOST_CONTEXT_DECL
+void BOOST_CONTEXT_CALLDECL make_fcontext( fcontext_t * fc, void (* fn)( intptr_t), intptr_t vp);
 
 }}
 

Modified: trunk/libs/context/example/jump.cpp
==============================================================================
--- trunk/libs/context/example/jump.cpp (original)
+++ trunk/libs/context/example/jump.cpp 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -48,7 +48,7 @@
                 ctx::make_fcontext( & fc2, f2, 0);
 
                 std::cout << "main: call start_fcontext( & fcm, & fc1)" << std::endl;
- ctx::start_fcontext( & fcm, & fc1);
+ ctx::jump_fcontext( & fcm, & fc1, 0);
 
                 std::cout << "main: done" << std::endl;
 

Modified: trunk/libs/context/example/link.cpp
==============================================================================
--- trunk/libs/context/example/link.cpp (original)
+++ trunk/libs/context/example/link.cpp 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -40,7 +40,6 @@
         fc1.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
         fc1.fc_stack.limit =
             static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
- fc1.fc_link = & fcm;
                 ctx::make_fcontext( & fc1, f1, 0);
 
         fc2.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
@@ -49,7 +48,7 @@
                 ctx::make_fcontext( & fc2, f2, 0);
 
                 std::cout << "main: call start_fcontext( & fcm, & fc1)" << std::endl;
- ctx::start_fcontext( & fcm, & fc1);
+ ctx::jump_fcontext( & fcm, & fc1, 0);
 
                 std::cout << "main: done" << std::endl;
 

Modified: trunk/libs/context/example/transfer.cpp
==============================================================================
--- trunk/libs/context/example/transfer.cpp (original)
+++ trunk/libs/context/example/transfer.cpp 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -35,11 +35,10 @@
     fc1.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
     fc1.fc_stack.limit =
         static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
- fc1.fc_link = & fcm;
     pair_t p( std::make_pair( 2, 7) );
     ctx::make_fcontext( & fc1, f1, ( intptr_t) & p);
     
- int res = ( int) ctx::start_fcontext( & fcm, & fc1);
+ int res = ( int) ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) & p);
     std::cout << p.first << " + " << p.second << " == " << res << std::endl;
     
     p = std::make_pair( 5, 6);

Modified: trunk/libs/context/performance/Jamfile.v2
==============================================================================
--- trunk/libs/context/performance/Jamfile.v2 (original)
+++ trunk/libs/context/performance/Jamfile.v2 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -15,6 +15,7 @@
 
 project boost/context/performance
     : requirements
+ <library>/boost/program_options//boost_program_options
       <library>/boost/thread//boost_thread
       <library>/boost/system//boost_system
       <library>/boost/context//boost_context

Modified: trunk/libs/context/performance/performance.cpp
==============================================================================
--- trunk/libs/context/performance/performance.cpp (original)
+++ trunk/libs/context/performance/performance.cpp 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -16,6 +16,7 @@
 #include <boost/config.hpp>
 #include <boost/context/all.hpp>
 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/program_options.hpp>
 
 #ifndef BOOST_WINDOWS
 #include <ucontext.h>
@@ -25,12 +26,15 @@
 #include "cycle.hpp"
 
 namespace ctx = boost::ctx;
+namespace po = boost::program_options;
+
+bool preserve_fpu = true;
 
 #define CALL_UCONTEXT(z,n,unused) \
     ::swapcontext( & ucm, & uc);
 
 #define CALL_FCONTEXT(z,n,unused) \
- ctx::jump_fcontext( & fcm, & fc, 0);
+ ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
 
 #ifndef BOOST_WINDOWS
 ucontext_t uc, ucm;
@@ -48,7 +52,7 @@
 static void f1( intptr_t)
 {
     while ( true)
- ctx::jump_fcontext( & fc, & fcm, 0);
+ ctx::jump_fcontext( & fc, & fcm, 7, preserve_fpu);
 }
 
 #ifndef BOOST_WINDOWS
@@ -85,9 +89,9 @@
     fc.fc_stack.base = alloc.allocate(ctx::default_stacksize());
     fc.fc_stack.limit =
         static_cast< char * >( fc.fc_stack.base) - ctx::default_stacksize();
- ctx::make_fcontext( & fc, f1, 0);
+ ctx::make_fcontext( & fc, f1, 7);
 
- ctx::start_fcontext( & fcm, & fc);
+ ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
 
     // cache warum-up
 BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
@@ -108,6 +112,25 @@
 {
     try
     {
+ po::options_description desc("allowed options");
+ desc.add_options()
+ ("help,h", "help message")
+ ("preserve-fpu,p", po::value< bool >( & preserve_fpu), "preserve floating point env");
+
+ po::variables_map vm;
+ po::store(
+ po::parse_command_line(
+ argc,
+ argv,
+ desc),
+ vm);
+ po::notify( vm);
+
+ if ( vm.count("help") )
+ {
+ std::cout << desc << std::endl;
+ return EXIT_SUCCESS;
+ }
         bind_to_processor( 0);
 
         cycle_t ov( overhead() );

Modified: trunk/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -53,27 +53,6 @@
  * *****************************************************************/
 
 .text
-.globl start_fcontext
-.align 2
-.type start_fcontext,%function
-start_fcontext:
- stmia a1, {v1-v8,sp-lr} @ save V1-V8,SP-LR
- str lr, [a1,#40] @ save LR as PC
-#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
- ldr a4, [a1,#56]
- stmia a4, {s16-s31} @ save S16-S31
-#endif
-
- ldr a1, [a2,#8] @ restore A1 as first arg
-#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
- ldr a4, [a2,#56]
- ldmia a4, {s16-s31} @ restore S16-S31
-#endif
-
- ldmia a2, {v1-v8,sp-pc} @ restore v1-V8,SP-PC
-.size start_fcontext,.-start_fcontext
-
-.text
 .globl jump_fcontext
 .align 2
 .type jump_fcontext,%function
@@ -85,7 +64,8 @@
     stmia a4, {s16-s31} @ save S16-S31
 #endif
 
- mov a1, a3 @ use thrid arg as return value after jump
+ mov a1, a3 @ use third arg as return value after jump
+ @ and as first arg in context function
 #if (defined(__VFP_FP__) && !defined(__SOFTFP__))
     ldr a4, [a2,#56]
     ldmia a4, {s16-s31} @ restore S16-S31
@@ -113,18 +93,14 @@
     str a2, [a1,#32] @ save the stack base
     ldr a2, [a1,#52] @ load the address of the next context
     str a2, [a1,#4] @ save the address of the next context
- adr a2, link_fcontext @ load address of link_fcontext
- str a2, [a1,#36] @ save address of link_fcontext
- mov a1, #0
- bx lr
 
-link_fcontext:
- mov a1, v1 @ load the adddress of the current context
- mov a2, v2 @ load the adddress of the next context
- teq a2, #0 @ test if the address of the next context is a null pointer
+ adr a2, finish @ helper code executed after context function returns
+ str a2, [a1,#36]
 
- bne start_fcontext_at_PLT @ install next context
+ mov a1, #0
+ bx lr
 
+finish:
     mov a1, #0
- bl _exit_at_PLT @ exit application
+ bl _exit_at_PLT @ exit application
 .size make_fcontext,.-make_fcontext

Modified: trunk/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm
==============================================================================
--- trunk/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm (original)
+++ trunk/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -84,7 +84,6 @@
 ; stmxcsr [ecx+02ch] ; save MMX control word
 ; fnstcw [ecx+030h] ; save x87 control word
 
-
     mov ecx, [esp+08h] ; load address of the second fcontext_t arg
     mov edi, [ecx] ; restore EDI
     mov esi, [ecx+04h] ; restore ESI
@@ -103,11 +102,11 @@
     mov eax, [ecx+028h] ; load fiber local storage
     mov [edx+010h], eax ; restore fiber local storage
 
-
 ; ldmxcsr [ecx+02ch] ; restore MMX control word
 ; fldcw [ecx+030h] ; restore x87 control word
 
     mov eax, [esp+0ch] ; use third arg as return value after jump
+ mov [esp+04h], eax ; use third arg as first arg in context function
 
     mov esp, [ecx+010h] ; restore ESP
     mov ecx, [ecx+014h] ; fetch the address to return to
@@ -143,27 +142,20 @@
     mov [eax+04h], ecx ; save the address of the next context
     mov ecx, [esp+0ch] ; load the address of the void pointer arg2
     mov [edx+04h], ecx ; save the address of the void pointer onto the context stack
- stmxcsr [eax+02ch] ; save MMX control word
- fnstcw [eax+030h] ; save x87 control word
- mov ecx, link_fcontext ; load helper code executed after fn() returns
- mov [edx], ecx ; save helper code executed adter fn() returns
+
+; stmxcsr [eax+02ch] ; save MMX control word
+; fnstcw [eax+030h] ; save x87 control word
+
+ mov ecx, finish ; helper code executed after context function returns
+ mov [edx], ecx
+
     xor eax, eax ; set EAX to zero
     ret
-make_fcontext ENDP
-
-link_fcontext PROC
- lea esp, [esp-0ch] ; adjust the stack to proper boundaries
- test esi, esi ; test if a next context was given
- je finish ; jump to finish
-
- push esi ; push the address of the next context on the stack
- push edi ; push the address of the current context on the stack
- call start_fcontext ; install next context
 
 finish:
     xor eax, eax ; set EAX to zero
     push eax ; exit code is zero
     call _exit ; exit application
     hlt
-link_fcontext ENDP
+make_fcontext ENDP
 END

Modified: trunk/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -68,6 +68,7 @@
 /* fldcw 0x28(%ecx) */ /* restore x87 control word */
 
     movl 0xc(%esp), %eax /* use third arg as return value after jump */
+ movl %eax, 0x4(%esp) /* use third arg as first arg in context function */
 
     movl 0x10(%ecx), %esp /* restore ESP */
     movl 0x14(%ecx), %ecx /* fetch the address to return to */
@@ -110,27 +111,19 @@
 
     call 2f
 2: popl %ecx /* address of label 1 */
- addl $link_fcontext-2b, %ecx /* compute address of label link_fcontext */
- movl %ecx, (%edx) /* store address of link_fcontext as return address on stack */
+ addl $finish-2b, %ecx /* compute address of label finish */
+ movl %ecx, (%edx) /* store address of finish as return address on stack */
 
     xorl %eax, %eax /* set EAX to zero */
     ret
 
-link_fcontext:
+finish:
     leal -0xc(%esp), %esp
 
     call 3f
 3: popl %ebx /* address of label 3 */
     addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx /* compute address of GOT and store it in EBX */
 
- testl %esi, %esi /* test if a next context was given */
- je 4f /* jump to finish */
-
- pushl %esi /* push the address of the next context on the stack */
- pushl %edi /* push the address of the current context to stack */
- call start_fcontext_at_PLT /* jump to next context */
-
-4:
     movl %eax, %eax
     pushl %eax /* exit code is zero */
     call _exit_at_PLT /* exit application */

Modified: trunk/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -67,6 +67,7 @@
 /* fldcw 0x28(%ecx) */ /* restore x87 control word */
 
     movl 0xc(%esp), %eax /* use third arg as return value after jump */
+ movl %eax, 0x4(%esp) /* use third arg as first arg in context function */
 
     movl 0x10(%ecx), %esp /* restore ESP */
     movl 0x14(%ecx), %ecx /* fetch the address to return to */
@@ -107,27 +108,19 @@
 
     call 2f
 2: popl %ecx /* address of label 1 */
- addl $link_fcontext-2b, %ecx /* compute address of label link_fcontext */
- movl %ecx, (%edx) /* store address of link_fcontext as return address on stack */
+ addl $finish-2b, %ecx /* compute address of label finish */
+ movl %ecx, (%edx) /* store address of finish as return address on stack */
 
     xorl %eax, %eax /* set EAX to zero */
     ret
 
-link_fcontext:
+finish:
     leal -0xc(%esp), %esp
 
     call 3f
 3: popl %ebx /* address of label 3 */
     addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx /* compute address of GOT and store it in EBX */
 
- testl %esi, %esi /* test if a next context was given */
- je 4f /* jump to finish */
-
- pushl %esi /* push the address of the next context on the stack */
- pushl %edi /* push the address of the current context to stack */
- call start_fcontext_at_PLT /* jump to next context */
-
-4:
     movl %eax, %eax
     pushl %eax /* exit code is zero */
     call _exit_at_PLT /* exit application */

Modified: trunk/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -99,6 +99,7 @@
 #endif
 
     move $v0, $a2 # use third arg as return value after jump
+ move $a0, $a2 # use third arg as first arg in context function
 
     lw $t9, 96($a1) # load PC
     jr $t9 # jump to context
@@ -138,22 +139,15 @@
     sw $t0, 72($a0) # save the stack base
     lw $t0, 120($a0) # load address of next user context
     sw $t0, 8($a0) # save the next context
- la $t9, link_fcontext # get address of link_fcontext
- sw $t9, 88($a0) # save address of link_fcontext
+
+ la $t9, finish # get address of finish
+ sw $t9, 88($a0) # save address of finish
 
     move $v0, $zero
     jr $ra
 
-link_fcontext:
+finish:
     move $gp, $s3 # restore GP (global pointer)
- move $a1, $s1 # set A1 to address of next context
- beqz $a1, 2f # test if a next context was given
-
- move $a0, $s0 # set A0 to address of current context
- lw $t9, %call16(start_fcontext)($gp) # install next context
- jr $t9
-
-2:
     move $a0, $zero
     lw $t9, %call16(_exit)($gp) # exit application
     jalr $t9

Modified: trunk/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -74,114 +74,6 @@
  * *****************************************************************/
 
 .text
-.globl start_fcontext
-.align 2
-.type start_fcontext,@function
-start_fcontext:
- stw %r13, 0(%r3) # save R13
- stw %r14, 4(%r3) # save R14
- stw %r15, 8(%r3) # save R15
- stw %r16, 12(%r3) # save R16
- stw %r17, 16(%r3) # save R17
- stw %r18, 20(%r3) # save R18
- stw %r19, 24(%r3) # save R19
- stw %r20, 28(%r3) # save R20
- stw %r21, 32(%r3) # save R21
- stw %r22, 36(%r3) # save R22
- stw %r23, 40(%r3) # save R23
- stw %r24, 44(%r3) # save R24
- stw %r25, 48(%r3) # save R25
- stw %r26, 52(%r3) # save R26
- stw %r27, 56(%r3) # save R27
- stw %r28, 60(%r3) # save R28
- stw %r29, 64(%r3) # save R29
- stw %r30, 68(%r3) # save R30
- stw %r31, 72(%r3) # save R31
- stw %r1, 76(%r3) # save SP
-
- mfcr %r0 # load CR
- stw %r0, 80(%r3) # save CR
- mflr %r0 # load LR
- stw %r0, 84(%r3) # save LR
- stw %r0, 88(%r3) # save LR as PC
-
- stfd %f14, 104(%r3) # save F14
- stfd %f15, 112(%r3) # save F15
- stfd %f16, 120(%r3) # save F16
- stfd %f17, 128(%r3) # save F17
- stfd %f18, 136(%r3) # save F18
- stfd %f19, 144(%r3) # save F19
- stfd %f20, 152(%r3) # save F20
- stfd %f21, 160(%r3) # save F21
- stfd %f22, 168(%r3) # save F22
- stfd %f23, 176(%r3) # save F23
- stfd %f24, 184(%r3) # save F24
- stfd %f25, 192(%r3) # save F25
- stfd %f26, 200(%r3) # save F26
- stfd %f27, 208(%r3) # save F27
- stfd %f28, 216(%r3) # save F28
- stfd %f29, 224(%r3) # save F29
- stfd %f30, 232(%r3) # save F30
- stfd %f31, 240(%r3) # save F31
- mffs %f0 # load FPSCR
- stfd %f0, 248(%r3) # save FPSCR
-
-
- lwz %r13, 0(%r4) # restore R13
- lwz %r14, 4(%r4) # restore R14
- lwz %r15, 8(%r4) # restore R15
- lwz %r16, 12(%r4) # restore R16
- lwz %r17, 16(%r4) # restore R17
- lwz %r18, 20(%r4) # restore R18
- lwz %r19, 24(%r4) # restore R19
- lwz %r20, 28(%r4) # restore R20
- lwz %r21, 32(%r4) # restore R21
- lwz %r22, 36(%r4) # restore R22
- lwz %r23, 40(%r4) # restore R23
- lwz %r24, 44(%r4) # restore R24
- lwz %r25, 48(%r4) # restore R25
- lwz %r26, 52(%r4) # restore R26
- lwz %r27, 56(%r4) # restore R27
- lwz %r28, 60(%r4) # restore R28
- lwz %r29, 64(%r4) # restore R29
- lwz %r30, 68(%r4) # restore R30
- lwz %r31, 72(%r4) # restore R31
- lwz %r1, 76(%r4) # restore SP
-
- lwz %r0, 80(%r4) # load CR
- mtcr %r0 # restore CR
- lwz %r0, 84(%r4) # load LR
- mtlr %r0 # restore LR
-
- lfd %f14, 104(%r4) # restore F14
- lfd %f15, 112(%r4) # restore F15
- lfd %f16, 120(%r4) # restore F16
- lfd %f17, 128(%r4) # restore F17
- lfd %f18, 136(%r4) # restore F18
- lfd %f19, 144(%r4) # restore F19
- lfd %f20, 152(%r4) # restore F20
- lfd %f21, 160(%r4) # restore F21
- lfd %f22, 168(%r4) # restore F22
- lfd %f23, 176(%r4) # restore F23
- lfd %f24, 184(%r4) # restore F24
- lfd %f25, 192(%r4) # restore F25
- lfd %f26, 200(%r4) # restore F26
- lfd %f27, 208(%r4) # restore F27
- lfd %f28, 216(%r4) # restore F28
- lfd %f29, 224(%r4) # restore F29
- lfd %f30, 232(%r4) # restore F30
- lfd %f31, 240(%r4) # restore F31
- lfd %f0, 248(%r4) # load FPSCR
- mtfsf 0xff, %f0 # restore FPSCR
-
- lwz %r0, 88(%r4) # load PC
- mr. %r3, %r15 # load void pointer as argument
- mtctr %r0 # restore CTR
-
- bctr # start to context
-.size start_fcontext, .-start_fcontext
-
-.text
 .globl jump_fcontext
 .align 2
 .type jump_fcontext,@function
@@ -283,6 +175,7 @@
     mtfsf 0xff, %f0 # restore FPSCR
 
     mr. %r3, %r5 # use third arg as return value after jump
+ # and as first arg in context function
 
     lwz %r0, 88(%r4) # load PC
     mtctr %r0 # restore CTR

Modified: trunk/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -89,121 +89,6 @@
 
 .section ".text"
 .align 2
-.globl start_fcontext
-.section ".opd","aw"
-.align 3
-start_fcontext:
-.quad .start_fcontext,.TOC._at_tocbase,0
-.previous
-.size start_fcontext,24
-.type .start_fcontext,@function
-.globl .start_fcontext
-.start_fcontext:
- std %r13, 0(%r3) # save R13
- std %r14, 8(%r3) # save R14
- std %r15, 16(%r3) # save R15
- std %r16, 24(%r3) # save R16
- std %r17, 32(%r3) # save R17
- std %r18, 40(%r3) # save R18
- std %r19, 48(%r3) # save R19
- std %r20, 56(%r3) # save R20
- std %r21, 64(%r3) # save R21
- std %r22, 72(%r3) # save R22
- std %r23, 80(%r3) # save R23
- std %r24, 88(%r3) # save R24
- std %r25, 96(%r3) # save R25
- std %r26, 104(%r3) # save R26
- std %r27, 112(%r3) # save R27
- std %r28, 120(%r3) # save R28
- std %r29, 128(%r3) # save R29
- std %r30, 136(%r3) # save R30
- std %r31, 144(%r3) # save R31
- std %r1, 152(%r3) # save SP
-
- mfcr %r0 # load CR
- std %r0, 160(%r3) # save CR
- mflr %r0 # load LR
- std %r0, 168(%r3) # save LR
- std %r0, 176(%r3) # save LR as PC
-
- stfd %f14, 208(%r3) # save F14
- stfd %f15, 216(%r3) # save F15
- stfd %f16, 224(%r3) # save F16
- stfd %f17, 232(%r3) # save F17
- stfd %f18, 240(%r3) # save F18
- stfd %f19, 248(%r3) # save F19
- stfd %f20, 256(%r3) # save F20
- stfd %f21, 264(%r3) # save F21
- stfd %f22, 272(%r3) # save F22
- stfd %f23, 280(%r3) # save F23
- stfd %f24, 288(%r3) # save F24
- stfd %f25, 296(%r3) # save F25
- stfd %f26, 304(%r3) # save F26
- stfd %f27, 312(%r3) # save F27
- stfd %f28, 320(%r3) # save F28
- stfd %f29, 328(%r3) # save F29
- stfd %f30, 336(%r3) # save F30
- stfd %f31, 344(%r3) # save F31
- mffs %f0 # load FPSCR
- stfd %f0, 352(%r3) # save FPSCR
-
-
- ld %r13, 0(%r4) # restore R13
- ld %r14, 8(%r4) # restore R14
- ld %r15, 16(%r4) # restore R15
- ld %r16, 24(%r4) # restore R16
- ld %r17, 32(%r4) # restore R17
- ld %r18, 40(%r4) # restore R18
- ld %r19, 48(%r4) # restore R19
- ld %r20, 56(%r4) # restore R20
- ld %r21, 64(%r4) # restore R21
- ld %r22, 72(%r4) # restore R22
- ld %r23, 80(%r4) # restore R23
- ld %r24, 88(%r4) # restore R24
- ld %r25, 96(%r4) # restore R25
- ld %r26, 104(%r4) # restore R26
- ld %r27, 112(%r4) # restore R27
- ld %r28, 120(%r4) # restore R28
- ld %r29, 128(%r4) # restore R29
- ld %r30, 136(%r4) # restore r30
- ld %r31, 144(%r4) # restore r31
- ld %r1, 152(%r4) # restore SP
-
- ld %r0, 160(%r4) # load CR
- mtcr %r0 # restore CR
- ld %r0, 168(%r4) # load LR
- mtlr %r0 # restore LR
-
- lfd %f14, 208(%r4) # restore F14
- lfd %f15, 216(%r4) # restore F15
- lfd %f16, 224(%r4) # restore F16
- lfd %f17, 232(%r4) # restore F17
- lfd %f18, 240(%r4) # restore F18
- lfd %f19, 248(%r4) # restore F19
- lfd %f20, 256(%r4) # restore F20
- lfd %f21, 264(%r4) # restore F21
- lfd %f22, 272(%r4) # restore F22
- lfd %f23, 280(%r4) # restore F23
- lfd %f24, 288(%r4) # restore F24
- lfd %f25, 296(%r4) # restore F25
- lfd %f26, 304(%r4) # restore F26
- lfd %f27, 312(%r4) # restore F27
- lfd %f28, 320(%r4) # restore F28
- lfd %f29, 328(%r4) # restore F29
- lfd %f30, 336(%r4) # restore F30
- lfd %f31, 344(%r4) # restore F31
- lfd %f0, 352(%r4) # load FPSCR
- mtfsf 0xff, %f0 # restore FPSCR
-
- ld %r0, 176(%r4) # load PC
- mr. %r3, %r15 # load void pointer as argument
- mtctr %r0 # restore CTR
-
- bctr # start to context
-.size .start_fcontext, .-.start_fcontext
-
-.section ".text"
-.align 2
 .globl jump_fcontext
 .section ".opd","aw"
 .align 3
@@ -311,6 +196,7 @@
     mtfsf 0xff, %f0 # restore FPSCR
 
     mr. %r3, %r5 # use third arg as return value after jump
+ # and as first arg in context function
 
     ld %r0, 176(%r4) # load PC
     mtctr %r0 # restore CTR

Modified: trunk/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm
==============================================================================
--- trunk/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm (original)
+++ trunk/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -107,17 +107,16 @@
     mov [rcx+030h], rbx ; save RBX
     mov [rcx+038h], rbp ; save RBP
 
- mov r9, gs:[030h] ; load NT_TIB
- mov rax, [r9+08h] ; load current stack base
+ mov r10, gs:[030h] ; load NT_TIB
+ mov rax, [r10+08h] ; load current stack base
     mov [rcx+050h], rax ; save current stack base
- mov rax, [r9+010h] ; load current stack limit
+ mov rax, [r10+010h] ; load current stack limit
     mov [rcx+058h], rax ; save current stack limit
- mov rax, [r9+018h] ; load fiber local storage
+ mov rax, [r10+018h] ; load fiber local storage
     mov [rcx+068h], rax ; save fiber local storage
 
-; stmxcsr [rcx+070h] ; save MMX control and status word
-; fnstcw [rcx+074h] ; save x87 control word
-
+ stmxcsr [rcx+070h] ; save MMX control and status word
+ fnstcw [rcx+074h] ; save x87 control word
     movaps [rcx+080h], xmm6
     movaps [rcx+090h], xmm7
     movaps [rcx+0100h], xmm8
@@ -134,7 +133,6 @@
     mov rax, [rsp] ; load return address
     mov [rcx+048h], rax ; save return address
 
-
     mov r12, [rdx] ; restore R12
     mov r13, [rdx+08h] ; restore R13
     mov r14, [rdx+010h] ; restore R14
@@ -144,17 +142,16 @@
     mov rbx, [rdx+030h] ; restore RBX
     mov rbp, [rdx+038h] ; restore RBP
 
- mov r9, gs:[030h] ; load NT_TIB
+ mov r10, gs:[030h] ; load NT_TIB
     mov rax, [rdx+050h] ; load stack base
- mov [r9+08h], rax ; restore stack base
+ mov [r10+08h], rax ; restore stack base
     mov rax, [rdx+058h] ; load stack limit
- mov [r9+010h], rax ; restore stack limit
+ mov [r10+010h], rax ; restore stack limit
     mov rax, [rdx+068h] ; load fiber local storage
- mov [r9+018h], rax ; restore fiber local storage
-
-; ldmxcsr [rdx+070h] ; restore MMX control and status word
-; fldcw [rdx+074h] ; restore x87 control word
+ mov [r10+018h], rax ; restore fiber local storage
 
+ ldmxcsr [rdx+070h] ; restore MMX control and status word
+ fldcw [rdx+074h] ; restore x87 control word
     movaps xmm6, [rdx+080h]
     movaps xmm7, [rdx+090h]
     movaps xmm8, [rdx+0100h]
@@ -167,12 +164,12 @@
     movaps xmm15, [rdx+0170h]
 
     mov rsp, [rdx+040h] ; restore RSP
- mov r9, [rdx+048h] ; fetch the address to returned to
- mov rcx, r14 ; restore RCX as first argument for called context
+ mov r10, [rdx+048h] ; fetch the address to returned to
 
     mov rax, r8 ; use third arg as return value after jump
+ mov rcx, r8 ; use third arg as first arg in context function
 
- jmp r9 ; indirect jump to caller
+ jmp r10 ; indirect jump to caller
 jump_fcontext ENDP
 
 make_fcontext PROC EXPORT FRAME ; generate function table entry in .pdata and unwind information in E
@@ -200,30 +197,16 @@
     stmxcsr [rcx+070h] ; save MMX control and status word
     fnstcw [rcx+074h] ; save x87 control word
 
- lea rax, link_fcontext ; helper code executed after fn() returns
+ lea rax, finish ; helper code executed after fn() returns
     mov [rdx], rax ; store address off the helper function as return address
 
     xor rax, rax ; set RAX to zero
     ret
-make_fcontext ENDP
-
-link_fcontext PROC FRAME ; generate function table entry in .pdata and unwind information in
- .endprolog ; .xdata for a function's structured exception handling unwind behavior
-
- sub rsp, 028h ; reserve shadow space for boost_fcontext_algin
- test r13, r13 ; test if a next context was given
- je finish ; jump to finish
-
- mov rcx, r12 ; first argument eq. address of current context
- mov rdx, r13 ; second argumnet eq. address of next context
- mov [rsp+010h], rdx
- mov [rsp+08h], rcx
- call start_fcontext ; install next context
 
 finish:
     xor rcx, rcx
     mov [rsp+08h], rcx
     call _exit ; exit application
     hlt
-link_fcontext ENDP
+make_fcontext ENDP
 END

Modified: trunk/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -60,11 +60,10 @@
     stmxcsr 0x58(%rdi) /* save MMX control and status word */
     fnstcw 0x5c(%rdi) /* save x87 control word */
 
- leaq 0x8(%rsp), %rcx /* exclude the return address and save as stack pointer */
- movq %rcx, 0x30(%rdi) /* save as stack pointer */
- movq (%rsp), %rcx /* save return address */
- movq %rcx, 0x38(%rdi) /* save return address as RIP */
-
+ leaq 0x8(%rsp), %rax /* exclude the return address and save as stack pointer */
+ movq %rax, 0x30(%rdi) /* save as stack pointer */
+ movq (%rsp), %rax /* save return address */
+ movq %rax, 0x38(%rdi) /* save return address as RIP */
 
     movq (%rsi), %rbx /* restore RBX */
     movq 0x8(%rsi), %r12 /* restore R12 */
@@ -76,11 +75,11 @@
     ldmxcsr 0x58(%rsi) /* restore MMX control and status word */
     fldcw 0x5c(%rsi) /* restore x87 control word */
 
- movq %rdx, %rax /* use third arg as return value after jump */
-
     movq 0x30(%rsi), %rsp /* restore RSP */
     movq 0x38(%rsi), %rcx /* fetch the address to return to */
- movq %r13, %rdi /* restore void pointer as argument */
+
+ movq %rdx, %rax /* use third arg as return value after jump */
+ movq %rdx, %rdi /* use third arg as first arg in context function */
 
     jmp *%rcx /* indirect jump to context */
 .size jump_fcontext,.-jump_fcontext
@@ -107,20 +106,14 @@
     movq %rcx, 0x8(%rdi) /* save the address of next context */
     stmxcsr 0x58(%rdi) /* save MMX control and status word */
     fnstcw 0x5c(%rdi) /* save x87 control word */
- leaq link_fcontext(%rip), %rcx /* helper code executed after context function returns */
+
+ leaq finish(%rip), %rcx /* helper code executed after context function returns */
     movq %rcx, (%rdx)
+
     xorq %rax, %rax /* set RAX to zero */
     ret
 
-link_fcontext:
- movq %r12, %rsi /* restore next context */
- testq %rsi, %rsi /* test if a next context was given */
- je 1f /* jump to finish */
-
- movq %rbx, %rdi /* restore current context */
- call start_fcontext_at_PLT /* jump to next context */
-
-1:
+finish:
     xorq %rdi, %rdi /* exit code is zero */
     call _exit_at_PLT /* exit application */
     hlt

Modified: trunk/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -56,14 +56,13 @@
     movq %r15, 0x20(%rdi) /* save R15 */
     movq %rbp, 0x28(%rdi) /* save RBP */
 
- stmxcsr 0x58(%rdi) /* save MMX control and status word */
- fnstcw 0x5c(%rdi) /* save x87 control word */
-
- leaq 0x8(%rsp), %rcx /* exclude the return address and save as stack pointer */
- movq %rcx, 0x30(%rdi) /* save as stack pointer */
- movq (%rsp), %rcx /* save return address */
- movq %rcx, 0x38(%rdi) /* save return address as RIP */
+ stmxcsr 0x58(%rdi) /* save MMX control and status word */
+ fnstcw 0x5c(%rdi) /* save x87 control word */
 
+ leaq 0x8(%rsp), %rax /* exclude the return address and save as stack pointer */
+ movq %rax, 0x30(%rdi) /* save as stack pointer */
+ movq (%rsp), %rax /* save return address */
+ movq %rax, 0x38(%rdi) /* save return address as RIP */
 
     movq (%rsi), %rbx /* restore RBX */
     movq 0x8(%rsi), %r12 /* restore R12 */
@@ -75,11 +74,11 @@
     ldmxcsr 0x58(%rsi) /* restore MMX control and status word */
     fldcw 0x5c(%rsi) /* restore x87 control word */
 
- movq %rdx, %rax /* use third arg as return value after jump */
-
     movq 0x30(%rsi), %rsp /* restore RSP */
     movq 0x38(%rsi), %rcx /* fetch the address to return to */
- movq %r13, %rdi /* restore void pointer as argument */
+
+ movq %rdx, %rax /* use third arg as return value after jump */
+ movq %rdx, %rdi /* use third arg as first arg in context function */
 
     jmp *%rcx /* indirect jump to context */
 
@@ -104,20 +103,14 @@
     movq %rcx, 0x8(%rdi) /* save the address of next context */
     stmxcsr 0x58(%rdi) /* save MMX control and status word */
     fnstcw 0x5c(%rdi) /* save x87 control word */
- leaq link_fcontext(%rip), %rcx /* helper code executed after context function returns */
+
+ leaq finish(%rip), %rcx /* helper code executed after context function returns */
     movq %rcx, (%rdx)
+
     xorq %rax, %rax /* set RAX to zero */
     ret
 
-link_fcontext:
- movq %r12, %rsi /* restore next context */
- testq %rsi, %rsi /* test if a next context was given */
- je 1f /* jump to finish */
-
- movq %rbx, %rdi /* restore current context */
- call start_fcontext_at_PLT /* jump to next context */
-
-1:
+finish:
     xorq %rdi, %rdi /* exit code is zero */
     call _exit_at_PLT /* exit application */
     hlt

Modified: trunk/libs/context/src/fcontext.cpp
==============================================================================
--- trunk/libs/context/src/fcontext.cpp (original)
+++ trunk/libs/context/src/fcontext.cpp 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -18,7 +18,8 @@
 namespace ctx {
 namespace detail {
 
-extern "C" BOOST_CONTEXT_DECL void * BOOST_CONTEXT_CALLDECL align_stack( void * vp)
+extern "C" BOOST_CONTEXT_DECL
+void * BOOST_CONTEXT_CALLDECL align_stack( void * vp)
 {
         void * base = vp;
     if ( 0 != ( ( ( uintptr_t) base) & 15) )
@@ -29,11 +30,6 @@
 
 }
 
-# if !defined(__arm__) && !defined(__powerpc__)
-extern "C" BOOST_CONTEXT_DECL intptr_t BOOST_CONTEXT_CALLDECL start_fcontext( fcontext_t * ofc, fcontext_t const* nfc)
-{ return jump_fcontext( ofc, nfc, 0); }
-#endif
-
 }}
 
 #ifdef BOOST_HAS_ABI_HEADERS

Modified: trunk/libs/context/test/test_context.cpp
==============================================================================
--- trunk/libs/context/test/test_context.cpp (original)
+++ trunk/libs/context/test/test_context.cpp 2012-04-21 15:05:03 EDT (Sat, 21 Apr 2012)
@@ -8,6 +8,7 @@
 #include <sstream>
 #include <stdexcept>
 #include <string>
+#include <utility>
 
 #include <boost/assert.hpp>
 #include <boost/test/unit_test.hpp>
@@ -28,11 +29,6 @@
         ctx::jump_fcontext( & fc1, & fcm, 0);
 }
 
-void f2( intptr_t)
-{
- ++value1;
-}
-
 void f3( intptr_t)
 {
     ++value1;
@@ -53,9 +49,12 @@
 
 void f6( intptr_t arg)
 {
- ctx::jump_fcontext(
- & fc1, & fcm,
- ctx::jump_fcontext( & fc1, & fcm, arg) );
+ std::pair< int, int > data = * ( std::pair< int, int > * ) arg;
+ int res = data.first + data.second;
+ data = * ( std::pair< int, int > *)
+ ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) res);
+ res = data.first + data.second;
+ ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) res);
 }
 
 void f7( intptr_t arg)
@@ -64,6 +63,7 @@
     { throw std::runtime_error( ( char *) arg); }
     catch ( std::runtime_error const& e)
     { value2 = e.what(); }
+ ctx::jump_fcontext( & fc1, & fcm, arg);
 }
 
 void f8( intptr_t arg)
@@ -71,6 +71,7 @@
     double d = * ( double *) arg;
     d += 3.45;
     value3 = d;
+ ctx::jump_fcontext( & fc1, & fcm, 0);
 }
 
 void test_start()
@@ -84,23 +85,7 @@
     ctx::make_fcontext( & fc1, f1, 0);
 
     BOOST_CHECK_EQUAL( 0, value1);
- ctx::start_fcontext( & fcm, & fc1);
- BOOST_CHECK_EQUAL( 1, value1);
-}
-
-void test_link()
-{
- value1 = 0;
-
- ctx::stack_allocator alloc;
-
- fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
- fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
- fc1.fc_link = & fcm;
- ctx::make_fcontext( & fc1, f2, 0);
-
- BOOST_CHECK_EQUAL( 0, value1);
- ctx::start_fcontext( & fcm, & fc1);
+ ctx::jump_fcontext( & fcm, & fc1, 0);
     BOOST_CHECK_EQUAL( 1, value1);
 }
 
@@ -115,7 +100,7 @@
     ctx::make_fcontext( & fc1, f3, 0);
 
     BOOST_CHECK_EQUAL( 0, value1);
- ctx::start_fcontext( & fcm, & fc1);
+ ctx::jump_fcontext( & fcm, & fc1, 0);
     BOOST_CHECK_EQUAL( 1, value1);
     ctx::jump_fcontext( & fcm, & fc1, 0);
     BOOST_CHECK_EQUAL( 2, value1);
@@ -129,7 +114,7 @@
     fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
     ctx::make_fcontext( & fc1, f4, 0);
 
- int result = ( int) ctx::start_fcontext( & fcm, & fc1);
+ int result = ( int) ctx::jump_fcontext( & fcm, & fc1, 0);
     BOOST_CHECK_EQUAL( 7, result);
 }
 
@@ -142,7 +127,7 @@
     int i = 7;
     ctx::make_fcontext( & fc1, f5, i);
 
- int result = ( int) ctx::start_fcontext( & fcm, & fc1);
+ int result = ( int) ctx::jump_fcontext( & fcm, & fc1, i);
     BOOST_CHECK_EQUAL( i, result);
 }
 
@@ -152,14 +137,14 @@
 
     fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
     fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
- int i = 3;
- ctx::make_fcontext( & fc1, f6, i);
+ std::pair< int, int > data = std::make_pair( 3, 7);
+ ctx::make_fcontext( & fc1, f6, ( intptr_t) & data);
 
- int result = ( int) ctx::start_fcontext( & fcm, & fc1);
- BOOST_CHECK_EQUAL( i, result);
- i = 7;
- result = ( int) ctx::jump_fcontext( & fcm, & fc1, i);
- BOOST_CHECK_EQUAL( i, result);
+ int result = ( int) ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) & data);
+ BOOST_CHECK_EQUAL( 10, result);
+ data = std::make_pair( 7, 7);
+ result = ( int) ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) & data);
+ BOOST_CHECK_EQUAL( 14, result);
 }
 
 void test_exception()
@@ -169,10 +154,9 @@
     fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
     fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
     char * what = "hello world";
- fc1.fc_link = & fcm;
     ctx::make_fcontext( & fc1, f7, ( intptr_t) what);
 
- ctx::start_fcontext( & fcm, & fc1);
+ ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) what);
     BOOST_CHECK_EQUAL( std::string( what), value2);
 }
 
@@ -182,11 +166,10 @@
 
     fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
     fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
- fc1.fc_link = & fcm;
     double d = 7.13;
     ctx::make_fcontext( & fc1, f8, ( intptr_t) & d);
 
- ctx::start_fcontext( & fcm, & fc1);
+ ctx::jump_fcontext( & fcm, & fc1, (intptr_t) & d);
     BOOST_CHECK_EQUAL( 10.58, value3);
 }
 
@@ -196,7 +179,6 @@
         BOOST_TEST_SUITE("Boost.Context: context test suite");
 
     test->add( BOOST_TEST_CASE( & test_start) );
- test->add( BOOST_TEST_CASE( & test_link) );
     test->add( BOOST_TEST_CASE( & test_jump) );
     test->add( BOOST_TEST_CASE( & test_result) );
     test->add( BOOST_TEST_CASE( & test_arg) );


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk