summaryrefslogtreecommitdiff
path: root/libs/context
diff options
context:
space:
mode:
Diffstat (limited to 'libs/context')
-rw-r--r--libs/context/build/Jamfile.v2373
-rw-r--r--libs/context/build/architecture.jam76
-rw-r--r--libs/context/config/32.cpp9
-rw-r--r--libs/context/config/64.cpp9
-rw-r--r--libs/context/config/Jamfile.jam17
-rw-r--r--libs/context/config/arm.cpp13
-rw-r--r--libs/context/config/mips1.cpp11
-rw-r--r--libs/context/config/power.cpp14
-rw-r--r--libs/context/config/x86.cpp16
-rw-r--r--libs/context/doc/Jamfile.v225
-rw-r--r--libs/context/doc/acknowledgements.qbk15
-rw-r--r--libs/context/doc/config.qbk60
-rw-r--r--libs/context/doc/context.qbk75
-rw-r--r--libs/context/doc/fcontext.qbk251
-rw-r--r--libs/context/doc/html/context/acknowledgements.html48
-rw-r--r--libs/context/doc/html/context/context.html294
-rw-r--r--libs/context/doc/html/context/context/boost_fcontext.html146
-rw-r--r--libs/context/doc/html/context/overview.html83
-rw-r--r--libs/context/doc/html/context/performance.html152
-rw-r--r--libs/context/doc/html/context/rationale.html104
-rw-r--r--libs/context/doc/html/context/rationale/other_apis_.html117
-rw-r--r--libs/context/doc/html/context/rationale/x86_and_floating_point_env.html124
-rw-r--r--libs/context/doc/html/context/reference.html104
-rw-r--r--libs/context/doc/html/context/requirements.html59
-rw-r--r--libs/context/doc/html/context/stack.html163
-rw-r--r--libs/context/doc/html/context/stack/stack_allocator.html51
-rw-r--r--libs/context/doc/html/context/stack/stack_helper.html170
-rw-r--r--libs/context/doc/html/context/tested.html295
-rw-r--r--libs/context/doc/html/context/todo.html51
-rw-r--r--libs/context/doc/html/index.html72
-rw-r--r--libs/context/doc/html/standalone_HTML.manifest16
-rw-r--r--libs/context/doc/overview.qbk42
-rw-r--r--libs/context/doc/performance.qbk39
-rw-r--r--libs/context/doc/rationale.qbk148
-rw-r--r--libs/context/doc/reference.qbk43
-rw-r--r--libs/context/doc/requirements.qbk18
-rw-r--r--libs/context/doc/stack.qbk116
-rw-r--r--libs/context/doc/tested.qbk74
-rw-r--r--libs/context/doc/todo.qbk13
-rw-r--r--libs/context/example/Jamfile.v249
-rw-r--r--libs/context/example/exit.cpp57
-rw-r--r--libs/context/example/jump.cpp56
-rw-r--r--libs/context/example/transfer.cpp51
-rw-r--r--libs/context/index.html14
-rw-r--r--libs/context/performance/Jamfile.v264
-rw-r--r--libs/context/performance/bind_processor.hpp12
-rw-r--r--libs/context/performance/bind_processor_aix.cpp25
-rw-r--r--libs/context/performance/bind_processor_freebsd.cpp29
-rw-r--r--libs/context/performance/bind_processor_hpux.cpp31
-rw-r--r--libs/context/performance/bind_processor_linux.cpp30
-rw-r--r--libs/context/performance/bind_processor_solaris.cpp26
-rw-r--r--libs/context/performance/bind_processor_windows.cpp24
-rw-r--r--libs/context/performance/cycle.hpp26
-rw-r--r--libs/context/performance/cycle_i386.hpp83
-rw-r--r--libs/context/performance/cycle_x86-64.hpp79
-rw-r--r--libs/context/performance/performance.cpp262
-rw-r--r--libs/context/performance/zeit.hpp53
-rw-r--r--libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S101
-rw-r--r--libs/context/src/asm/fcontext_i386_ms_pe_masm.asm151
-rw-r--r--libs/context/src/asm/fcontext_i386_sysv_elf_gas.S122
-rw-r--r--libs/context/src/asm/fcontext_i386_sysv_macho_gas.S118
-rw-r--r--libs/context/src/asm/fcontext_mips32_o32_elf_gas.S144
-rw-r--r--libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S222
-rw-r--r--libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S250
-rw-r--r--libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm207
-rw-r--r--libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S116
-rw-r--r--libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S111
-rw-r--r--libs/context/src/fcontext.cpp36
-rw-r--r--libs/context/src/seh.cpp83
-rw-r--r--libs/context/src/stack_allocator_posix.cpp84
-rw-r--r--libs/context/src/stack_allocator_windows.cpp86
-rw-r--r--libs/context/src/stack_utils_posix.cpp80
-rw-r--r--libs/context/src/stack_utils_windows.cpp84
-rw-r--r--libs/context/test/Jamfile.v225
-rw-r--r--libs/context/test/test_context.cpp190
75 files changed, 6687 insertions, 0 deletions
diff --git a/libs/context/build/Jamfile.v2 b/libs/context/build/Jamfile.v2
new file mode 100644
index 0000000000..bbe9e87255
--- /dev/null
+++ b/libs/context/build/Jamfile.v2
@@ -0,0 +1,373 @@
+
+# Boost.Context Library Build Jamfile
+
+# Copyright Oliver Kowalke 2009.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import common ;
+import feature ;
+import indirect ;
+import modules ;
+import os ;
+import toolset ;
+import architecture ;
+
+project boost/context
+ : source-location ../src
+ : requirements
+ <os>SOLARIS:<define>_XOPEN_SOURCE=1
+ <os>SOLARIS:<define>_XOPEN_SOURCE_EXTENDED=1
+ : usage-requirements
+ <link>shared:<define>BOOST_CONTEXT_DYN_LINK=1
+ ;
+
+local rule default_binary_format ( )
+{
+ local tmp = elf ;
+ if [ os.name ] = "MACOSX" { tmp = mach-o ; }
+ if [ os.name ] = "NT" { tmp = pe ; }
+ return $(tmp) ;
+}
+
+feature.feature binary-format
+ : elf
+ mach-o
+ pe
+ : propagated
+ ;
+feature.set-default binary-format : [ default_binary_format ] ;
+
+
+local rule default_abi ( )
+{
+ local tmp = sysv ;
+ if [ os.name ] = "NT" { tmp = ms ; }
+ else if [ os.platform ] = "ARM" { tmp = aapcs ; }
+ else if [ os.platform ] = "MIPS" { tmp = o32 ; }
+ return $(tmp) ;
+}
+
+feature.feature abi
+ : aapcs
+ eabi
+ ms
+ n32
+ n64
+ o32
+ o64
+ sysv
+ : propagated
+ ;
+feature.set-default abi : [ default_abi ] ;
+
+
+actions gas
+{
+ as -o "$(<)" "$(>)"
+}
+
+actions masm
+{
+ ml /c /Fo"$(<)" "$(>)"
+}
+
+actions masm64
+{
+ ml64 /c /Fo"$(<)" "$(>)"
+}
+
+
+rule configure ( properties * )
+{
+ local result ;
+
+ if ( ! ( <toolset>gcc in $(properties)
+ || <toolset>intel in $(properties)
+ || <toolset>msvc in $(properties) ) )
+ {
+ result = <build>no ;
+ ECHO "toolset not supported" ;
+ }
+
+ return $(result) ;
+}
+
+# ARM
+alias asm_context_sources
+ : asm/fcontext_arm_aapcs_elf_gas.S
+ : <abi>aapcs
+ <architecture>arm
+ <binary-format>elf
+ <toolset>gcc
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_arm_aapcs_elf_gas.o : asm/fcontext_arm_aapcs_elf_gas.S : @gas ]
+ : <abi>aapcs
+ <architecture>arm
+ <binary-format>elf
+ ;
+
+# MIPS 32bit
+alias asm_context_sources
+ : asm/fcontext_mips32_o32_elf_gas.S
+ : <abi>o32
+ <architecture>mips1
+ <binary-format>elf
+ <toolset>gcc
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_mips32_o32_elf_gas.o : asm/fcontext_mips32_o32_elf_gas.S : @gas ]
+ : <abi>o32
+ <architecture>mips1
+ <binary-format>elf
+ ;
+
+# POWERPC 32bit
+alias asm_context_sources
+ : asm/fcontext_ppc32_sysv_elf_gas.S
+ : <abi>sysv
+ <address-model>32
+ <architecture>power
+ <binary-format>elf
+ <toolset>gcc
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_ppc32_sysv_elf_gas.o : asm/fcontext_ppc32_sysv_elf_gas.S : @gas ]
+ : <abi>sysv
+ <address-model>32
+ <architecture>power
+ <binary-format>elf
+ ;
+
+# POWERPC 64bit
+alias asm_context_sources
+ : asm/fcontext_ppc64_sysv_elf_gas.S
+ : <abi>sysv
+ <address-model>64
+ <architecture>power
+ <binary-format>elf
+ <toolset>gcc
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_ppc64_sysv_elf_gas.o : asm/fcontext_ppc64_sysv_elf_gas.S : @gas ]
+ : <abi>sysv
+ <address-model>64
+ <architecture>power
+ <binary-format>elf
+ ;
+
+# I386
+alias asm_context_sources
+ : asm/fcontext_i386_sysv_elf_gas.S
+ : <abi>sysv
+ <address-model>32
+ <architecture>x86
+ <binary-format>elf
+ <toolset>gcc
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_i386_sysv_elf_gas.S
+ : <abi>sysv
+ <address-model>32
+ <architecture>x86
+ <binary-format>elf
+ <toolset>intel
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_i386_sysv_elf_gas.o : asm/fcontext_i386_sysv_elf_gas.S : @gas ]
+ : <abi>sysv
+ <address-model>32
+ <architecture>x86
+ <binary-format>elf
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_i386_sysv_macho_gas.S
+ : <abi>sysv
+ <address-model>32
+ <architecture>x86
+ <binary-format>mach-o
+ <target-os>darwin
+ <toolset>gcc
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_i386_sysv_macho_gas.S
+ : <abi>sysv
+ <address-model>32
+ <architecture>x86
+ <binary-format>mach-o
+ <target-os>darwin
+ <toolset>intel
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_i386_sysv_macho_gas.o : asm/fcontext_i386_sysv_macho_gas.S : @gas ]
+ : <abi>sysv
+ <address-model>32
+ <architecture>x86
+ <binary-format>mach-o
+ <target-os>darwin
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_i386_ms_pe_masm.asm
+ : <abi>ms
+ <address-model>32
+ <architecture>x86
+ <binary-format>pe
+ <target-os>windows
+ <toolset>intel
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_i386_ms_pe_masm.asm
+ : <abi>ms
+ <address-model>32
+ <architecture>x86
+ <binary-format>pe
+ <target-os>windows
+ <toolset>msvc
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_i386_ms_pe_masm.o : asm/fcontext_i386_ms_pe_masm.asm : @masm ]
+ : <abi>ms
+ <address-model>32
+ <architecture>x86
+ <binary-format>pe
+ <target-os>windows
+ <toolset>gcc
+ ;
+
+
+# X86_64
+alias asm_context_sources
+ : asm/fcontext_x86_64_sysv_elf_gas.S
+ : <abi>sysv
+ <address-model>64
+ <architecture>x86
+ <binary-format>elf
+ <toolset>gcc
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_x86_64_sysv_elf_gas.S
+ : <abi>sysv
+ <address-model>64
+ <architecture>x86
+ <binary-format>elf
+ <toolset>intel
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_x86_64_sysv_elf_gas.o : asm/fcontext_x86_64_sysv_elf_gas.S : @gas ]
+ : <abi>sysv
+ <address-model>64
+ <architecture>x86
+ <binary-format>elf
+ ;
+
+
+alias asm_context_sources
+ : asm/fcontext_x86_64_sysv_macho_gas.S
+ : <abi>sysv
+ <address-model>64
+ <architecture>x86
+ <binary-format>mach-o
+ <target-os>darwin
+ <toolset>gcc
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_x86_64_sysv_macho_gas.S
+ : <abi>sysv
+ <address-model>64
+ <architecture>x86
+ <binary-format>mach-o
+ <target-os>darwin
+ <toolset>intel
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_x86_64_sysv_macho_gas.o : asm/fcontext_x86_64_sysv_macho_gas.S : @gas ]
+ : <abi>sysv
+ <address-model>64
+ <architecture>x86
+ <binary-format>mach-o
+ <target-os>darwin
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_x86_64_ms_pe_masm.asm
+ : <abi>ms
+ <address-model>64
+ <architecture>x86
+ <binary-format>pe
+ <target-os>windows
+ <toolset>intel
+ ;
+
+alias asm_context_sources
+ : asm/fcontext_x86_64_ms_pe_masm.asm
+ : <abi>ms
+ <address-model>64
+ <architecture>x86
+ <binary-format>pe
+ <target-os>windows
+ <toolset>msvc
+ ;
+
+alias asm_context_sources
+ : [ make asm/fcontext_x86_64_ms_pe_masm.o : asm/fcontext_x86_64_ms_pe_masm.asm : @masm64 ]
+ : <abi>ms
+ <address-model>64
+ <architecture>x86
+ <binary-format>pe
+ <target-os>windows
+ <toolset>gcc
+ ;
+
+explicit asm_context_sources ;
+
+
+alias select_asm_context_sources
+ : asm_context_sources
+ : [ architecture.architecture ]
+ [ architecture.address-model ]
+ ;
+
+
+alias context_sources
+ : fcontext.cpp
+ seh.cpp
+ stack_allocator_windows.cpp
+ stack_utils_windows.cpp
+ : <target-os>windows
+ ;
+
+alias context_sources
+ : fcontext.cpp
+ stack_allocator_posix.cpp
+ stack_utils_posix.cpp
+ ;
+
+explicit context_sources ;
+
+
+lib boost_context
+ : select_asm_context_sources
+ context_sources
+ : <link>shared:<define>BOOST_CONTEXT_DYN_LINK=1
+ ;
+
+
+boost-install boost_context ;
diff --git a/libs/context/build/architecture.jam b/libs/context/build/architecture.jam
new file mode 100644
index 0000000000..e06b1d2cda
--- /dev/null
+++ b/libs/context/build/architecture.jam
@@ -0,0 +1,76 @@
+# architecture.jam
+#
+# Copyright 2012 Steven Watanabe
+#
+# Distributed under the Boost Software License Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import configure ;
+import project ;
+import path ;
+import property ;
+
+local here = [ modules.binding $(__name__) ] ;
+
+project.push-current [ project.current ] ;
+project.load [ path.join [ path.make $(here:D) ] ../config ] ;
+project.pop-current ;
+
+rule deduce-address-model ( properties * )
+{
+ local result = [ property.select <address-model> : $(properties) ] ;
+ if $(result)
+ {
+ return $(result) ;
+ }
+ else
+ {
+ if [ configure.builds /boost/architecture//32 : $(properties) : 32-bit ]
+ {
+ return <address-model>32 ;
+ }
+ else if [ configure.builds /boost/architecture//64 : $(properties) : 64-bit ]
+ {
+ return <address-model>64 ;
+ }
+ }
+}
+
+rule address-model ( )
+{
+ return <conditional>@architecture.deduce-address-model ;
+}
+
+rule deduce-architecture ( properties * )
+{
+ local result = [ property.select <architecture> : $(properties) ] ;
+ if $(result)
+ {
+ return $(result) ;
+ }
+ else
+ {
+ if [ configure.builds /boost/architecture//x86 : $(properties) : x86 ]
+ {
+ return <architecture>x86 ;
+ }
+ else if [ configure.builds /boost/architecture//power : $(properties) : power ]
+ {
+ return <architecture>power ;
+ }
+ else if [ configure.builds /boost/architecture//arm : $(properties) : arm ]
+ {
+ return <architecture>arm ;
+ }
+ else if [ configure.builds /boost/architecture//mips1 : $(properties) : mips1 ]
+ {
+ return <architecture>mips1 ;
+ }
+ }
+}
+
+rule architecture ( )
+{
+ return <conditional>@architecture.deduce-architecture ;
+}
diff --git a/libs/context/config/32.cpp b/libs/context/config/32.cpp
new file mode 100644
index 0000000000..d3d2dba29c
--- /dev/null
+++ b/libs/context/config/32.cpp
@@ -0,0 +1,9 @@
+// 32.cpp
+//
+// Copyright (c) 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+int test[sizeof(void*) == 4? 1 : -1];
diff --git a/libs/context/config/64.cpp b/libs/context/config/64.cpp
new file mode 100644
index 0000000000..5a33bc6452
--- /dev/null
+++ b/libs/context/config/64.cpp
@@ -0,0 +1,9 @@
+// 64.cpp
+//
+// Copyright (c) 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+int test[sizeof(void*) == 8? 1 : -1];
diff --git a/libs/context/config/Jamfile.jam b/libs/context/config/Jamfile.jam
new file mode 100644
index 0000000000..a9a7b3f446
--- /dev/null
+++ b/libs/context/config/Jamfile.jam
@@ -0,0 +1,17 @@
+# Jamfile.jam
+#
+# Copyright 2012 Steven Watanabe
+#
+# Distributed under the Boost Software License Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+project /boost/architecture ;
+
+obj 32 : 32.cpp ;
+obj 64 : 64.cpp ;
+
+obj power : power.cpp ;
+obj x86 : x86.cpp ;
+obj mips1 : mips1.cpp ;
+obj arm : arm.cpp ;
diff --git a/libs/context/config/arm.cpp b/libs/context/config/arm.cpp
new file mode 100644
index 0000000000..e56cddf039
--- /dev/null
+++ b/libs/context/config/arm.cpp
@@ -0,0 +1,13 @@
+// arm.cpp
+//
+// Copyright (c) 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(__arm__) && !defined(__thumb__) && \
+ !defined(__TARGET_ARCH_ARM) && !defined(__TARGET_ARCH_THUMB) && \
+ !defined(_ARM)
+#error "Not ARM"
+#endif
diff --git a/libs/context/config/mips1.cpp b/libs/context/config/mips1.cpp
new file mode 100644
index 0000000000..adc4a61d03
--- /dev/null
+++ b/libs/context/config/mips1.cpp
@@ -0,0 +1,11 @@
+// mips1.cpp
+//
+// Copyright (c) 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if !((defined(__mips) && __mips == 1) || defined(_MIPS_ISA_MIPS1) || defined(_R3000))
+#error "Not MIPS1"
+#endif
diff --git a/libs/context/config/power.cpp b/libs/context/config/power.cpp
new file mode 100644
index 0000000000..0551194a97
--- /dev/null
+++ b/libs/context/config/power.cpp
@@ -0,0 +1,14 @@
+// power.cpp
+//
+// Copyright (c) 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(__powerpc) && !defined(__powerpc__) && !defined(__ppc) \
+ && !defined(__ppc__) && !defined(_M_PPC) && !defined(_ARCH_PPC) \
+ && !defined(__POWERPC__) && !defined(__PPCGECKO__) \
+ && !defined(__PPCBROADWAY) && !defined(_XENON)
+#error "Not PPC"
+#endif
diff --git a/libs/context/config/x86.cpp b/libs/context/config/x86.cpp
new file mode 100644
index 0000000000..0d2f9c2e90
--- /dev/null
+++ b/libs/context/config/x86.cpp
@@ -0,0 +1,16 @@
+// x86.cpp
+//
+// Copyright (c) 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(i386) && !defined(__i386__) && !defined(__i386) \
+ && !defined(__i486__) && !defined(__i586__) && !defined(__i686__) \
+ && !defined(_M_IX86) && !defined(__X86__) && !defined(_X86_) \
+ && !defined(__THW_INTEL__) && !defined(__I86__) && !defined(__INTEL__) \
+ && !defined(__amd64__) && !defined(__x86_64__) && !defined(__amd64) \
+ && !defined(__x86_64) && !defined(_M_X64)
+#error "Not x86"
+#endif
diff --git a/libs/context/doc/Jamfile.v2 b/libs/context/doc/Jamfile.v2
new file mode 100644
index 0000000000..df263bbd4b
--- /dev/null
+++ b/libs/context/doc/Jamfile.v2
@@ -0,0 +1,25 @@
+# (C) Copyright 2008 Anthony Williams
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+xml context : context.qbk ;
+
+boostbook standalone
+ :
+ context
+ :
+ # HTML options first:
+ # How far down we chunk nested sections, basically all of them:
+ <xsl:param>chunk.section.depth=3
+ # Don't put the first section on the same page as the TOC:
+ <xsl:param>chunk.first.sections=1
+ # How far down sections get TOC's
+ <xsl:param>toc.section.depth=10
+ # Max depth in each TOC:
+ <xsl:param>toc.max.depth=3
+ # How far down we go with TOC's
+ <xsl:param>generate.section.toc.level=10
+ # Path for links to Boost:
+ <xsl:param>boost.root=../../../..
+ ;
diff --git a/libs/context/doc/acknowledgements.qbk b/libs/context/doc/acknowledgements.qbk
new file mode 100644
index 0000000000..34f02308db
--- /dev/null
+++ b/libs/context/doc/acknowledgements.qbk
@@ -0,0 +1,15 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:acknowledgements Acknowledgments]
+
+I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, Fernando Pelliccioni,
+Giovanni Piero Deretta, Gordon Woodhull, Helge Bahmann, Holger Grund,
+Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Phil Endecott, Robert Stewart,
+Steven Watanabe, Vicente J. Botet Escriba, Wayne Piekarski.
+
+[endsect]
diff --git a/libs/context/doc/config.qbk b/libs/context/doc/config.qbk
new file mode 100644
index 0000000000..7716a4821c
--- /dev/null
+++ b/libs/context/doc/config.qbk
@@ -0,0 +1,60 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:installtion How to build and install]
+
+__boost_context__ must be built for the particular compiler(s) and CPU architecture(s)s
+being targeted. __boost_context__ includes assembly code and, therefore, requires
+GNU AS for supported POSIX systems, and MASM for Windows systems.
+
+[note The architecture, instruction set, and address model are optional __boost_build__
+properties that must be given on the bjam command line, as shown in the table below.]
+
+[table
+ [[][]]
+ [
+ [ARM, UNIX, aapcs, elf]
+ [bjam toolset = gcc architecture = arm]
+ ]
+ [
+ [MIPS (32bit), UNIX, o32, elf]
+ [bjam toolset = gcc architecture = mips1]
+ ]
+ [
+ [I386, UNIX, sysv, elf]
+ [bjam toolset = gcc architecture = x86 instruction-set = i686 address-model = 32]
+ ]
+ [
+ [I386, UNIX, sysv, elf]
+ [bjam toolset = intel architecture = x86 instruction-set = i686 address-model = 32]
+ ]
+ [
+ [I386, Windows, ms, pe]
+ [bjam toolset = msvc-9.0 architecture = x86 instruction-set = i686 address-model = 32]
+ ]
+ [
+ [PowerPc (32bit), UNIX, sysv, elf]
+ [bjam toolset = gcc architecture = power address-model = 32]
+ ]
+ [
+ [PowerPc (64bit), UNIX, sysv, elf]
+ [bjam toolset = gcc architecture = power address-model = 64]
+ ]
+ [
+ [X86_64, UNIX, sysv, elf]
+ [bjam toolset = gcc architecture = x86 instruction-set = yorksfield address-model = 64]
+ ]
+ [
+ [X86_64, UNIX, sysv, elf]
+ [bjam toolset = intel architecture = x86 instruction-set = yorksfield address-model = 64]
+ ]
+ [
+ [X86_64, Windows, ms, pe]
+ [bjam toolset = msvc-10.0 architecture = x86 instruction-set = yorksfield address-model = 64]
+ ]
+]
+[endsect]
diff --git a/libs/context/doc/context.qbk b/libs/context/doc/context.qbk
new file mode 100644
index 0000000000..c12853bcbf
--- /dev/null
+++ b/libs/context/doc/context.qbk
@@ -0,0 +1,75 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[article Context
+ [quickbook 1.4]
+ [authors [Kowalke, Oliver]]
+ [copyright 2009 Oliver Kowalke]
+ [purpose C++ Library for swiching different user ctx]
+ [category text]
+ [license
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ [@http://www.boost.org/LICENSE_1_0.txt])
+ ]
+]
+
+
+[def __boost_build__ [*Boost.Build]]
+[def __boost_context__ [*Boost.Context]]
+[def __boost_fiber__ [*Boost.Coroutine]]
+[def __boost_task__ [*Boost.Task]]
+
+[template cs_example_link[link_text] [link context.examples.enumerator [link_text]]]
+[template context_link[link_text] [link context.context.context [link_text]]]
+[template stack_link[link_text] [link context.stack [link_text]]]
+[template preformance_link[link_text] [link context.performance [link_text]]]
+
+[def __context_fn__ ['context-function]]
+[def __coroutine__ ['coroutine]]
+[def __coroutines__ ['coroutines]]
+[def __coop_threads__ ['cooperative threads (userland threads)]]
+[def __fls__ ['fiber-local storage]]
+[def __guard_page__ ['guard-page]]
+[def __not_a_context__ ['not-a-context]]
+[def __stack__ [stack_link ['stack]]]
+[def __thread__ ['thread]]
+[def __threads__ ['threads]]
+[def __tls__ ['thread-local storage]]
+[def __stack_allocator__ ['StackAllocator]]
+[def __stack_allocator_concept__ ['StackAllocator concept]]
+
+[def __fcontext__ ['fcontext_t]]
+[def __ucontext__ ['ucontext_t]]
+
+[def __fls_alloc__ ['::FlsAlloc()]]
+[def __fls_free__ ['::FlsFree()]]
+
+[def __bad_alloc__ ['std::bad_alloc]]
+[def __fc_base__ ['fc_base]]
+[def __fc_limit__ ['fc_limit]]
+[def __fc_link__ ['fc_link]]
+[def __jump_fcontext__ ['jump_fcontext()]]
+[def __make_fcontext__ ['make_fcontext()]]
+[def __invalid_argument__ ['std::invalid_argument]]
+[def __stack_alloc__ ['allocate()]]
+[def __stack_dealloc__ ['deallocate()]]
+[def __stack_helper__ ['stack_helper]]
+[def __yield__ ['yield]]
+
+[def __context_ns__ ['boost::ctx]]
+
+[include overview.qbk]
+[include requirements.qbk]
+[include fcontext.qbk]
+[include stack.qbk]
+[include performance.qbk]
+[include tested.qbk]
+[include rationale.qbk]
+[include reference.qbk]
+[include todo.qbk]
+[include acknowledgements.qbk]
diff --git a/libs/context/doc/fcontext.qbk b/libs/context/doc/fcontext.qbk
new file mode 100644
index 0000000000..2c320f0cd7
--- /dev/null
+++ b/libs/context/doc/fcontext.qbk
@@ -0,0 +1,251 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:context Context]
+
+Each instance of __fcontext__ represents a context (CPU registers and stack
+space). Together with its related functions __jump_fcontext__ and
+__make_fcontext__ it provides a execution control transfer mechanism similar
+interface like
+[@http://www.kernel.org/doc/man-pages/online/pages/man2/getcontext.2.html ucontext_t].
+__fcontext__ and its functions are located in __context_ns__ and the functions
+are declared as extern "C".
+
+[warning If __fcontext__ is used in a multithreaded application, it can migrated
+between threads, but must not reference __tls__.]
+
+[note If __fls__ is used on Windows, the user is responsible for calling
+__fls_alloc__, __fls_free__.]
+
+[important The low level API is the part to port to new platforms.]
+
+
+[heading Executing a context]
+
+A new context supposed to execute a __context_fn__ (returning void and accepting
+intptr_t as argument) must be initialized by function __make_fcontext__.
+
+ // context-function
+ void f( intptr);
+
+ // creates and manages a protected stack (with guard page)
+ ctx::stack_allocator alloc;
+ fc.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
+ fc.fc_stack.limit =
+ static_cast< char * >( fc.fc_stack.base) - ctx::minimum_stacksize();
+
+ // context fc uses f() as context function
+ make_fcontext( & fc, f);
+
+__fcontext__ requires a pointer to the top of the stack (__fc_base__) as well
+as a pointer to the lower bound of the stack (__fc_limit__).
+
+Calling __jump_fcontext__ invokes the __context_fn__ in a newly created context
+complete with registers, flags, stack and instruction pointers. When control
+should be returned to the original calling context, call __jump_fcontext__.
+The current context information (registers, flags, and stack and instruction
+pointers) is saved and the original context information is restored. Calling
+__jump_fcontext__ again resumes execution in the second context after saving the
+new state of the original context.
+
+ namespace ctx = boost::ctx;
+
+ ctx::fcontext_t fcm, fc1, fc2;
+
+ void f1( intptr_t)
+ {
+ std::cout << "f1: entered" << std::endl;
+ std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl;
+ ctx::jump_fcontext( & fc1, & fc2, 0);
+ std::cout << "f1: return" << std::endl;
+ ctx::jump_fcontext( & fc1, & fcm, 0);
+ }
+
+ void f2( intptr_t)
+ {
+ std::cout << "f2: entered" << std::endl;
+ std::cout << "f2: call jump_fcontext( & fc2, & fc1, 0)" << std::endl;
+ ctx::jump_fcontext( & fc2, & fc1, 0);
+ BOOST_ASSERT( false && ! "f2: never returns");
+ }
+
+ int main( int argc, char * argv[])
+ {
+ ctx::stack_allocator alloc1, alloc2;
+
+ fc1.fc_stack.base = alloc1.allocate(ctx::minimum_stacksize());
+ fc1.fc_stack.limit =
+ static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
+ ctx::make_fcontext( & fc1, f1);
+
+ fc2.fc_stack.base = alloc2.allocate(ctx::minimum_stacksize());
+ fc2.fc_stack.limit =
+ static_cast< char * >( fc2.fc_stack.base) - ctx::minimum_stacksize();
+ ctx::make_fcontext( & fc2, f2);
+
+ std::cout << "main: call jump_fcontext( & fcm, & fc1, 0)" << std::endl;
+ ctx::jump_fcontext( & fcm, & fc1, 0);
+
+ std::cout << "main: done" << std::endl;
+
+ return EXIT_SUCCESS;
+ }
+
+ output:
+ main: call jump_fcontext( & fcm, & fc1, 0)
+ f1: entered
+ f1: call jump_fcontext( & fc1, & fc2, 0)
+ f2: entered
+ f2: call jump_fcontext( & fc2, & fc1, 0)
+ f1: return
+ main: done
+
+First call of __jump_fcontext__ enters the __context_fn__ `f1()` by starting
+context fc1 (context fcm saves the registers of `main()`). For jumping between
+context's fc1 and fc2 `jump_fcontext()` is called.
+Because context fcm is chained to fc1, `main()` is entered (returning from
+__jump_fcontext__) after context fc1 becomes complete (return from `f1()`).
+
+[warning Calling __jump_fcontext__ to the same context from inside the same
+context results in undefined behaviour.]
+
+[note In contrast to threads, which are preemtive, __fcontext__ switches are
+cooperative (programmer controls when switch will happen). The kernel is not
+involved in the context switches.]
+
+
+[heading Transfer of data]
+
+The third argument passed to __jump_fcontext__, in one context, is passed as
+the first argument of the __context_fn__ if the context is started for the
+first time.
+In all following invocations of __jump_fcontext__ the intptr_t passed to
+__jump_fcontext__, in one context, is returned by __jump_fcontext__ in the
+other context.
+
+ namespace ctx = boost::ctx;
+
+ ctx::fcontext_t fc1, fcm;
+
+ typedef std::pair< int, int > pair_t;
+
+ void f1( intptr_t param)
+ {
+ pair_t * p = ( pair_t *) param;
+
+ p = ( pair_t *) ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) ( p->first + p->second) );
+
+ ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) ( p->first + p->second) );
+ }
+
+ int main( int argc, char * argv[])
+ {
+ 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;
+ pair_t p( std::make_pair( 2, 7) );
+ ctx::make_fcontext( & fc1, f1);
+
+ 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);
+ res = ( int) ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) & p);
+ std::cout << p.first << " + " << p.second << " == " << res << std::endl;
+
+ std::cout << "main: done" << std::endl;
+
+ return EXIT_SUCCESS;
+ }
+
+ output:
+ 2 + 7 == 9
+ 5 + 6 == 11
+ main: done
+
+
+[heading Exceptions in __context_fn__]
+
+If the __context_fn__ emits an exception, the application will terminate.
+
+
+[heading Preserving floating point registers]
+
+Preserving the floating point registers increases the cycle count for a context
+switch (see performance tests).
+The foruth argument of __jump_fcontext__ controls if fpu registers should be
+preserved by the context jump.
+
+[important The use of the fpu controling argument of __jump_fcontext__ must
+be consistent in the application. Otherwise the behaviour is undefined.]
+
+
+[heading Stack unwinding]
+
+Sometimes it is necessary to unwind the stack of an unfinished context to
+destroy local stack variables so they can release allocated resources (RAII
+pattern). The user is responsible for this task.
+
+
+[section:boost_fcontext Struct `fcontext_t` and related functions]
+
+ struct stack_t
+ {
+ void * base;
+ void * limit;
+ };
+
+ struct fcontext_t
+ {
+ < platform specific >
+
+ stack_t fc_stack;
+ };
+
+ intptr_t jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp);
+ void make_fcontext( fcontext_t * fc, void(* fn)(intptr_t) );
+
+[heading `base`]
+[variablelist
+[[Member:] [Pointer to the top of the stack.]]
+]
+
+[heading `limit`]
+[variablelist
+[[Member:] [Pointer to the bottom of the stack.]]
+]
+
+[heading `fc_stack`]
+[variablelist
+[[Member:] [Tracks the memory for the context's stack.]]
+]
+
+[heading `intptr_t jump_fcontext( fcontext_t * ofc, fcontext_t * nfc, intptr_t p, bool preserve_fpu)`]
+[variablelist
+[[Effects:] [Stores the current context data (stack pointer, instruction
+pointer, and CPU registers) to `*ofc` and restores the context data from `*nfc`,
+which implies jumping to `*nfc`'s execution context. The intptr_t argument, `p`,
+is passed to the current context to be returned by the most recent call to
+`jump_fcontext()` in the same thread. The last argument controls if fpu registers
+have to be preserved.]]
+[[Returns:] [The third pointer argument passed to the most recent call to
+`jump_fcontext()`, if any.]]
+]
+
+[heading `void make_fcontext( fcontext_t * fc, void(*fn)(intptr_t))`]
+[variablelist
+[[Precondition:] [A stack is applied to `*fc` before `make_fcontext()` is called.]]
+[[Effects:] [Modifies `*fc` in order to execute `fn` when the context is
+activated next.]]
+]
+
+[endsect]
+
+[endsect]
diff --git a/libs/context/doc/html/context/acknowledgements.html b/libs/context/doc/html/context/acknowledgements.html
new file mode 100644
index 0000000000..ac56768845
--- /dev/null
+++ b/libs/context/doc/html/context/acknowledgements.html
@@ -0,0 +1,48 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Acknowledgments</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="todo.html" title="Todo">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="todo.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.acknowledgements"></a><a class="link" href="acknowledgements.html" title="Acknowledgments">Acknowledgments</a>
+</h2></div></div></div>
+<p>
+ I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, Fernando Pelliccioni,
+ Giovanni Piero Deretta, Gordon Woodhull, Helge Bahmann, Holger Grund, Jeffrey
+ Lee Hellrung (Jr.), Keith Jeffery, Phil Endecott, Robert Stewart, Steven Watanabe,
+ Vicente J. Botet Escriba, Wayne Piekarski.
+ </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="todo.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/context.html b/libs/context/doc/html/context/context.html
new file mode 100644
index 0000000000..ae9591ea73
--- /dev/null
+++ b/libs/context/doc/html/context/context.html
@@ -0,0 +1,294 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Context</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="requirements.html" title="Requirements">
+<link rel="next" href="context/boost_fcontext.html" title="Struct fcontext_t and related functions">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="context/boost_fcontext.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.context"></a><a class="link" href="context.html" title="Context">Context</a>
+</h2></div></div></div>
+<div class="toc"><dl><dt><span class="section"><a href="context/boost_fcontext.html">Struct <code class="computeroutput"><span class="identifier">fcontext_t</span></code> and related functions</a></span></dt></dl></div>
+<p>
+ Each instance of <span class="emphasis"><em>fcontext_t</em></span> represents a context (CPU
+ registers and stack space). Together with its related functions <span class="emphasis"><em>jump_fcontext()</em></span>
+ and <span class="emphasis"><em>make_fcontext()</em></span> it provides a execution control transfer
+ mechanism similar interface like <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/getcontext.2.html" target="_top">ucontext_t</a>.
+ <span class="emphasis"><em>fcontext_t</em></span> and its functions are located in <span class="emphasis"><em>boost::ctx</em></span>
+ and the functions are declared as extern "C".
+ </p>
+<div class="warning"><table border="0" summary="Warning">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
+<th align="left">Warning</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ If <span class="emphasis"><em>fcontext_t</em></span> is used in a multithreaded application,
+ it can migrated between threads, but must not reference <span class="emphasis"><em>thread-local
+ storage</em></span>.
+ </p></td></tr>
+</table></div>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ If <span class="emphasis"><em>fiber-local storage</em></span> is used on Windows, the user
+ is responsible for calling <span class="emphasis"><em>::FlsAlloc()</em></span>, <span class="emphasis"><em>::FlsFree()</em></span>.
+ </p></td></tr>
+</table></div>
+<div class="important"><table border="0" summary="Important">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
+<th align="left">Important</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ The low level API is the part to port to new platforms.
+ </p></td></tr>
+</table></div>
+<h4>
+<a name="context.context.h0"></a>
+ <span><a name="context.context.executing_a_context"></a></span><a class="link" href="context.html#context.context.executing_a_context">Executing
+ a context</a>
+ </h4>
+<p>
+ A new context supposed to execute a <span class="emphasis"><em>context-function</em></span> (returning
+ void and accepting intptr_t as argument) must be initialized by function <span class="emphasis"><em>make_fcontext()</em></span>.
+ </p>
+<pre class="programlisting"><span class="comment">// context-function</span>
+<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span> <span class="identifier">intptr</span><span class="special">);</span>
+
+<span class="comment">// creates and manages a protected stack (with guard page)</span>
+<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">stack_allocator</span> <span class="identifier">alloc</span><span class="special">;</span>
+<span class="identifier">fc</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">base</span> <span class="special">=</span> <span class="identifier">alloc</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">minimum_stacksize</span><span class="special">());</span>
+<span class="identifier">fc</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">limit</span> <span class="special">=</span>
+ <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">char</span> <span class="special">*</span> <span class="special">&gt;(</span> <span class="identifier">fc</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">base</span><span class="special">)</span> <span class="special">-</span> <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">minimum_stacksize</span><span class="special">();</span>
+
+<span class="comment">// context fc uses f() as context function</span>
+<span class="identifier">make_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span>
+</pre>
+<p>
+ <span class="emphasis"><em>fcontext_t</em></span> requires a pointer to the top of the stack
+ (<span class="emphasis"><em>fc_base</em></span>) as well as a pointer to the lower bound of the
+ stack (<span class="emphasis"><em>fc_limit</em></span>).
+ </p>
+<p>
+ Calling <span class="emphasis"><em>jump_fcontext()</em></span> invokes the <span class="emphasis"><em>context-function</em></span>
+ in a newly created context complete with registers, flags, stack and instruction
+ pointers. When control should be returned to the original calling context,
+ call <span class="emphasis"><em>jump_fcontext()</em></span>. The current context information
+ (registers, flags, and stack and instruction pointers) is saved and the original
+ context information is restored. Calling <span class="emphasis"><em>jump_fcontext()</em></span>
+ again resumes execution in the second context after saving the new state of
+ the original context.
+ </p>
+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ctx</span><span class="special">;</span>
+
+<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fcontext_t</span> <span class="identifier">fcm</span><span class="special">,</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="identifier">fc2</span><span class="special">;</span>
+
+<span class="keyword">void</span> <span class="identifier">f1</span><span class="special">(</span> <span class="identifier">intptr_t</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: call jump_fcontext( &amp; fc1, &amp; fc2, 0)"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fc2</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: return"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fcm</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
+<span class="special">}</span>
+
+<span class="keyword">void</span> <span class="identifier">f2</span><span class="special">(</span> <span class="identifier">intptr_t</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f2: entered"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f2: call jump_fcontext( &amp; fc2, &amp; fc1, 0)"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc2</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
+ <span class="identifier">BOOST_ASSERT</span><span class="special">(</span> <span class="keyword">false</span> <span class="special">&amp;&amp;</span> <span class="special">!</span> <span class="string">"f2: never returns"</span><span class="special">);</span>
+<span class="special">}</span>
+
+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span> <span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span>
+<span class="special">{</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">stack_allocator</span> <span class="identifier">alloc1</span><span class="special">,</span> <span class="identifier">alloc2</span><span class="special">;</span>
+
+ <span class="identifier">fc1</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">base</span> <span class="special">=</span> <span class="identifier">alloc1</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">minimum_stacksize</span><span class="special">());</span>
+ <span class="identifier">fc1</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">limit</span> <span class="special">=</span>
+ <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">char</span> <span class="special">*</span> <span class="special">&gt;(</span> <span class="identifier">fc1</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">base</span><span class="special">)</span> <span class="special">-</span> <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">minimum_stacksize</span><span class="special">();</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">make_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span>
+
+ <span class="identifier">fc2</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">base</span> <span class="special">=</span> <span class="identifier">alloc2</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">minimum_stacksize</span><span class="special">());</span>
+ <span class="identifier">fc2</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">limit</span> <span class="special">=</span>
+ <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">char</span> <span class="special">*</span> <span class="special">&gt;(</span> <span class="identifier">fc2</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">base</span><span class="special">)</span> <span class="special">-</span> <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">minimum_stacksize</span><span class="special">();</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">make_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc2</span><span class="special">,</span> <span class="identifier">f2</span><span class="special">);</span>
+
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"main: call jump_fcontext( &amp; fcm, &amp; fc1, 0)"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fcm</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
+
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"main: done"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+
+ <span class="keyword">return</span> <span class="identifier">EXIT_SUCCESS</span><span class="special">;</span>
+<span class="special">}</span>
+
+<span class="identifier">output</span><span class="special">:</span>
+ <span class="identifier">main</span><span class="special">:</span> <span class="identifier">call</span> <span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fcm</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span>
+ <span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span>
+ <span class="identifier">f1</span><span class="special">:</span> <span class="identifier">call</span> <span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fc2</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span>
+ <span class="identifier">f2</span><span class="special">:</span> <span class="identifier">entered</span>
+ <span class="identifier">f2</span><span class="special">:</span> <span class="identifier">call</span> <span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc2</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span>
+ <span class="identifier">f1</span><span class="special">:</span> <span class="keyword">return</span>
+ <span class="identifier">main</span><span class="special">:</span> <span class="identifier">done</span>
+</pre>
+<p>
+ First call of <span class="emphasis"><em>jump_fcontext()</em></span> enters the <span class="emphasis"><em>context-function</em></span>
+ <code class="computeroutput"><span class="identifier">f1</span><span class="special">()</span></code>
+ by starting context fc1 (context fcm saves the registers of <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code>). For jumping between context's fc1 and fc2
+ <code class="computeroutput"><span class="identifier">jump_fcontext</span><span class="special">()</span></code>
+ is called. Because context fcm is chained to fc1, <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code> is entered (returning from <span class="emphasis"><em>jump_fcontext()</em></span>)
+ after context fc1 becomes complete (return from <code class="computeroutput"><span class="identifier">f1</span><span class="special">()</span></code>).
+ </p>
+<div class="warning"><table border="0" summary="Warning">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
+<th align="left">Warning</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ Calling <span class="emphasis"><em>jump_fcontext()</em></span> to the same context from inside
+ the same context results in undefined behaviour.
+ </p></td></tr>
+</table></div>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ In contrast to threads, which are preemtive, <span class="emphasis"><em>fcontext_t</em></span>
+ switches are cooperative (programmer controls when switch will happen). The
+ kernel is not involved in the context switches.
+ </p></td></tr>
+</table></div>
+<h4>
+<a name="context.context.h1"></a>
+ <span><a name="context.context.transfer_of_data"></a></span><a class="link" href="context.html#context.context.transfer_of_data">Transfer
+ of data</a>
+ </h4>
+<p>
+ The third argument passed to <span class="emphasis"><em>jump_fcontext()</em></span>, in one context,
+ is passed as the first argument of the <span class="emphasis"><em>context-function</em></span>
+ if the context is started for the first time. In all following invocations
+ of <span class="emphasis"><em>jump_fcontext()</em></span> the intptr_t passed to <span class="emphasis"><em>jump_fcontext()</em></span>,
+ in one context, is returned by <span class="emphasis"><em>jump_fcontext()</em></span> in the
+ other context.
+ </p>
+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ctx</span><span class="special">;</span>
+
+<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fcontext_t</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="identifier">fcm</span><span class="special">;</span>
+
+<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">pair_t</span><span class="special">;</span>
+
+<span class="keyword">void</span> <span class="identifier">f1</span><span class="special">(</span> <span class="identifier">intptr_t</span> <span class="identifier">param</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">pair_t</span> <span class="special">*</span> <span class="identifier">p</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">pair_t</span> <span class="special">*)</span> <span class="identifier">param</span><span class="special">;</span>
+
+ <span class="identifier">p</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">pair_t</span> <span class="special">*)</span> <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fcm</span><span class="special">,</span> <span class="special">(</span> <span class="identifier">intptr_t</span><span class="special">)</span> <span class="special">(</span> <span class="identifier">p</span><span class="special">-&gt;</span><span class="identifier">first</span> <span class="special">+</span> <span class="identifier">p</span><span class="special">-&gt;</span><span class="identifier">second</span><span class="special">)</span> <span class="special">);</span>
+
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fcm</span><span class="special">,</span> <span class="special">(</span> <span class="identifier">intptr_t</span><span class="special">)</span> <span class="special">(</span> <span class="identifier">p</span><span class="special">-&gt;</span><span class="identifier">first</span> <span class="special">+</span> <span class="identifier">p</span><span class="special">-&gt;</span><span class="identifier">second</span><span class="special">)</span> <span class="special">);</span>
+<span class="special">}</span>
+
+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span> <span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span>
+<span class="special">{</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">stack_allocator</span> <span class="identifier">alloc</span><span class="special">;</span>
+
+ <span class="identifier">fc1</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">base</span> <span class="special">=</span> <span class="identifier">alloc</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">minimum_stacksize</span><span class="special">());</span>
+ <span class="identifier">fc1</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">limit</span> <span class="special">=</span>
+ <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">char</span> <span class="special">*</span> <span class="special">&gt;(</span> <span class="identifier">fc1</span><span class="special">.</span><span class="identifier">fc_stack</span><span class="special">.</span><span class="identifier">base</span><span class="special">)</span> <span class="special">-</span> <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">minimum_stacksize</span><span class="special">();</span>
+ <span class="identifier">fc1</span><span class="special">.</span><span class="identifier">fc_link</span> <span class="special">=</span> <span class="special">&amp;</span> <span class="identifier">fcm</span><span class="special">;</span>
+ <span class="identifier">pair_t</span> <span class="identifier">p</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span> <span class="number">2</span><span class="special">,</span> <span class="number">7</span><span class="special">)</span> <span class="special">);</span>
+ <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">make_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span>
+
+ <span class="keyword">int</span> <span class="identifier">res</span> <span class="special">=</span> <span class="special">(</span> <span class="keyword">int</span><span class="special">)</span> <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fcm</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="special">(</span> <span class="identifier">intptr_t</span><span class="special">)</span> <span class="special">&amp;</span> <span class="identifier">p</span><span class="special">);</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">" + "</span> <span class="special">&lt;&lt;</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">second</span> <span class="special">&lt;&lt;</span> <span class="string">" == "</span> <span class="special">&lt;&lt;</span> <span class="identifier">res</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+
+ <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">);</span>
+ <span class="identifier">res</span> <span class="special">=</span> <span class="special">(</span> <span class="keyword">int</span><span class="special">)</span> <span class="identifier">ctx</span><span class="special">::</span><span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">fcm</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">fc1</span><span class="special">,</span> <span class="special">(</span> <span class="identifier">intptr_t</span><span class="special">)</span> <span class="special">&amp;</span> <span class="identifier">p</span><span class="special">);</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">first</span> <span class="special">&lt;&lt;</span> <span class="string">" + "</span> <span class="special">&lt;&lt;</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">second</span> <span class="special">&lt;&lt;</span> <span class="string">" == "</span> <span class="special">&lt;&lt;</span> <span class="identifier">res</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"main: done"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+
+ <span class="keyword">return</span> <span class="identifier">EXIT_SUCCESS</span><span class="special">;</span>
+<span class="special">}</span>
+
+<span class="identifier">output</span><span class="special">:</span>
+ <span class="number">2</span> <span class="special">+</span> <span class="number">7</span> <span class="special">==</span> <span class="number">9</span>
+ <span class="number">5</span> <span class="special">+</span> <span class="number">6</span> <span class="special">==</span> <span class="number">11</span>
+ <span class="identifier">main</span><span class="special">:</span> <span class="identifier">done</span>
+</pre>
+<h4>
+<a name="context.context.h2"></a>
+ <span><a name="context.context.exceptions_in__emphasis_context_function__emphasis_"></a></span><a class="link" href="context.html#context.context.exceptions_in__emphasis_context_function__emphasis_">Exceptions
+ in <span class="emphasis"><em>context-function</em></span></a>
+ </h4>
+<p>
+ If the <span class="emphasis"><em>context-function</em></span> emits an exception, the application
+ will terminate.
+ </p>
+<h4>
+<a name="context.context.h3"></a>
+ <span><a name="context.context.preserving_floating_point_registers"></a></span><a class="link" href="context.html#context.context.preserving_floating_point_registers">Preserving
+ floating point registers</a>
+ </h4>
+<p>
+ Preserving the floating point registers increases the cycle count for a context
+ switch (see performance tests). The foruth argument of <span class="emphasis"><em>jump_fcontext()</em></span>
+ controls if fpu registers should be preserved by the context jump.
+ </p>
+<div class="important"><table border="0" summary="Important">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
+<th align="left">Important</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ The use of the fpu controling argument of <span class="emphasis"><em>jump_fcontext()</em></span>
+ must be consistent in the application. Otherwise the behaviour is undefined.
+ </p></td></tr>
+</table></div>
+<h4>
+<a name="context.context.h4"></a>
+ <span><a name="context.context.stack_unwinding"></a></span><a class="link" href="context.html#context.context.stack_unwinding">Stack
+ unwinding</a>
+ </h4>
+<p>
+ Sometimes it is necessary to unwind the stack of an unfinished context to destroy
+ local stack variables so they can release allocated resources (RAII pattern).
+ The user is responsible for this task.
+ </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="context/boost_fcontext.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/context/boost_fcontext.html b/libs/context/doc/html/context/context/boost_fcontext.html
new file mode 100644
index 0000000000..fad862482b
--- /dev/null
+++ b/libs/context/doc/html/context/context/boost_fcontext.html
@@ -0,0 +1,146 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Struct fcontext_t and related functions</title>
+<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../../index.html" title="Context">
+<link rel="up" href="../context.html" title="Context">
+<link rel="prev" href="../context.html" title="Context">
+<link rel="next" href="../stack.html" title="Stack allocation">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../context.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../context.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../stack.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="context.context.boost_fcontext"></a><a class="link" href="boost_fcontext.html" title="Struct fcontext_t and related functions">Struct <code class="computeroutput"><span class="identifier">fcontext_t</span></code> and related functions</a>
+</h3></div></div></div>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">stack_t</span>
+<span class="special">{</span>
+ <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">base</span><span class="special">;</span>
+ <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">limit</span><span class="special">;</span>
+<span class="special">};</span>
+
+<span class="keyword">struct</span> <span class="identifier">fcontext_t</span>
+<span class="special">{</span>
+ <span class="special">&lt;</span> <span class="identifier">platform</span> <span class="identifier">specific</span> <span class="special">&gt;</span>
+
+ <span class="identifier">stack_t</span> <span class="identifier">fc_stack</span><span class="special">;</span>
+<span class="special">};</span>
+
+<span class="identifier">intptr_t</span> <span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="identifier">fcontext_t</span> <span class="special">*</span> <span class="identifier">ofc</span><span class="special">,</span> <span class="identifier">fcontext_t</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">nfc</span><span class="special">,</span> <span class="identifier">intptr_t</span> <span class="identifier">vp</span><span class="special">);</span>
+<span class="keyword">void</span> <span class="identifier">make_fcontext</span><span class="special">(</span> <span class="identifier">fcontext_t</span> <span class="special">*</span> <span class="identifier">fc</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(*</span> <span class="identifier">fn</span><span class="special">)(</span><span class="identifier">intptr_t</span><span class="special">)</span> <span class="special">);</span>
+</pre>
+<h5>
+<a name="context.context.boost_fcontext.h0"></a>
+ <span><a name="context.context.boost_fcontext._code__phrase_role__identifier__base__phrase___code_"></a></span><a class="link" href="boost_fcontext.html#context.context.boost_fcontext._code__phrase_role__identifier__base__phrase___code_"><code class="computeroutput"><span class="identifier">base</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Member:</span></dt>
+<dd><p>
+ Pointer to the top of the stack.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.context.boost_fcontext.h1"></a>
+ <span><a name="context.context.boost_fcontext._code__phrase_role__identifier__limit__phrase___code_"></a></span><a class="link" href="boost_fcontext.html#context.context.boost_fcontext._code__phrase_role__identifier__limit__phrase___code_"><code class="computeroutput"><span class="identifier">limit</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Member:</span></dt>
+<dd><p>
+ Pointer to the bottom of the stack.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.context.boost_fcontext.h2"></a>
+ <span><a name="context.context.boost_fcontext._code__phrase_role__identifier__fc_stack__phrase___code_"></a></span><a class="link" href="boost_fcontext.html#context.context.boost_fcontext._code__phrase_role__identifier__fc_stack__phrase___code_"><code class="computeroutput"><span class="identifier">fc_stack</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Member:</span></dt>
+<dd><p>
+ Tracks the memory for the context's stack.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.context.boost_fcontext.h3"></a>
+ <span><a name="context.context.boost_fcontext._code__phrase_role__identifier__intptr_t__phrase___phrase_role__identifier__jump_fcontext__phrase__phrase_role__special_____phrase___phrase_role__identifier__fcontext_t__phrase___phrase_role__special_____phrase___phrase_role__identifier__ofc__phrase__phrase_role__special_____phrase___phrase_role__identifier__fcontext_t__phrase___phrase_role__special_____phrase___phrase_role__identifier__nfc__phrase__phrase_role__special_____phrase___phrase_role__identifier__intptr_t__phrase___phrase_role__identifier__p__phrase__phrase_role__special_____phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__preserve_fpu__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="boost_fcontext.html#context.context.boost_fcontext._code__phrase_role__identifier__intptr_t__phrase___phrase_role__identifier__jump_fcontext__phrase__phrase_role__special_____phrase___phrase_role__identifier__fcontext_t__phrase___phrase_role__special_____phrase___phrase_role__identifier__ofc__phrase__phrase_role__special_____phrase___phrase_role__identifier__fcontext_t__phrase___phrase_role__special_____phrase___phrase_role__identifier__nfc__phrase__phrase_role__special_____phrase___phrase_role__identifier__intptr_t__phrase___phrase_role__identifier__p__phrase__phrase_role__special_____phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__preserve_fpu__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="identifier">intptr_t</span> <span class="identifier">jump_fcontext</span><span class="special">(</span> <span class="identifier">fcontext_t</span>
+ <span class="special">*</span> <span class="identifier">ofc</span><span class="special">,</span> <span class="identifier">fcontext_t</span>
+ <span class="special">*</span> <span class="identifier">nfc</span><span class="special">,</span> <span class="identifier">intptr_t</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">bool</span>
+ <span class="identifier">preserve_fpu</span><span class="special">)</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Effects:</span></dt>
+<dd><p>
+ Stores the current context data (stack pointer, instruction pointer,
+ and CPU registers) to <code class="computeroutput"><span class="special">*</span><span class="identifier">ofc</span></code> and restores the context data
+ from <code class="computeroutput"><span class="special">*</span><span class="identifier">nfc</span></code>,
+ which implies jumping to <code class="computeroutput"><span class="special">*</span><span class="identifier">nfc</span></code>'s execution context. The intptr_t
+ argument, <code class="computeroutput"><span class="identifier">p</span></code>, is passed
+ to the current context to be returned by the most recent call to <code class="computeroutput"><span class="identifier">jump_fcontext</span><span class="special">()</span></code>
+ in the same thread. The last argument controls if fpu registers have
+ to be preserved.
+ </p></dd>
+<dt><span class="term">Returns:</span></dt>
+<dd><p>
+ The third pointer argument passed to the most recent call to <code class="computeroutput"><span class="identifier">jump_fcontext</span><span class="special">()</span></code>,
+ if any.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.context.boost_fcontext.h4"></a>
+ <span><a name="context.context.boost_fcontext._code__phrase_role__keyword__void__phrase___phrase_role__identifier__make_fcontext__phrase__phrase_role__special_____phrase___phrase_role__identifier__fcontext_t__phrase___phrase_role__special_____phrase___phrase_role__identifier__fc__phrase__phrase_role__special_____phrase___phrase_role__keyword__void__phrase__phrase_role__special______phrase__phrase_role__identifier__fn__phrase__phrase_role__special______phrase__phrase_role__identifier__intptr_t__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="boost_fcontext.html#context.context.boost_fcontext._code__phrase_role__keyword__void__phrase___phrase_role__identifier__make_fcontext__phrase__phrase_role__special_____phrase___phrase_role__identifier__fcontext_t__phrase___phrase_role__special_____phrase___phrase_role__identifier__fc__phrase__phrase_role__special_____phrase___phrase_role__keyword__void__phrase__phrase_role__special______phrase__phrase_role__identifier__fn__phrase__phrase_role__special______phrase__phrase_role__identifier__intptr_t__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="identifier">make_fcontext</span><span class="special">(</span> <span class="identifier">fcontext_t</span>
+ <span class="special">*</span> <span class="identifier">fc</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(*</span><span class="identifier">fn</span><span class="special">)(</span><span class="identifier">intptr_t</span><span class="special">))</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Precondition:</span></dt>
+<dd><p>
+ A stack is applied to <code class="computeroutput"><span class="special">*</span><span class="identifier">fc</span></code> before <code class="computeroutput"><span class="identifier">make_fcontext</span><span class="special">()</span></code> is called.
+ </p></dd>
+<dt><span class="term">Effects:</span></dt>
+<dd><p>
+ Modifies <code class="computeroutput"><span class="special">*</span><span class="identifier">fc</span></code>
+ in order to execute <code class="computeroutput"><span class="identifier">fn</span></code>
+ when the context is activated next.
+ </p></dd>
+</dl>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../context.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../context.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../stack.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/overview.html b/libs/context/doc/html/context/overview.html
new file mode 100644
index 0000000000..a6bc1f609d
--- /dev/null
+++ b/libs/context/doc/html/context/overview.html
@@ -0,0 +1,83 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Overview</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="../index.html" title="Context">
+<link rel="next" href="requirements.html" title="Requirements">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="requirements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.overview"></a><a class="link" href="overview.html" title="Overview">Overview</a>
+</h2></div></div></div>
+<p>
+ <span class="bold"><strong>Boost.Context</strong></span> is a foundational library that
+ provides a sort of cooperative multitasking on a single thread. By providing
+ an abstraction of the current execution state in the current thread, including
+ the stack (with local variables) and stack pointer, all registers and CPU flags,
+ and the instruction pointer, a <span class="emphasis"><em>fcontext_t</em></span> instance represents
+ a specific point in the application's execution path. This is useful for building
+ higher-level abstractions, like <span class="emphasis"><em>coroutines</em></span>, <span class="emphasis"><em>cooperative
+ threads (userland threads)</em></span> or an aquivalent to <a href="http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx" target="_top">C#
+ keyword <span class="emphasis"><em>yield</em></span></a> in C++.
+ </p>
+<p>
+ A <span class="emphasis"><em>fcontext_t</em></span> provides the means to suspend the current
+ execution path and to transfer execution control, thereby permitting another
+ <span class="emphasis"><em>fcontext_t</em></span> to run on the current thread. This stateful
+ transfer mechanism enables a <span class="emphasis"><em>fcontext_t</em></span> to suspend execution
+ from within nested functions and, later, to resume from where it was suspended.
+ While the execution path represented by a <span class="emphasis"><em>fcontext_t</em></span> only
+ runs on a single thread, it can be migrated to another thread at any given
+ time.
+ </p>
+<p>
+ A context switch between threads requires system calls (involving the OS kernel),
+ which can cost more than thousand CPU cycles on x86 CPUs. By contrast, transferring
+ control among them requires only fewer than hundred CPU cycles because it does
+ not involve system calls as it is done within a single thread.
+ </p>
+<p>
+ In order to use the classes and functions described here, you can either include
+ the specific headers specified by the descriptions of each class or function,
+ or include the master library header:
+ </p>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">all</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
+</pre>
+<p>
+ which includes all the other headers in turn.
+ </p>
+<p>
+ All functions and classes are contained in the namespace <span class="emphasis"><em>boost::ctx</em></span>.
+ </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="requirements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/performance.html b/libs/context/doc/html/context/performance.html
new file mode 100644
index 0000000000..8bdddcbe68
--- /dev/null
+++ b/libs/context/doc/html/context/performance.html
@@ -0,0 +1,152 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Performance</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="stack/stack_helper.html" title="Helper functions">
+<link rel="next" href="tested.html" title="Tested Platforms">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="stack/stack_helper.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tested.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.performance"></a><a class="link" href="performance.html" title="Performance">Performance</a>
+</h2></div></div></div>
+<p>
+ Performance of <span class="bold"><strong>Boost.Context</strong></span> was measured
+ on the platforms shown in the following table. Performance measurements were
+ taken using <code class="computeroutput"><span class="identifier">rdtsc</span></code>, with overhead
+ corrections, on x86 platforms. In each case, stack protection was active, cache
+ warm-up was accounted for, and the one running thread was pinned to a single
+ CPU. The code was compiled using the build options, 'variant = release cxxflags
+ = -DBOOST_DISABLE_ASSERTS'.
+ </p>
+<p>
+ The numbers in the table are the number of cycles per iteration, based upon
+ an average computed over 10 iterations.
+ </p>
+<div class="table">
+<a name="context.performance.t0"></a><p class="title"><b>Table&#160;1.&#160;Perfomance of context switch</b></p>
+<div class="table-contents"><table class="table" summary="Perfomance of context switch">
+<colgroup>
+<col>
+<col>
+<col>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ Platform
+ </p>
+ </th>
+<th>
+ <p>
+ ucontext_t
+ </p>
+ </th>
+<th>
+ <p>
+ fcontext_t with fpu
+ </p>
+ </th>
+<th>
+ <p>
+ fcontext_t without fpu
+ </p>
+ </th>
+<th>
+ <p>
+ boost::function
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ AMD Athlon 64 DualCore 4400+ (32bit Linux)
+ </p>
+ </td>
+<td>
+ <p>
+ 846 cycles
+ </p>
+ </td>
+<td>
+ <p>
+ 65 cycles
+ </p>
+ </td>
+<td>
+ <p>
+ 46 cycles
+ </p>
+ </td>
+<td>
+ <p>
+ 43 cycles
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ Intel Core2 Q6700 (64bit Linux)
+ </p>
+ </td>
+<td>
+ <p>
+ 1472 cycles
+ </p>
+ </td>
+<td>
+ <p>
+ 172 cycles
+ </p>
+ </td>
+<td>
+ <p>
+ 63 cycles
+ </p>
+ </td>
+<td>
+ <p>
+ 60 cycles
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<br class="table-break">
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="stack/stack_helper.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tested.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/rationale.html b/libs/context/doc/html/context/rationale.html
new file mode 100644
index 0000000000..4b85082379
--- /dev/null
+++ b/libs/context/doc/html/context/rationale.html
@@ -0,0 +1,104 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Rationale</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="tested.html" title="Tested Platforms">
+<link rel="next" href="rationale/other_apis_.html" title="Other APIs">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tested.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rationale/other_apis_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.rationale"></a><a class="link" href="rationale.html" title="Rationale">Rationale</a>
+</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section"><a href="rationale/other_apis_.html">Other APIs </a></span></dt>
+<dt><span class="section"><a href="rationale/x86_and_floating_point_env.html">x86 and
+ floating-point env</a></span></dt>
+</dl></div>
+<h4>
+<a name="context.rationale.h0"></a>
+ <span><a name="context.rationale.no_inline_assembler"></a></span><a class="link" href="rationale.html#context.rationale.no_inline_assembler">No
+ inline-assembler</a>
+ </h4>
+<p>
+ Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support
+ inline assembler. <sup>[<a name="context.rationale.f0" href="#ftn.context.rationale.f0" class="footnote">1</a>]</sup>.
+ </p>
+<h4>
+<a name="context.rationale.h1"></a>
+ <span><a name="context.rationale.fcontext_t"></a></span><a class="link" href="rationale.html#context.rationale.fcontext_t">fcontext_t</a>
+ </h4>
+<p>
+ <span class="bold"><strong>Boost.Context</strong></span> provides the low level API fcontext_t
+ which is implemented in assembler to provide context swapping operations. fcontext_t
+ is the part to port to new platforms.
+ </p>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ Context switches do not preserve the signal mask on UNIX systems.
+ </p></td></tr>
+</table></div>
+<p>
+ Because the assembler code uses the byte layout of <span class="emphasis"><em>fcontext_t</em></span>
+ to access its members <span class="emphasis"><em>fcontext_t</em></span> must be a POD. This requires
+ that <span class="emphasis"><em>fcontext_t</em></span> has only a default constructor, no visibility
+ keywords (e.g. private, public, protected), no virtual methods and all members
+ and base clases are PODs too.
+ </p>
+<h4>
+<a name="context.rationale.h2"></a>
+ <span><a name="context.rationale.protecting_the_stack"></a></span><a class="link" href="rationale.html#context.rationale.protecting_the_stack">Protecting
+ the stack</a>
+ </h4>
+<p>
+ Because the stack's size is fixed -- there is no support for split stacks yet
+ -- it is important to protect against exceeding the stack's bounds. Otherwise,
+ in the best case, overrunning the stack's memory will result in a segmentation
+ fault or access violation and, in the worst case, the application's memory
+ will be overwritten. <code class="computeroutput"><span class="identifier">stack_allocator</span></code>
+ appends a guard page to the stack to help detect overruns. The guard page consumes
+ no physical memory, but generates a segmentation fault or access violation
+ on access to the virtual memory addresses within it.
+ </p>
+<div class="footnotes">
+<br><hr width="100" align="left">
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.f0" href="#context.rationale.f0" class="para">1</a>] </sup>
+ <a href="http://msdn.microsoft.com/en-us/library/4ks26t93.aspx" target="_top">MSDN article
+ 'Inline Assembler'</a>
+ </p></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tested.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rationale/other_apis_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/rationale/other_apis_.html b/libs/context/doc/html/context/rationale/other_apis_.html
new file mode 100644
index 0000000000..f86669a1e0
--- /dev/null
+++ b/libs/context/doc/html/context/rationale/other_apis_.html
@@ -0,0 +1,117 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Other APIs</title>
+<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../../index.html" title="Context">
+<link rel="up" href="../rationale.html" title="Rationale">
+<link rel="prev" href="../rationale.html" title="Rationale">
+<link rel="next" href="x86_and_floating_point_env.html" title="x86 and floating-point env">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../rationale.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="x86_and_floating_point_env.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="context.rationale.other_apis_"></a><a class="link" href="other_apis_.html" title="Other APIs">Other APIs </a>
+</h3></div></div></div>
+<h5>
+<a name="context.rationale.other_apis_.h0"></a>
+ <span><a name="context.rationale.other_apis_.setjmp___longjmp__"></a></span><a class="link" href="other_apis_.html#context.rationale.other_apis_.setjmp___longjmp__">setjmp()/longjmp()</a>
+ </h5>
+<p>
+ C99 defines <code class="computeroutput"><span class="identifier">setjmp</span><span class="special">()</span></code>/<code class="computeroutput"><span class="identifier">longjmp</span><span class="special">()</span></code>
+ to provide non-local jumps but it does not require that <span class="emphasis"><em>longjmp()</em></span>
+ preserves the current stack frame. Therefore, jumping into a function which
+ was exited via a call to <span class="emphasis"><em>longjmp()</em></span> is undefined <sup>[<a name="context.rationale.other_apis_.f0" href="#ftn.context.rationale.other_apis_.f0" class="footnote">2</a>]</sup>.
+ </p>
+<h5>
+<a name="context.rationale.other_apis_.h1"></a>
+ <span><a name="context.rationale.other_apis_.ucontext_t"></a></span><a class="link" href="other_apis_.html#context.rationale.other_apis_.ucontext_t">ucontext_t</a>
+ </h5>
+<p>
+ Since POSIX.1-2003 <code class="computeroutput"><span class="identifier">ucontext_t</span></code>
+ is deprecated and was removed in POSIX.1-2008! The function signature of
+ <code class="computeroutput"><span class="identifier">makecontext</span><span class="special">()</span></code>
+ is:
+ </p>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">makecontext</span><span class="special">(</span><span class="identifier">ucontext_t</span> <span class="special">*</span><span class="identifier">ucp</span><span class="special">,</span> <span class="keyword">void</span> <span class="special">(*</span><span class="identifier">func</span><span class="special">)(),</span> <span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="special">...);</span>
+</pre>
+<p>
+ The third argument of <code class="computeroutput"><span class="identifier">makecontext</span><span class="special">()</span></code> specifies the number of integer arguments
+ that follow which will require function pointer cast if <code class="computeroutput"><span class="identifier">func</span></code>
+ will accept those arguments which is undefined in C99 <sup>[<a name="context.rationale.other_apis_.f1" href="#ftn.context.rationale.other_apis_.f1" class="footnote">3</a>]</sup>.
+ </p>
+<p>
+ The arguments in the var-arg list are required to be integers, passing pointers
+ in var-arg list is not guarantied to work, especially it will fail for architectures
+ where pointers are larger than integers.
+ </p>
+<p>
+ <code class="computeroutput"><span class="identifier">ucontext_t</span></code> preserves signal
+ mask between context switches which involes system calls consuming a lot
+ of CPU cycles (ucontext_t is slower by perfomance_link[factor 13x] relative
+ to <code class="computeroutput"><span class="identifier">fcontext_t</span></code>).
+ </p>
+<h5>
+<a name="context.rationale.other_apis_.h2"></a>
+ <span><a name="context.rationale.other_apis_.windows_fibers"></a></span><a class="link" href="other_apis_.html#context.rationale.other_apis_.windows_fibers">Windows
+ fibers</a>
+ </h5>
+<p>
+ A drawback of Windows Fiber API is that <code class="computeroutput"><span class="identifier">CreateFiber</span><span class="special">()</span></code> does not accept a pointer to user allocated
+ stack space preventing the reuse of stacks for other context instances. Because
+ the Windows Fiber API requires to call <code class="computeroutput"><span class="identifier">ConvertThreadToFiber</span><span class="special">()</span></code> if <code class="computeroutput"><span class="identifier">SwitchFiber</span><span class="special">()</span></code> is called for a thread which has not been
+ converted to a fiber. For the same reason <code class="computeroutput"><span class="identifier">ConvertFiberToThread</span><span class="special">()</span></code> must be called after return from <code class="computeroutput"><span class="identifier">SwitchFiber</span><span class="special">()</span></code>
+ if the thread was forced to be converted to a fiber before (which is inefficient).
+ </p>
+<pre class="programlisting"><span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">is_a_fiber</span><span class="special">()</span> <span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">ConvertThreadToFiber</span><span class="special">(</span> <span class="number">0</span><span class="special">);</span>
+ <span class="identifier">SwitchToFiber</span><span class="special">(</span> <span class="identifier">ctx</span><span class="special">);</span>
+ <span class="identifier">ConvertFiberToThread</span><span class="special">();</span>
+<span class="special">}</span>
+</pre>
+<p>
+ If the condition <code class="computeroutput"><span class="identifier">_WIN32_WINNT</span> <span class="special">&gt;=</span> <span class="identifier">_WIN32_WINNT_VISTA</span></code>
+ is met function <code class="computeroutput"><span class="identifier">IsThreadAFiber</span><span class="special">()</span></code> is provided in order to detect if the current
+ thread was already converted. Unfortunately Windows XP + SP 2/3 defines
+ <code class="computeroutput"><span class="identifier">_WIN32_WINNT</span> <span class="special">&gt;=</span>
+ <span class="identifier">_WIN32_WINNT_VISTA</span></code> without providing
+ <code class="computeroutput"><span class="identifier">IsThreadAFiber</span><span class="special">()</span></code>.
+ </p>
+<div class="footnotes">
+<br><hr width="100" align="left">
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.other_apis_.f0" href="#context.rationale.other_apis_.f0" class="para">2</a>] </sup>
+ ISO/IEC 9899:1999, 2005, 7.13.2.1:2
+ </p></div>
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.other_apis_.f1" href="#context.rationale.other_apis_.f1" class="para">3</a>] </sup>
+ ISO/IEC 9899:1999, 2005, J.2
+ </p></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../rationale.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="x86_and_floating_point_env.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/rationale/x86_and_floating_point_env.html b/libs/context/doc/html/context/rationale/x86_and_floating_point_env.html
new file mode 100644
index 0000000000..a2118af85c
--- /dev/null
+++ b/libs/context/doc/html/context/rationale/x86_and_floating_point_env.html
@@ -0,0 +1,124 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>x86 and floating-point env</title>
+<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../../index.html" title="Context">
+<link rel="up" href="../rationale.html" title="Rationale">
+<link rel="prev" href="other_apis_.html" title="Other APIs">
+<link rel="next" href="../reference.html" title="Reference">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="other_apis_.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="context.rationale.x86_and_floating_point_env"></a><a class="link" href="x86_and_floating_point_env.html" title="x86 and floating-point env">x86 and
+ floating-point env</a>
+</h3></div></div></div>
+<h5>
+<a name="context.rationale.x86_and_floating_point_env.h0"></a>
+ <span><a name="context.rationale.x86_and_floating_point_env.i386"></a></span><a class="link" href="x86_and_floating_point_env.html#context.rationale.x86_and_floating_point_env.i386">i386</a>
+ </h5>
+<p>
+ "The FpCsr and the MxCsr register must be saved and restored before
+ any call or return by any procedure that needs to modify them ..."
+ <sup>[<a name="context.rationale.x86_and_floating_point_env.f0" href="#ftn.context.rationale.x86_and_floating_point_env.f0" class="footnote">4</a>]</sup>.
+ </p>
+<h5>
+<a name="context.rationale.x86_and_floating_point_env.h1"></a>
+ <span><a name="context.rationale.x86_and_floating_point_env.x86_64"></a></span><a class="link" href="x86_and_floating_point_env.html#context.rationale.x86_and_floating_point_env.x86_64">x86_64</a>
+ </h5>
+<h5>
+<a name="context.rationale.x86_and_floating_point_env.h2"></a>
+ <span><a name="context.rationale.x86_and_floating_point_env.windows"></a></span><a class="link" href="x86_and_floating_point_env.html#context.rationale.x86_and_floating_point_env.windows">Windows</a>
+ </h5>
+<p>
+ MxCsr - "A callee that modifies any of the nonvolatile fields within
+ MxCsr must restore them before returning to its caller. Furthermore, a caller
+ that has modified any of these fields must restore them to their standard
+ values before invoking a callee ..." <sup>[<a name="context.rationale.x86_and_floating_point_env.f1" href="#ftn.context.rationale.x86_and_floating_point_env.f1" class="footnote">5</a>]</sup>.
+ </p>
+<p>
+ FpCsr - "A callee that modifies any of the fields within FpCsr must
+ restore them before returning to its caller. Furthermore, a caller that has
+ modified any of these fields must restore them to their standard values before
+ invoking a callee ..." <sup>[<a name="context.rationale.x86_and_floating_point_env.f2" href="#ftn.context.rationale.x86_and_floating_point_env.f2" class="footnote">6</a>]</sup>.
+ </p>
+<p>
+ "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved
+ across context switches. There is no explicit calling convention for these
+ registers." <sup>[<a name="context.rationale.x86_and_floating_point_env.f3" href="#ftn.context.rationale.x86_and_floating_point_env.f3" class="footnote">7</a>]</sup>.
+ </p>
+<p>
+ "The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7".
+ <sup>[<a name="context.rationale.x86_and_floating_point_env.f4" href="#ftn.context.rationale.x86_and_floating_point_env.f4" class="footnote">8</a>]</sup>.
+ </p>
+<p>
+ "XMM6-XMM15 must be preserved" <sup>[<a name="context.rationale.x86_and_floating_point_env.f5" href="#ftn.context.rationale.x86_and_floating_point_env.f5" class="footnote">9</a>]</sup>
+ </p>
+<h5>
+<a name="context.rationale.x86_and_floating_point_env.h3"></a>
+ <span><a name="context.rationale.x86_and_floating_point_env.sysv"></a></span><a class="link" href="x86_and_floating_point_env.html#context.rationale.x86_and_floating_point_env.sysv">SysV</a>
+ </h5>
+<p>
+ "The control bits of the MxCsr register are callee-saved (preserved
+ across calls), while the status bits are caller-saved (not preserved). The
+ x87 status word register is caller-saved, whereas the x87 control word (FpCsr)
+ is callee-saved." <sup>[<a name="context.rationale.x86_and_floating_point_env.f6" href="#ftn.context.rationale.x86_and_floating_point_env.f6" class="footnote">10</a>]</sup>.
+ </p>
+<div class="footnotes">
+<br><hr width="100" align="left">
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.x86_and_floating_point_env.f0" href="#context.rationale.x86_and_floating_point_env.f0" class="para">4</a>] </sup>
+ 'Calling Conventions', Agner Fog
+ </p></div>
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.x86_and_floating_point_env.f1" href="#context.rationale.x86_and_floating_point_env.f1" class="para">5</a>] </sup>
+ <a href="http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx" target="_top">MSDN
+ article 'MxCsr'</a>
+ </p></div>
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.x86_and_floating_point_env.f2" href="#context.rationale.x86_and_floating_point_env.f2" class="para">6</a>] </sup>
+ <a href="http://http://msdn.microsoft.com/en-us/library/ms235300.aspx" target="_top">MSDN
+ article 'FpCsr'</a>
+ </p></div>
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.x86_and_floating_point_env.f3" href="#context.rationale.x86_and_floating_point_env.f3" class="para">7</a>] </sup>
+ <a href="http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx" target="_top">MSDN
+ article 'Legacy Floating-Point Support'</a>
+ </p></div>
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.x86_and_floating_point_env.f4" href="#context.rationale.x86_and_floating_point_env.f4" class="para">8</a>] </sup>
+ 'Calling Conventions', Agner Fog
+ </p></div>
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.x86_and_floating_point_env.f5" href="#context.rationale.x86_and_floating_point_env.f5" class="para">9</a>] </sup>
+ <a href="http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx" target="_top">MSDN
+ article 'Register Usage'</a>
+ </p></div>
+<div class="footnote"><p><sup>[<a id="ftn.context.rationale.x86_and_floating_point_env.f6" href="#context.rationale.x86_and_floating_point_env.f6" class="para">10</a>] </sup>
+ SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4,
+ 3.2.1
+ </p></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="other_apis_.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/reference.html b/libs/context/doc/html/context/reference.html
new file mode 100644
index 0000000000..1cff2438e5
--- /dev/null
+++ b/libs/context/doc/html/context/reference.html
@@ -0,0 +1,104 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Reference</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="rationale/x86_and_floating_point_env.html" title="x86 and floating-point env">
+<link rel="next" href="todo.html" title="Todo">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="rationale/x86_and_floating_point_env.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="todo.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.reference"></a><a class="link" href="reference.html" title="Reference">Reference</a>
+</h2></div></div></div>
+<h4>
+<a name="context.reference.h0"></a>
+ <span><a name="context.reference.arm"></a></span><a class="link" href="reference.html#context.reference.arm">ARM</a>
+ </h4>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ AAPCS ABI: Procedure Call Standard for the ARM Architecture
+ </li>
+<li class="listitem">
+ AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement
+ </li>
+</ul></div>
+<h4>
+<a name="context.reference.h1"></a>
+ <span><a name="context.reference.mips"></a></span><a class="link" href="reference.html#context.reference.mips">MIPS</a>
+ </h4>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
+ O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement
+ </li></ul></div>
+<h4>
+<a name="context.reference.h2"></a>
+ <span><a name="context.reference.powerpc32"></a></span><a class="link" href="reference.html#context.reference.powerpc32">PowerPC32</a>
+ </h4>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
+ SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement
+ </li></ul></div>
+<h4>
+<a name="context.reference.h3"></a>
+ <span><a name="context.reference.powerpc64"></a></span><a class="link" href="reference.html#context.reference.powerpc64">PowerPC64</a>
+ </h4>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
+ SYSV ABI: PowerPC User Instruction Set Architecture, Book I
+ </li></ul></div>
+<h4>
+<a name="context.reference.h4"></a>
+ <span><a name="context.reference.x86_32"></a></span><a class="link" href="reference.html#context.reference.x86_32">X86-32</a>
+ </h4>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture
+ Processor Supplement
+ </li>
+<li class="listitem">
+ MS PE: <a href="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx" target="_top">Calling
+ Conventions</a>
+ </li>
+</ul></div>
+<h4>
+<a name="context.reference.h5"></a>
+ <span><a name="context.reference.x86_64"></a></span><a class="link" href="reference.html#context.reference.x86_64">X86-64</a>
+ </h4>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor
+ Supplement
+ </li>
+<li class="listitem">
+ MS PE: <a href="http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx" target="_top">x64
+ Software Conventions</a>
+ </li>
+</ul></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="rationale/x86_and_floating_point_env.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="todo.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/requirements.html b/libs/context/doc/html/context/requirements.html
new file mode 100644
index 0000000000..814e0141fa
--- /dev/null
+++ b/libs/context/doc/html/context/requirements.html
@@ -0,0 +1,59 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Requirements</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="overview.html" title="Overview">
+<link rel="next" href="context.html" title="Context">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="overview.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="context.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.requirements"></a><a class="link" href="requirements.html" title="Requirements">Requirements</a>
+</h2></div></div></div>
+<p>
+ <span class="bold"><strong>Boost.Context</strong></span> must be built for the particular
+ compiler(s) and CPU architecture(s)s being targeted. <span class="bold"><strong>Boost.Context</strong></span>
+ includes assembly code and, therefore, requires GNU AS for supported POSIX
+ systems, and MASM for Windows systems.
+ </p>
+<div class="important"><table border="0" summary="Important">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
+<th align="left">Important</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ Please note that address-model=64 must be given to bjam command line on 64bit
+ Windows (boost-build issue).
+ </p></td></tr>
+</table></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="overview.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="context.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/stack.html b/libs/context/doc/html/context/stack.html
new file mode 100644
index 0000000000..a519a46195
--- /dev/null
+++ b/libs/context/doc/html/context/stack.html
@@ -0,0 +1,163 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Stack allocation</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="context/boost_fcontext.html" title="Struct fcontext_t and related functions">
+<link rel="next" href="stack/stack_allocator.html" title="Class stack_allocator">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="context/boost_fcontext.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack/stack_allocator.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.stack"></a><a class="link" href="stack.html" title="Stack allocation">Stack allocation</a>
+</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section"><a href="stack/stack_allocator.html">Class <code class="computeroutput"><span class="identifier">stack_allocator</span></code></a></span></dt>
+<dt><span class="section"><a href="stack/stack_helper.html">Helper functions</a></span></dt>
+</dl></div>
+<p>
+ A <span class="emphasis"><em>fcontext_t</em></span> requires a stack which will be allocated/deallocated
+ by a <span class="emphasis"><em>StackAllocator</em></span>. <span class="bold"><strong>Boost.Context</strong></span>
+ uses <code class="computeroutput"><span class="identifier">stack_allocator</span></code> by default
+ but a customized <code class="computeroutput"><span class="identifier">stack</span> <span class="identifier">allocator</span></code>
+ can be passed to the context constructor instead. If a context is constructed
+ it invokes <span class="emphasis"><em>allocate()</em></span> function and by its destruction
+ the stack gets released by <span class="emphasis"><em>deallocate()</em></span>.
+ </p>
+<h4>
+<a name="context.stack.h0"></a>
+ <span><a name="context.stack._emphasis_stackallocator_concept__emphasis_"></a></span><a class="link" href="stack.html#context.stack._emphasis_stackallocator_concept__emphasis_"><span class="emphasis"><em>StackAllocator
+ concept</em></span></a>
+ </h4>
+<p>
+ A <span class="emphasis"><em>StackAllocator</em></span> must satisfy the <span class="emphasis"><em>StackAllocator
+ concept</em></span> requirements shown in the following table, in which <code class="computeroutput"><span class="identifier">a</span></code> is an object of a <span class="emphasis"><em>StackAllocator</em></span>
+ type, <code class="computeroutput"><span class="identifier">p</span></code> is a <code class="computeroutput"><span class="keyword">void</span> <span class="special">*</span></code>, and
+ <code class="computeroutput"><span class="identifier">s</span></code> is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span></code>:
+ </p>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ expression
+ </p>
+ </th>
+<th>
+ <p>
+ return type
+ </p>
+ </th>
+<th>
+ <p>
+ notes
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">(</span>
+ <span class="identifier">s</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ <code class="computeroutput"><span class="keyword">void</span> <span class="special">*</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ returns a pointer to <code class="computeroutput"><span class="identifier">s</span></code>
+ bytes allocated from the stack
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">deallocate</span><span class="special">(</span>
+ <span class="identifier">p</span><span class="special">,</span>
+ <span class="identifier">s</span><span class="special">)</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ <code class="computeroutput"><span class="keyword">void</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ deallocates <code class="computeroutput"><span class="identifier">s</span></code> bytes
+ of memory beginning at <code class="computeroutput"><span class="identifier">p</span></code>,
+ a pointer previously returned by <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">()</span></code>
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+<div class="important"><table border="0" summary="Important">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
+<th align="left">Important</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ The implementation of <code class="computeroutput"><span class="identifier">allocate</span><span class="special">()</span></code> might include logic to protect against
+ exceeding the context's available stack size rather than leaving it as undefined
+ behaviour.
+ </p></td></tr>
+</table></div>
+<div class="important"><table border="0" summary="Important">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
+<th align="left">Important</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ Calling <code class="computeroutput"><span class="identifier">deallocate</span><span class="special">()</span></code>
+ with a pointer not returned by <code class="computeroutput"><span class="identifier">allocate</span><span class="special">()</span></code> results in undefined behaviour.
+ </p></td></tr>
+</table></div>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ The stack is not required to be aligned; alignment takes place inside <code class="computeroutput"><span class="identifier">make_fcontext</span><span class="special">()</span></code>.
+ </p></td></tr>
+</table></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="context/boost_fcontext.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack/stack_allocator.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/stack/stack_allocator.html b/libs/context/doc/html/context/stack/stack_allocator.html
new file mode 100644
index 0000000000..2a810b23e8
--- /dev/null
+++ b/libs/context/doc/html/context/stack/stack_allocator.html
@@ -0,0 +1,51 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Class stack_allocator</title>
+<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../../index.html" title="Context">
+<link rel="up" href="../stack.html" title="Stack allocation">
+<link rel="prev" href="../stack.html" title="Stack allocation">
+<link rel="next" href="stack_helper.html" title="Helper functions">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../stack.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack_helper.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="context.stack.stack_allocator"></a><a class="link" href="stack_allocator.html" title="Class stack_allocator">Class <code class="computeroutput"><span class="identifier">stack_allocator</span></code></a>
+</h3></div></div></div>
+<p>
+ <span class="bold"><strong>Boost.Context</strong></span> provides a <span class="emphasis"><em>StackAllocator</em></span>
+ <code class="computeroutput"><span class="identifier">stack_allocator</span></code> which models
+ the <span class="emphasis"><em>StackAllocator concept</em></span> concept. It appends a <span class="emphasis"><em>guard-page</em></span>
+ to protect against exceeding the stack. If the guard page is accessed (read
+ or write operation) a segmentation fault/access violation is generated by
+ the operating system.
+ </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../stack.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack_helper.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/stack/stack_helper.html b/libs/context/doc/html/context/stack/stack_helper.html
new file mode 100644
index 0000000000..af5494b77d
--- /dev/null
+++ b/libs/context/doc/html/context/stack/stack_helper.html
@@ -0,0 +1,170 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Helper functions</title>
+<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../../index.html" title="Context">
+<link rel="up" href="../stack.html" title="Stack allocation">
+<link rel="prev" href="stack_allocator.html" title="Class stack_allocator">
+<link rel="next" href="../performance.html" title="Performance">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="stack_allocator.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../performance.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="context.stack.stack_helper"></a><a class="link" href="stack_helper.html" title="Helper functions">Helper functions</a>
+</h3></div></div></div>
+<p>
+ <span class="bold"><strong>Boost.Context</strong></span> provides easy access to the
+ stack related limits defined by the environment.
+ </p>
+<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">default_stacksize</span><span class="special">();</span>
+
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">minimum_stacksize</span><span class="special">();</span>
+
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">maximum_stacksize</span><span class="special">();</span>
+
+<span class="keyword">bool</span> <span class="identifier">is_stack_unbound</span><span class="special">();</span>
+
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">pagesize</span><span class="special">();</span>
+
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">page_count</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">stacksize</span><span class="special">);</span>
+</pre>
+<h5>
+<a name="context.stack.stack_helper.h0"></a>
+ <span><a name="context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_stacksize__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_helper.html#context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_stacksize__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
+ <span class="identifier">default_stacksize</span><span class="special">()</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Returns:</span></dt>
+<dd><p>
+ Returns a default stack size, which may be platform specific. The present
+ implementation returns a value of 256 kB.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.stack.stack_helper.h1"></a>
+ <span><a name="context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_stacksize__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_helper.html#context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_stacksize__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
+ <span class="identifier">minimum_stacksize</span><span class="special">()</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Returns:</span></dt>
+<dd><p>
+ Returns the minimum size in bytes of stack defined by the environment.
+ </p></dd>
+<dt><span class="term">Throws:</span></dt>
+<dd><p>
+ Nothing.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.stack.stack_helper.h2"></a>
+ <span><a name="context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_stacksize__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_helper.html#context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_stacksize__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
+ <span class="identifier">maximum_stacksize</span><span class="special">()</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Preconditions:</span></dt>
+<dd><p>
+ <code class="computeroutput"><span class="identifier">is_stack_unbound</span><span class="special">()</span></code>
+ returns <code class="computeroutput"><span class="keyword">false</span></code>.
+ </p></dd>
+<dt><span class="term">Returns:</span></dt>
+<dd><p>
+ Returns the maximum size in bytes of stack defined by the environment.
+ </p></dd>
+<dt><span class="term">Throws:</span></dt>
+<dd><p>
+ Nothing.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.stack.stack_helper.h3"></a>
+ <span><a name="context.stack.stack_helper._code__phrase_role__keyword__bool__phrase___phrase_role__identifier__is_stack_unbound__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_helper.html#context.stack.stack_helper._code__phrase_role__keyword__bool__phrase___phrase_role__identifier__is_stack_unbound__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="keyword">bool</span> <span class="identifier">is_stack_unbound</span><span class="special">()</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Returns:</span></dt>
+<dd><p>
+ Returns <code class="computeroutput"><span class="keyword">true</span></code> if the environment
+ defines no limit for the size of a stack.
+ </p></dd>
+<dt><span class="term">Throws:</span></dt>
+<dd><p>
+ Nothing.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.stack.stack_helper.h4"></a>
+ <span><a name="context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__pagesize__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_helper.html#context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__pagesize__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
+ <span class="identifier">pagesize</span><span class="special">()</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Returns:</span></dt>
+<dd><p>
+ Returns how many bytes the operating system allocates for one page.
+ </p></dd>
+<dt><span class="term">Throws:</span></dt>
+<dd><p>
+ Nothing.
+ </p></dd>
+</dl>
+</div>
+<h5>
+<a name="context.stack.stack_helper.h5"></a>
+ <span><a name="context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__page_count__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stacksize__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="stack_helper.html#context.stack.stack_helper._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__page_count__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stacksize__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
+ <span class="identifier">page_count</span><span class="special">(</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">stacksize</span><span class="special">)</span></code></a>
+ </h5>
+<div class="variablelist">
+<p class="title"><b></b></p>
+<dl>
+<dt><span class="term">Returns:</span></dt>
+<dd><p>
+ Returns how many pages have to be allocated for a stack of <code class="computeroutput"><span class="identifier">stacksize</span></code> bytes.
+ </p></dd>
+<dt><span class="term">Throws:</span></dt>
+<dd><p>
+ Nothing.
+ </p></dd>
+</dl>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="stack_allocator.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../performance.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/tested.html b/libs/context/doc/html/context/tested.html
new file mode 100644
index 0000000000..e2fe446b10
--- /dev/null
+++ b/libs/context/doc/html/context/tested.html
@@ -0,0 +1,295 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Tested Platforms</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="performance.html" title="Performance">
+<link rel="next" href="rationale.html" title="Rationale">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="performance.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rationale.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.tested"></a><a class="link" href="tested.html" title="Tested Platforms">Tested Platforms</a>
+</h2></div></div></div>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ Platform
+ </p>
+ </th>
+<th>
+ <p>
+ OS
+ </p>
+ </th>
+<th>
+ <p>
+ Compiler
+ </p>
+ </th>
+<th>
+ <p>
+ ABI
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ ARM (ARM926EJ-S)
+ </p>
+ </td>
+<td>
+ <p>
+ Debian GNU/Linux (Lenny)
+ </p>
+ </td>
+<td>
+ <p>
+ GCC 4.4.4
+ </p>
+ </td>
+<td>
+ <p>
+ ARM APCS (Linux)
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ MIPS (MIPS 24K)
+ </p>
+ </td>
+<td>
+ <p>
+ Debian GNU/Linux (Lenny)
+ </p>
+ </td>
+<td>
+ <p>
+ GCC 4.3.2
+ </p>
+ </td>
+<td>
+ <p>
+ O32
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ MIPS (O2 / MIPS R5000)
+ </p>
+ </td>
+<td>
+ <p>
+ Debian GNU/Linux (Lenny)
+ </p>
+ </td>
+<td>
+ <p>
+ GCC 4.3.2
+ </p>
+ </td>
+<td>
+ <p>
+ O32
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ PowerPC (7400)
+ </p>
+ </td>
+<td>
+ <p>
+ Debian GNU/Linux (Lenny)
+ </p>
+ </td>
+<td>
+ <p>
+ GCC 4.3.2
+ </p>
+ </td>
+<td>
+ <p>
+ SYSV
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ X86_64 (Intel Core2 Quad)
+ </p>
+ </td>
+<td>
+ <p>
+ Ubuntu GNU/Linux (Lucid Lynx)
+ </p>
+ </td>
+<td>
+ <p>
+ GCC 4.4.3
+ </p>
+ </td>
+<td>
+ <p>
+ SYSV
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ X86_64
+ </p>
+ </td>
+<td>
+ <p>
+ Windows 7
+ </p>
+ </td>
+<td>
+ <p>
+ MS VC 10.0
+ </p>
+ </td>
+<td>
+ <p>
+ PE
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ I386
+ </p>
+ </td>
+<td>
+ <p>
+ Debian GNU/Linux (Lenny)
+ </p>
+ </td>
+<td>
+ <p>
+ GCC 4.4.3
+ </p>
+ </td>
+<td>
+ <p>
+ SYSV
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ I386
+ </p>
+ </td>
+<td>
+ <p>
+ FreeBSD 8.0
+ </p>
+ </td>
+<td>
+ <p>
+ GCC 4.2.1
+ </p>
+ </td>
+<td>
+ <p>
+ SYSV
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ I386
+ </p>
+ </td>
+<td>
+ <p>
+ OpenSolaris 2009.06
+ </p>
+ </td>
+<td>
+ <p>
+ GCC 4.3.2
+ </p>
+ </td>
+<td>
+ <p>
+ SYSV
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ I386
+ </p>
+ </td>
+<td>
+ <p>
+ Windows XP
+ </p>
+ </td>
+<td>
+ <p>
+ MSVC 9.0
+ </p>
+ </td>
+<td>
+ <p>
+ PE
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="performance.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rationale.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/context/todo.html b/libs/context/doc/html/context/todo.html
new file mode 100644
index 0000000000..c6c1b329a1
--- /dev/null
+++ b/libs/context/doc/html/context/todo.html
@@ -0,0 +1,51 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Todo</title>
+<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Context">
+<link rel="up" href="../index.html" title="Context">
+<link rel="prev" href="reference.html" title="Reference">
+<link rel="next" href="acknowledgements.html" title="Acknowledgments">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="reference.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="context.todo"></a><a class="link" href="todo.html" title="Todo">Todo</a>
+</h2></div></div></div>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ provide support for SPARC
+ </li>
+<li class="listitem">
+ support split-stack feature from gcc/gold linker
+ </li>
+</ul></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2009 Oliver Kowalke<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="reference.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/context/doc/html/index.html b/libs/context/doc/html/index.html
new file mode 100644
index 0000000000..e540e54353
--- /dev/null
+++ b/libs/context/doc/html/index.html
@@ -0,0 +1,72 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Context</title>
+<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="index.html" title="Context">
+<link rel="next" href="context/overview.html" title="Overview">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
+<td align="center"><a href="../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav"><a accesskey="n" href="context/overview.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
+<div class="article">
+<div class="titlepage">
+<div>
+<div><h2 class="title">
+<a name="context"></a>Context</h2></div>
+<div><div class="authorgroup"><div class="author"><h3 class="author">
+<span class="firstname">Oliver</span> <span class="surname">Kowalke</span>
+</h3></div></div></div>
+<div><p class="copyright">Copyright &#169; 2009 Oliver Kowalke</p></div>
+<div><div class="legalnotice">
+<a name="context.legal"></a><p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+</div></div>
+</div>
+<hr>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="section"><a href="context/overview.html">Overview</a></span></dt>
+<dt><span class="section"><a href="context/requirements.html">Requirements</a></span></dt>
+<dt><span class="section"><a href="context/context.html">Context</a></span></dt>
+<dd><dl><dt><span class="section"><a href="context/context/boost_fcontext.html">Struct <code class="computeroutput"><span class="identifier">fcontext_t</span></code> and related functions</a></span></dt></dl></dd>
+<dt><span class="section"><a href="context/stack.html">Stack allocation</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="context/stack/stack_allocator.html">Class <code class="computeroutput"><span class="identifier">stack_allocator</span></code></a></span></dt>
+<dt><span class="section"><a href="context/stack/stack_helper.html">Helper functions</a></span></dt>
+</dl></dd>
+<dt><span class="section"><a href="context/performance.html">Performance</a></span></dt>
+<dt><span class="section"><a href="context/tested.html">Tested Platforms</a></span></dt>
+<dt><span class="section"><a href="context/rationale.html">Rationale</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="context/rationale/other_apis_.html">Other APIs </a></span></dt>
+<dt><span class="section"><a href="context/rationale/x86_and_floating_point_env.html">x86 and
+ floating-point env</a></span></dt>
+</dl></dd>
+<dt><span class="section"><a href="context/reference.html">Reference</a></span></dt>
+<dt><span class="section"><a href="context/todo.html">Todo</a></span></dt>
+<dt><span class="section"><a href="context/acknowledgements.html">Acknowledgments</a></span></dt>
+</dl>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"><p><small>Last revised: August 15, 2012 at 23:36:42 GMT</small></p></td>
+<td align="right"><div class="copyright-footer"></div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav"><a accesskey="n" href="context/overview.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
+</body>
+</html>
diff --git a/libs/context/doc/html/standalone_HTML.manifest b/libs/context/doc/html/standalone_HTML.manifest
new file mode 100644
index 0000000000..3ffe9abe75
--- /dev/null
+++ b/libs/context/doc/html/standalone_HTML.manifest
@@ -0,0 +1,16 @@
+index.html
+context/overview.html
+context/requirements.html
+context/context.html
+context/context/boost_fcontext.html
+context/stack.html
+context/stack/stack_allocator.html
+context/stack/stack_helper.html
+context/performance.html
+context/tested.html
+context/rationale.html
+context/rationale/other_apis_.html
+context/rationale/x86_and_floating_point_env.html
+context/reference.html
+context/todo.html
+context/acknowledgements.html
diff --git a/libs/context/doc/overview.qbk b/libs/context/doc/overview.qbk
new file mode 100644
index 0000000000..d08381f635
--- /dev/null
+++ b/libs/context/doc/overview.qbk
@@ -0,0 +1,42 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:overview Overview]
+
+__boost_context__ is a foundational library that provides a sort of cooperative
+multitasking on a single thread. By providing an abstraction of the current
+execution state in the current thread, including the stack (with local
+variables) and stack pointer, all registers and CPU flags, and the instruction
+pointer, a __fcontext__ instance represents a specific point in the application's
+execution path. This is useful for building higher-level abstractions, like
+__coroutines__, __coop_threads__ or an aquivalent to
+[@http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx C# keyword __yield__]
+in C++.
+
+A __fcontext__ provides the means to suspend the current execution path and to
+transfer execution control, thereby permitting another __fcontext__ to run on the
+current thread. This stateful transfer mechanism enables a __fcontext__ to
+suspend execution from within nested functions and, later, to resume from where
+it was suspended. While the execution path represented by a __fcontext__ only
+runs on a single thread, it can be migrated to another thread at any given time.
+
+A context switch between threads requires system calls (involving the OS
+kernel), which can cost more than thousand CPU cycles on x86 CPUs. By contrast,
+transferring control among them requires only fewer than hundred CPU cycles because
+it does not involve system calls as it is done within a single thread.
+
+In order to use the classes and functions described here, you can either include
+the specific headers specified by the descriptions of each class or function, or
+include the master library header:
+
+ #include <boost/context/all.hpp>
+
+which includes all the other headers in turn.
+
+All functions and classes are contained in the namespace __context_ns__.
+
+[endsect]
diff --git a/libs/context/doc/performance.qbk b/libs/context/doc/performance.qbk
new file mode 100644
index 0000000000..f6d01fe1a0
--- /dev/null
+++ b/libs/context/doc/performance.qbk
@@ -0,0 +1,39 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:performance Performance]
+
+Performance of __boost_context__ was measured on the platforms shown in the
+following table. Performance measurements were taken using `rdtsc`, with
+overhead corrections, on x86 platforms. In each case, stack protection was
+active, cache warm-up was accounted for, and the one running thread was pinned
+to a single CPU. The code was compiled using the build options,
+'variant = release cxxflags = -DBOOST_DISABLE_ASSERTS'.
+
+The numbers in the table are the number of cycles per iteration, based upon an
+average computed over 10 iterations.
+
+[table Perfomance of context switch
+ [[Platform] [ucontext_t] [fcontext_t with fpu] [fcontext_t without fpu] [boost::function]]
+ [
+ [AMD Athlon 64 DualCore 4400+ (32bit Linux)]
+ [846 cycles]
+ [65 cycles]
+ [46 cycles]
+ [43 cycles]
+ ]
+ [
+ [Intel Core2 Q6700 (64bit Linux)]
+ [1472 cycles]
+ [172 cycles]
+ [63 cycles]
+ [60 cycles]
+ ]
+]
+
+
+[endsect]
diff --git a/libs/context/doc/rationale.qbk b/libs/context/doc/rationale.qbk
new file mode 100644
index 0000000000..75e8dfb746
--- /dev/null
+++ b/libs/context/doc/rationale.qbk
@@ -0,0 +1,148 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:rationale Rationale]
+
+[heading No inline-assembler]
+
+Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not
+support inline assembler.
+[footnote [@http://msdn.microsoft.com/en-us/library/4ks26t93.aspx MSDN article
+'Inline Assembler']].
+
+
+[heading fcontext_t]
+
+__boost_context__ provides the low level API fcontext_t which is
+implemented in assembler to provide context swapping operations.
+fcontext_t is the part to port to new platforms.
+
+[note Context switches do not preserve the signal mask on UNIX systems.]
+
+Because the assembler code uses the byte layout of __fcontext__ to access
+its members __fcontext__ must be a POD. This requires that __fcontext__ has only a
+default constructor, no visibility keywords (e.g. private, public, protected), no
+virtual methods and all members and base clases are PODs too.
+
+
+[heading Protecting the stack]
+
+Because the stack's size is fixed -- there is no support for split stacks yet -- it
+is important to protect against exceeding the stack's bounds. Otherwise, in the
+best case, overrunning the stack's memory will result in a segmentation fault or
+access violation and, in the worst case, the application's memory will be
+overwritten. `stack_allocator` appends a guard page to the stack to help detect
+overruns. The guard page consumes no physical memory, but generates a
+segmentation fault or access violation on access to the virtual memory addresses
+within it.
+
+
+[section Other APIs ]
+
+[heading setjmp()/longjmp()]
+
+C99 defines `setjmp()`/`longjmp()` to provide non-local jumps but it does not
+require that ['longjmp()] preserves the current stack frame. Therefore, jumping
+into a function which was exited via a call to ['longjmp()] is undefined
+[footnote ISO/IEC 9899:1999, 2005, 7.13.2.1:2].
+
+
+[heading ucontext_t]
+
+Since POSIX.1-2003 `ucontext_t` is deprecated and was removed in POSIX.1-2008!
+The function signature of `makecontext()` is:
+
+ void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
+
+The third argument of `makecontext()` specifies the number of integer arguments
+that follow which will require function pointer cast if `func` will accept those
+arguments which is undefined in C99
+[footnote ISO/IEC 9899:1999, 2005, J.2].
+
+The arguments in the var-arg list are required to be integers, passing pointers
+in var-arg list is not guarantied to work, especially it will fail for
+architectures where pointers are larger than integers.
+
+`ucontext_t` preserves signal mask between context switches which involes system
+calls consuming a lot of CPU cycles (ucontext_t is slower by
+perfomance_link[factor 13x] relative to `fcontext_t`).
+
+
+[heading Windows fibers]
+
+A drawback of Windows Fiber API is that `CreateFiber()` does not accept a
+pointer to user allocated stack space preventing the reuse of stacks for other
+context instances. Because the Windows Fiber API requires to call
+`ConvertThreadToFiber()` if `SwitchFiber()` is called for a thread which has not
+been converted to a fiber. For the same reason `ConvertFiberToThread()`
+must be called after return from `SwitchFiber()` if the thread was forced to be
+converted to a fiber before (which is inefficient).
+
+ if ( ! is_a_fiber() )
+ {
+ ConvertThreadToFiber( 0);
+ SwitchToFiber( ctx);
+ ConvertFiberToThread();
+ }
+
+If the condition `_WIN32_WINNT >= _WIN32_WINNT_VISTA` is met function
+`IsThreadAFiber()` is provided in order to detect if the current thread was
+already converted. Unfortunately Windows XP + SP 2/3 defines
+`_WIN32_WINNT >= _WIN32_WINNT_VISTA` without providing `IsThreadAFiber()`.
+
+[endsect]
+
+
+[section x86 and floating-point env]
+
+[heading i386]
+
+"The FpCsr and the MxCsr register must be saved and restored before any call or return
+by any procedure that needs to modify them ..."
+[footnote 'Calling Conventions', Agner Fog].
+
+
+[heading x86_64]
+
+[heading Windows]
+
+MxCsr - "A callee that modifies any of the nonvolatile fields within MxCsr must restore
+them before returning to its caller. Furthermore, a caller that has modified any
+of these fields must restore them to their standard values before invoking a callee ..."
+[footnote [@http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx MSDN article
+'MxCsr']].
+
+FpCsr - "A callee that modifies any of the fields within FpCsr must restore them before
+returning to its caller. Furthermore, a caller that has modified any of these
+fields must restore them to their standard values before invoking a callee ..."
+[footnote [@http://http://msdn.microsoft.com/en-us/library/ms235300.aspx MSDN article
+'FpCsr']].
+
+"The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved across
+context switches. There is no explicit calling convention for these registers."
+[footnote [@http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx MSDN article
+'Legacy Floating-Point Support']].
+
+"The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7".
+[footnote 'Calling Conventions', Agner Fog].
+
+"XMM6-XMM15 must be preserved"
+[footnote [@http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx MSDN
+article 'Register Usage']]
+
+
+[heading SysV]
+
+"The control bits of the MxCsr register are callee-saved (preserved across calls),
+while the status bits are caller-saved (not preserved). The x87 status word register is
+caller-saved, whereas the x87 control word (FpCsr) is callee-saved."
+[footnote SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4, 3.2.1].
+
+[endsect]
+
+
+[endsect]
diff --git a/libs/context/doc/reference.qbk b/libs/context/doc/reference.qbk
new file mode 100644
index 0000000000..d7ab1ddbd0
--- /dev/null
+++ b/libs/context/doc/reference.qbk
@@ -0,0 +1,43 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:reference Reference]
+
+[heading ARM]
+
+* AAPCS ABI: Procedure Call Standard for the ARM Architecture
+* AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement
+
+
+[heading MIPS]
+
+* O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement
+
+
+[heading PowerPC32]
+
+* SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement
+
+
+[heading PowerPC64]
+
+* SYSV ABI: PowerPC User Instruction Set Architecture, Book I
+
+
+[heading X86-32]
+
+* SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture Processor Supplement
+* MS PE: [@http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx Calling Conventions]
+
+
+[heading X86-64]
+
+* SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor Supplement
+* MS PE: [@http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx x64 Software Conventions]
+
+
+[endsect]
diff --git a/libs/context/doc/requirements.qbk b/libs/context/doc/requirements.qbk
new file mode 100644
index 0000000000..aa5a656777
--- /dev/null
+++ b/libs/context/doc/requirements.qbk
@@ -0,0 +1,18 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:requirements Requirements]
+
+__boost_context__ must be built for the particular compiler(s) and CPU
+architecture(s)s being targeted. __boost_context__ includes assembly code and,
+therefore, requires GNU AS for supported POSIX systems, and MASM for Windows
+systems.
+
+[important Please note that address-model=64 must be given to bjam command line
+on 64bit Windows (boost-build issue).]
+
+[endsect]
diff --git a/libs/context/doc/stack.qbk b/libs/context/doc/stack.qbk
new file mode 100644
index 0000000000..306ca27842
--- /dev/null
+++ b/libs/context/doc/stack.qbk
@@ -0,0 +1,116 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:stack Stack allocation]
+
+A __fcontext__ requires a stack which will be allocated/deallocated
+by a __stack_allocator__.
+__boost_context__ uses `stack_allocator` by default but a
+customized `stack allocator` can be passed to the context constructor
+instead.
+If a context is constructed it invokes __stack_alloc__ function and by its
+destruction the stack gets released by __stack_dealloc__.
+
+[heading __stack_allocator_concept__]
+A __stack_allocator__ must satisfy the __stack_allocator_concept__ requirements
+shown in the following table, in which `a` is an object of a
+__stack_allocator__ type, `p` is a `void *`, and `s` is a `std::size_t`:
+
+[table
+ [[expression][return type][notes]]
+ [
+ [`a.allocate( s)`]
+ [`void *`]
+ [returns a pointer to `s` bytes allocated from the stack]
+ ]
+ [
+ [`a.deallocate( p, s)`]
+ [`void`]
+ [deallocates `s` bytes of memory beginning at `p`,
+ a pointer previously returned by `a.allocate()`]
+ ]
+]
+
+[important The implementation of `allocate()` might include logic to protect
+against exceeding the context's available stack size rather than leaving it as
+undefined behaviour.]
+
+[important Calling `deallocate()` with a pointer not returned by `allocate()`
+results in undefined behaviour.]
+
+[note The stack is not required to be aligned; alignment takes place inside
+`make_fcontext()`.]
+
+
+[section:stack_allocator Class `stack_allocator`]
+
+__boost_context__ provides a __stack_allocator__ `stack_allocator` which models
+the __stack_allocator_concept__ concept.
+It appends a __guard_page__ to protect against exceeding the stack. If the guard
+page is accessed (read or write operation) a segmentation fault/access violation
+is generated by the operating system.
+
+[endsect]
+
+
+[section:stack_helper Helper functions]
+
+__boost_context__ provides easy access to the stack related limits defined by
+the environment.
+
+ std::size_t default_stacksize();
+
+ std::size_t minimum_stacksize();
+
+ std::size_t maximum_stacksize();
+
+ bool is_stack_unbound();
+
+ std::size_t pagesize();
+
+ std::size_t page_count( std::size_t stacksize);
+
+[heading `std::size_t default_stacksize()`]
+[variablelist
+[[Returns:] [Returns a default stack size, which may be platform specific.
+The present implementation returns a value of 256 kB.]]
+]
+
+[heading `std::size_t minimum_stacksize()`]
+[variablelist
+[[Returns:] [Returns the minimum size in bytes of stack defined by the environment.]]
+[[Throws:] [Nothing.]]
+]
+
+[heading `std::size_t maximum_stacksize()`]
+[variablelist
+[[Preconditions:] [`is_stack_unbound()` returns `false`.]]
+[[Returns:] [Returns the maximum size in bytes of stack defined by the environment.]]
+[[Throws:] [Nothing.]]
+]
+
+[heading `bool is_stack_unbound()`]
+[variablelist
+[[Returns:] [Returns `true` if the environment defines no limit for the size of a stack.]]
+[[Throws:] [Nothing.]]
+]
+
+[heading `std::size_t pagesize()`]
+[variablelist
+[[Returns:] [Returns how many bytes the operating system allocates for one page.]]
+[[Throws:] [Nothing.]]
+]
+
+[heading `std::size_t page_count( std::size_t stacksize)`]
+[variablelist
+[[Returns:] [Returns how many pages have to be allocated for a stack of `stacksize` bytes.]]
+[[Throws:] [Nothing.]]
+]
+
+[endsect]
+
+[endsect]
diff --git a/libs/context/doc/tested.qbk b/libs/context/doc/tested.qbk
new file mode 100644
index 0000000000..08a20074d8
--- /dev/null
+++ b/libs/context/doc/tested.qbk
@@ -0,0 +1,74 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:tested Tested Platforms]
+
+[table
+ [[Platform] [OS] [Compiler] [ABI]]
+ [
+ [ARM (ARM926EJ-S)]
+ [Debian GNU/Linux (Lenny)]
+ [GCC 4.4.4]
+ [ARM APCS (Linux)]
+ ]
+ [
+ [MIPS (MIPS 24K)]
+ [Debian GNU/Linux (Lenny)]
+ [GCC 4.3.2]
+ [O32]
+ ]
+ [
+ [MIPS (O2 / MIPS R5000)]
+ [Debian GNU/Linux (Lenny)]
+ [GCC 4.3.2]
+ [O32]
+ ]
+ [
+ [PowerPC (7400)]
+ [Debian GNU/Linux (Lenny)]
+ [GCC 4.3.2]
+ [SYSV]
+ ]
+ [
+ [X86_64 (Intel Core2 Quad)]
+ [Ubuntu GNU/Linux (Lucid Lynx)]
+ [GCC 4.4.3]
+ [SYSV]
+ ]
+ [
+ [X86_64]
+ [Windows 7]
+ [MS VC 10.0]
+ [PE]
+ ]
+ [
+ [I386]
+ [Debian GNU/Linux (Lenny)]
+ [GCC 4.4.3]
+ [SYSV]
+ ]
+ [
+ [I386]
+ [FreeBSD 8.0]
+ [GCC 4.2.1]
+ [SYSV]
+ ]
+ [
+ [I386]
+ [OpenSolaris 2009.06]
+ [GCC 4.3.2]
+ [SYSV]
+ ]
+ [
+ [I386]
+ [Windows XP]
+ [MSVC 9.0]
+ [PE]
+ ]
+]
+
+[endsect]
diff --git a/libs/context/doc/todo.qbk b/libs/context/doc/todo.qbk
new file mode 100644
index 0000000000..42aac14048
--- /dev/null
+++ b/libs/context/doc/todo.qbk
@@ -0,0 +1,13 @@
+[/
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+]
+
+[section:todo Todo]
+
+* provide support for SPARC
+* support split-stack feature from gcc/gold linker
+
+[endsect]
diff --git a/libs/context/example/Jamfile.v2 b/libs/context/example/Jamfile.v2
new file mode 100644
index 0000000000..e08943f9c7
--- /dev/null
+++ b/libs/context/example/Jamfile.v2
@@ -0,0 +1,49 @@
+# Boost.Context Library Examples Jamfile
+
+# Copyright Oliver Kowalke 2009.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+# For more information, see http://www.boost.org/
+
+import common ;
+import feature ;
+import indirect ;
+import modules ;
+import os ;
+import toolset ;
+
+if [ os.name ] = SOLARIS
+{
+ lib socket ;
+ lib nsl ;
+}
+else if [ os.name ] = NT
+{
+ lib ws2_32 ;
+ lib mswsock ;
+}
+else if [ os.name ] = HPUX
+{
+ lib ipv6 ;
+}
+
+project boost/context/example
+ : requirements
+ <library>/boost/context//boost_context
+ <define>BOOST_ALL_NO_LIB=1
+ <link>static
+ ;
+
+exe jump
+ : jump.cpp
+ ;
+
+exe exit
+ : exit.cpp
+ ;
+
+exe transfer
+ : transfer.cpp
+ ;
diff --git a/libs/context/example/exit.cpp b/libs/context/example/exit.cpp
new file mode 100644
index 0000000000..638d9f4a9e
--- /dev/null
+++ b/libs/context/example/exit.cpp
@@ -0,0 +1,57 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/context/all.hpp>
+
+namespace ctx = boost::ctx;
+
+ctx::fcontext_t fc1, fc2;
+
+void f1( intptr_t)
+{
+ std::cout << "f1: entered" << std::endl;
+ std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl;
+ ctx::jump_fcontext( & fc1, & fc2, 0);
+ std::cout << "f1: return" << std::endl;
+}
+
+void f2( intptr_t)
+{
+ std::cout << "f2: entered" << std::endl;
+ std::cout << "f2: call jump_fcontext( & fc2, & fc1, 0)" << std::endl;
+ ctx::jump_fcontext( & fc2, & fc1, 0);
+ BOOST_ASSERT( false && ! "f2: never returns");
+}
+
+int main( int argc, char * argv[])
+{
+ ctx::fcontext_t fcm;
+ 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();
+ ctx::make_fcontext( & fc1, f1);
+
+ fc2.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
+ fc2.fc_stack.limit =
+ static_cast< char * >( fc2.fc_stack.base) - ctx::minimum_stacksize();
+ ctx::make_fcontext( & fc2, f2);
+
+ std::cout << "main: call start_fcontext( & fcm, & fc1, 0)" << std::endl;
+ ctx::jump_fcontext( & fcm, & fc1, 0);
+
+ std::cout << "main: done" << std::endl;
+ BOOST_ASSERT( false && ! "main: never returns");
+
+ return EXIT_SUCCESS;
+}
diff --git a/libs/context/example/jump.cpp b/libs/context/example/jump.cpp
new file mode 100644
index 0000000000..7520b2fcd5
--- /dev/null
+++ b/libs/context/example/jump.cpp
@@ -0,0 +1,56 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/context/all.hpp>
+
+namespace ctx = boost::ctx;
+
+ctx::fcontext_t fcm, fc1, fc2;
+
+void f1( intptr_t)
+{
+ std::cout << "f1: entered" << std::endl;
+ std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl;
+ ctx::jump_fcontext( & fc1, & fc2, 0);
+ std::cout << "f1: return" << std::endl;
+ ctx::jump_fcontext( & fc1, & fcm, 0);
+}
+
+void f2( intptr_t)
+{
+ std::cout << "f2: entered" << std::endl;
+ std::cout << "f2: call jump_fcontext( & fc2, & fc1, 0)" << std::endl;
+ ctx::jump_fcontext( & fc2, & fc1, 0);
+ BOOST_ASSERT( false && ! "f2: never returns");
+}
+
+int main( int argc, char * argv[])
+{
+ ctx::stack_allocator alloc1, alloc2;
+
+ fc1.fc_stack.base = alloc1.allocate(ctx::minimum_stacksize());
+ fc1.fc_stack.limit =
+ static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize();
+ ctx::make_fcontext( & fc1, f1);
+
+ fc2.fc_stack.base = alloc2.allocate(ctx::minimum_stacksize());
+ fc2.fc_stack.limit =
+ static_cast< char * >( fc2.fc_stack.base) - ctx::minimum_stacksize();
+ ctx::make_fcontext( & fc2, f2);
+
+ std::cout << "main: call start_fcontext( & fcm, & fc1, 0)" << std::endl;
+ ctx::jump_fcontext( & fcm, & fc1, 0);
+
+ std::cout << "main: done" << std::endl;
+
+ return EXIT_SUCCESS;
+}
diff --git a/libs/context/example/transfer.cpp b/libs/context/example/transfer.cpp
new file mode 100644
index 0000000000..6837faf01d
--- /dev/null
+++ b/libs/context/example/transfer.cpp
@@ -0,0 +1,51 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <utility>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/context/all.hpp>
+
+namespace ctx = boost::ctx;
+
+ctx::fcontext_t fc1, fcm;
+
+typedef std::pair< int, int > pair_t;
+
+void f1( intptr_t param)
+{
+ pair_t * p = ( pair_t *) param;
+
+ p = ( pair_t *) ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) ( p->first + p->second) );
+
+ ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) ( p->first + p->second) );
+}
+
+int main( int argc, char * argv[])
+{
+ 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();
+ ctx::make_fcontext( & fc1, f1);
+
+ pair_t p( std::make_pair( 2, 7) );
+ 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);
+ res = ( int) ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) & p);
+ std::cout << p.first << " + " << p.second << " == " << res << std::endl;
+
+ std::cout << "main: done" << std::endl;
+
+ return EXIT_SUCCESS;
+}
diff --git a/libs/context/index.html b/libs/context/index.html
new file mode 100644
index 0000000000..0ade6cbd26
--- /dev/null
+++ b/libs/context/index.html
@@ -0,0 +1,14 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="doc/html/index.html">doc/html/index.html</a>
+<hr>
+<p>&copy; Copyright Beman Dawes, 2001</p>
+<p> Distributed under the Boost Software
+License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html>
diff --git a/libs/context/performance/Jamfile.v2 b/libs/context/performance/Jamfile.v2
new file mode 100644
index 0000000000..108c0e1ce1
--- /dev/null
+++ b/libs/context/performance/Jamfile.v2
@@ -0,0 +1,64 @@
+
+# Copyright Oliver Kowalke 2009.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+# For more information, see http://www.boost.org/
+
+import common ;
+import feature ;
+import indirect ;
+import modules ;
+import os ;
+import toolset ;
+
+project boost/context/performance
+ : requirements
+ <library>/boost/context//boost_context
+ <link>static
+ <linkflags>"-lrt"
+ <threading>single
+ ;
+
+alias sources
+ : performance.cpp
+ bind_processor_aix.cpp
+ : <target-os>aix
+ ;
+
+alias sources
+ : performance.cpp
+ bind_processor_freebsd.cpp
+ : <target-os>freebsd
+ ;
+
+alias sources
+ : performance.cpp
+ bind_processor_hpux.cpp
+ : <target-os>hpux
+ ;
+
+alias sources
+ : performance.cpp
+ bind_processor_linux.cpp
+ : <target-os>linux
+ ;
+
+alias sources
+ : performance.cpp
+ bind_processor_solaris.cpp
+ : <target-os>solaris
+ ;
+
+alias sources
+ : performance.cpp
+ bind_processor_windows.cpp
+ : <target-os>windows
+ ;
+
+explicit sources ;
+
+exe performance
+ : sources
+ ;
diff --git a/libs/context/performance/bind_processor.hpp b/libs/context/performance/bind_processor.hpp
new file mode 100644
index 0000000000..f89b507445
--- /dev/null
+++ b/libs/context/performance/bind_processor.hpp
@@ -0,0 +1,12 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BIND_TO_PROCESSOR_H
+#define BIND_TO_PROCESSOR_H
+
+void bind_to_processor( unsigned int n);
+
+#endif // BIND_TO_PROCESSOR_H
diff --git a/libs/context/performance/bind_processor_aix.cpp b/libs/context/performance/bind_processor_aix.cpp
new file mode 100644
index 0000000000..7ddc2eb42c
--- /dev/null
+++ b/libs/context/performance/bind_processor_aix.cpp
@@ -0,0 +1,25 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "bind_processor.hpp"
+
+extern "C"
+{
+#include <sys/processor.h>
+#include <sys/thread.h>
+}
+
+#include <stdexcept>
+
+#include <boost/config/abi_prefix.hpp>
+
+void bind_to_processor( unsigned int n)
+{
+ if ( ::bindprocessor( BINDTHREAD, ::thread_self(), static_cast< cpu_t >( n) ) == -1)
+ throw std::runtime_error("::bindprocessor() failed");
+}
+
+#include <boost/config/abi_suffix.hpp>
diff --git a/libs/context/performance/bind_processor_freebsd.cpp b/libs/context/performance/bind_processor_freebsd.cpp
new file mode 100644
index 0000000000..7e28b70676
--- /dev/null
+++ b/libs/context/performance/bind_processor_freebsd.cpp
@@ -0,0 +1,29 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "bind_processor.hpp"
+
+extern "C"
+{
+#include <sys/param.h>
+#include <sys/cpuset.h>
+}
+
+#include <stdexcept>
+
+#include <boost/config/abi_prefix.hpp>
+
+void bind_to_processor( unsigned int n)
+{
+ cpuset_t cpuset;
+ CPU_ZERO( & cpuset);
+ CPU_SET( n, & cpuset);
+
+ if ( ::cpuset_setaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof( cpuset), & cpuset) == -1)
+ throw std::runtime_error("::cpuset_setaffinity() failed");
+}
+
+#include <boost/config/abi_suffix.hpp>
diff --git a/libs/context/performance/bind_processor_hpux.cpp b/libs/context/performance/bind_processor_hpux.cpp
new file mode 100644
index 0000000000..af33c1125c
--- /dev/null
+++ b/libs/context/performance/bind_processor_hpux.cpp
@@ -0,0 +1,31 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "bind_processor.hpp"
+
+extern "C"
+{
+#include <sys/pthread.h>
+}
+
+#include <stdexcept>
+
+#include <boost/config/abi_prefix.hpp>
+
+void bind_to_processor( unsigned int n)
+{
+ ::pthread_spu_t spu;
+ int errno_(
+ ::pthread_processor_bind_np(
+ PTHREAD_BIND_FORCED_NP,
+ & spu,
+ static_cast< pthread_spu_t >( n),
+ PTHREAD_SELFTID_NP) );
+ if ( errno_ != 0)
+ throw std::runtime_error("::pthread_processor_bind_np() failed");
+}
+
+#include <boost/config/abi_suffix.hpp>
diff --git a/libs/context/performance/bind_processor_linux.cpp b/libs/context/performance/bind_processor_linux.cpp
new file mode 100644
index 0000000000..3fb9588132
--- /dev/null
+++ b/libs/context/performance/bind_processor_linux.cpp
@@ -0,0 +1,30 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "bind_processor.hpp"
+
+extern "C"
+{
+#include <pthread.h>
+#include <sched.h>
+}
+
+#include <stdexcept>
+
+#include <boost/config/abi_prefix.hpp>
+
+void bind_to_processor( unsigned int n)
+{
+ cpu_set_t cpuset;
+ CPU_ZERO( & cpuset);
+ CPU_SET( n, & cpuset);
+
+ int errno_( ::pthread_setaffinity_np( ::pthread_self(), sizeof( cpuset), & cpuset) );
+ if ( errno_ != 0)
+ throw std::runtime_error("::pthread_setaffinity_np() failed");
+}
+
+#include <boost/config/abi_suffix.hpp>
diff --git a/libs/context/performance/bind_processor_solaris.cpp b/libs/context/performance/bind_processor_solaris.cpp
new file mode 100644
index 0000000000..0830c1b453
--- /dev/null
+++ b/libs/context/performance/bind_processor_solaris.cpp
@@ -0,0 +1,26 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "bind_processor.hpp"
+
+extern "C"
+{
+#include <sys/types.h>
+#include <sys/processor.h>
+#include <sys/procset.h>
+}
+
+#include <stdexcept>
+
+#include <boost/config/abi_prefix.hpp>
+
+void bind_to_processor( unsigned int n)
+{
+ if ( ::processor_bind( P_LWPID, P_MYID, static_cast< processorid_t >( n), 0) == -1)
+ throw std::runtime_error("::processor_bind() failed");
+}
+
+#include <boost/config/abi_suffix.hpp>
diff --git a/libs/context/performance/bind_processor_windows.cpp b/libs/context/performance/bind_processor_windows.cpp
new file mode 100644
index 0000000000..6fefbc65f1
--- /dev/null
+++ b/libs/context/performance/bind_processor_windows.cpp
@@ -0,0 +1,24 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "bind_processor.hpp"
+
+extern "C"
+{
+#include <windows.h>
+}
+
+#include <stdexcept>
+
+#include <boost/config/abi_prefix.hpp>
+
+void bind_to_processor( unsigned int n)
+{
+ if ( ::SetThreadAffinityMask( ::GetCurrentThread(), ( DWORD_PTR)1 << n) == 0)
+ throw std::runtime_error("::SetThreadAffinityMask() failed");
+}
+
+#include <boost/config/abi_suffix.hpp>
diff --git a/libs/context/performance/cycle.hpp b/libs/context/performance/cycle.hpp
new file mode 100644
index 0000000000..c26c85983b
--- /dev/null
+++ b/libs/context/performance/cycle.hpp
@@ -0,0 +1,26 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef CYCLE_H
+#define CYCLE_H
+
+// x86_64
+// test x86_64 before i386 because icc might
+// define __i686__ for x86_64 too
+#if defined(__x86_64__) || defined(__x86_64) \
+ || defined(__amd64__) || defined(__amd64) \
+ || defined(_M_X64) || defined(_M_AMD64)
+# include "cycle_x86-64.hpp"
+// i386
+#elif defined(i386) || defined(__i386__) || defined(__i386) \
+ || defined(__i486__) || defined(__i586__) || defined(__i686__) \
+ || defined(__X86__) || defined(_X86_) || defined(__THW_INTEL__) \
+ || defined(__I86__) || defined(__INTEL__) || defined(__IA32__) \
+ || defined(_M_IX86) || defined(_I86_)
+# include "cycle_i386.hpp"
+#endif
+
+#endif // CYCLE_H
diff --git a/libs/context/performance/cycle_i386.hpp b/libs/context/performance/cycle_i386.hpp
new file mode 100644
index 0000000000..3e670077a1
--- /dev/null
+++ b/libs/context/performance/cycle_i386.hpp
@@ -0,0 +1,83 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef CYCLE_I386_H
+#define CYCLE_I386_H
+
+#include <algorithm>
+#include <numeric>
+#include <cstddef>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_CONTEXT_CYCLE
+
+typedef boost::uint64_t cycle_t;
+
+#if _MSC_VER
+inline
+cycle_t cycles()
+{
+ cycle_t c;
+ __asm {
+ cpuid
+ rdtsc
+ mov dword ptr [c + 0], eax
+ mov dword ptr [c + 4], edx
+ }
+ return c;
+}
+#elif defined(__GNUC__) || \
+ defined(__INTEL_COMPILER) || defined(__ICC) || defined(_ECC) || defined(__ICL)
+inline
+cycle_t cycles()
+{
+ boost::uint32_t lo, hi;
+
+ __asm__ __volatile__ (
+ "xorl %%eax, %%eax\n"
+ "cpuid\n"
+ ::: "%eax", "%ebx", "%ecx", "%edx"
+ );
+ __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi) );
+ __asm__ __volatile__ (
+ "xorl %%eax, %%eax\n"
+ "cpuid\n"
+ ::: "%eax", "%ebx", "%ecx", "%edx"
+ );
+
+ return ( cycle_t)hi << 32 | lo;
+}
+#else
+# error "this compiler is not supported"
+#endif
+
+struct measure_cycles
+{
+ cycle_t operator()()
+ {
+ cycle_t start( cycles() );
+ return cycles() - start;
+ }
+};
+
+inline
+cycle_t overhead_cycles()
+{
+ std::size_t iterations( 10);
+ std::vector< cycle_t > overhead( iterations, 0);
+ for ( std::size_t i( 0); i < iterations; ++i)
+ std::generate(
+ overhead.begin(), overhead.end(),
+ measure_cycles() );
+ BOOST_ASSERT( overhead.begin() != overhead.end() );
+ return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
+}
+
+#endif // CYCLE_I386_H
diff --git a/libs/context/performance/cycle_x86-64.hpp b/libs/context/performance/cycle_x86-64.hpp
new file mode 100644
index 0000000000..a2212b8120
--- /dev/null
+++ b/libs/context/performance/cycle_x86-64.hpp
@@ -0,0 +1,79 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef CYCLE_X86_64_H
+#define CYCLE_X86_64_H
+
+#include <algorithm>
+#include <numeric>
+#include <cstddef>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+
+#define BOOST_CONTEXT_CYCLE
+
+typedef boost::uint64_t cycle_t;
+
+#if _MSC_VER >= 1400
+# include <intrin.h>
+# pragma intrinsic(__rdtsc)
+inline
+cycle_t cycles()
+{ return __rdtsc(); }
+#elif defined(__INTEL_COMPILER) || defined(__ICC) || defined(_ECC) || defined(__ICL)
+inline
+cycle_t cycles()
+{ return __rdtsc(); }
+#elif defined(__GNUC__) || defined(__SUNPRO_C)
+inline
+cycle_t cycles()
+{
+ boost::uint32_t lo, hi;
+
+ __asm__ __volatile__ (
+ "xorl %%eax, %%eax\n"
+ "cpuid\n"
+ ::: "%rax", "%rbx", "%rcx", "%rdx"
+ );
+ __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi) );
+ __asm__ __volatile__ (
+ "xorl %%eax, %%eax\n"
+ "cpuid\n"
+ ::: "%rax", "%rbx", "%rcx", "%rdx"
+ );
+
+ return ( cycle_t)hi << 32 | lo;
+}
+#else
+# error "this compiler is not supported"
+#endif
+
+struct measure_cycles
+{
+ cycle_t operator()()
+ {
+ cycle_t start( cycles() );
+ return cycles() - start;
+ }
+};
+
+inline
+cycle_t overhead_cycles()
+{
+ std::size_t iterations( 10);
+ std::vector< cycle_t > overhead( iterations, 0);
+ for ( std::size_t i( 0); i < iterations; ++i)
+ std::generate(
+ overhead.begin(), overhead.end(),
+ measure_cycles() );
+ BOOST_ASSERT( overhead.begin() != overhead.end() );
+ return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
+}
+
+#endif // CYCLE_X86_64_H
diff --git a/libs/context/performance/performance.cpp b/libs/context/performance/performance.cpp
new file mode 100644
index 0000000000..f6461e1fb0
--- /dev/null
+++ b/libs/context/performance/performance.cpp
@@ -0,0 +1,262 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_PP_LIMIT_MAG 10
+
+#include <cstdio>
+#include <cstdlib>
+#include <iostream>
+#include <stdexcept>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#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>
+#endif
+
+#include "bind_processor.hpp"
+#include "cycle.hpp"
+
+#if _POSIX_C_SOURCE >= 199309L
+#include "zeit.hpp"
+#endif
+
+namespace ctx = boost::ctx;
+
+bool preserve_fpu = false;
+
+#define CALL_FUNCTION(z,n,unused) \
+ fn();
+
+#define CALL_UCONTEXT(z,n,unused) \
+ ::swapcontext( & ucm, & uc);
+
+#define CALL_FCONTEXT(z,n,unused) \
+ ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
+
+#ifndef BOOST_WINDOWS
+ucontext_t uc, ucm;
+#endif
+ctx::fcontext_t fc, fcm;
+
+static void f3()
+{ }
+
+#ifndef BOOST_WINDOWS
+static void f2()
+{
+ while ( true)
+ ::swapcontext( & uc, & ucm);
+}
+#endif
+
+static void f1( intptr_t)
+{
+ while ( true)
+ ctx::jump_fcontext( & fc, & fcm, 7, preserve_fpu);
+}
+
+#ifdef BOOST_CONTEXT_CYCLE
+cycle_t test_function_cycle( cycle_t ov)
+{
+ boost::function< void() > fn( boost::bind( f3) );
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~)
+
+ cycle_t start( cycles() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~)
+ cycle_t total( cycles() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+
+#ifndef BOOST_WINDOWS
+cycle_t test_ucontext_cycle( cycle_t ov)
+{
+ ctx::stack_allocator alloc;
+
+ ::getcontext( & uc);
+ uc.uc_stack.ss_sp =
+ static_cast< char * >( alloc.allocate(ctx::default_stacksize() ) )
+ - ctx::default_stacksize();
+ uc.uc_stack.ss_size = ctx::default_stacksize();
+ ::makecontext( & uc, f2, 7);
+
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~)
+
+ cycle_t start( cycles() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~)
+ cycle_t total( cycles() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+#endif
+
+cycle_t test_fcontext_cycle( cycle_t ov)
+{
+ ctx::stack_allocator alloc;
+ 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);
+
+ ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
+
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
+
+ cycle_t start( cycles() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
+ cycle_t total( cycles() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+#endif
+
+#if _POSIX_C_SOURCE >= 199309L
+zeit_t test_function_zeit( zeit_t ov)
+{
+ boost::function< void() > fn( boost::bind( f3) );
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~)
+
+ zeit_t start( zeit() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~)
+ zeit_t total( zeit() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+
+#ifndef BOOST_WINDOWS
+zeit_t test_ucontext_zeit( zeit_t ov)
+{
+ ctx::stack_allocator alloc;
+
+ ::getcontext( & uc);
+ uc.uc_stack.ss_sp =
+ static_cast< char * >( alloc.allocate(ctx::default_stacksize() ) )
+ - ctx::default_stacksize();
+ uc.uc_stack.ss_size = ctx::default_stacksize();
+ ::makecontext( & uc, f2, 7);
+
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~)
+
+ zeit_t start( zeit() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~)
+ zeit_t total( zeit() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+#endif
+
+zeit_t test_fcontext_zeit( zeit_t ov)
+{
+ ctx::stack_allocator alloc;
+ 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);
+
+ ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
+
+ // cache warum-up
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
+
+ zeit_t start( zeit() );
+BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
+ zeit_t total( zeit() - start);
+
+ // we have two jumps and two measuremt-overheads
+ total -= ov; // overhead of measurement
+ total /= BOOST_PP_LIMIT_MAG; // per call
+ total /= 2; // 2x jump_to c1->c2 && c2->c1
+
+ return total;
+}
+#endif
+
+int main( int argc, char * argv[])
+{
+ try
+ {
+ bind_to_processor( 0);
+
+#ifdef BOOST_CONTEXT_CYCLE
+ {
+ cycle_t ov( overhead_cycles() );
+ std::cout << "overhead for rdtsc == " << ov << " cycles" << std::endl;
+
+ unsigned int res = test_fcontext_cycle( ov);
+ std::cout << "fcontext: average of " << res << " cycles per switch" << std::endl;
+#ifndef BOOST_WINDOWS
+ res = test_ucontext_cycle( ov);
+ std::cout << "ucontext: average of " << res << " cycles per switch" << std::endl;
+#endif
+ res = test_function_cycle( ov);
+ std::cout << "boost::function: average of " << res << " cycles per switch" << std::endl;
+ }
+#endif
+
+#if _POSIX_C_SOURCE >= 199309L
+ {
+ zeit_t ov( overhead_zeit() );
+ std::cout << "\noverhead for clock_gettime() == " << ov << " ns" << std::endl;
+
+ unsigned int res = test_fcontext_zeit( ov);
+ std::cout << "fcontext: average of " << res << " ns per switch" << std::endl;
+#ifndef BOOST_WINDOWS
+ res = test_ucontext_zeit( ov);
+ std::cout << "ucontext: average of " << res << " ns per switch" << std::endl;
+#endif
+ res = test_function_zeit( ov);
+ std::cout << "boost::function: average of " << res << " ns per switch" << std::endl;
+ }
+#endif
+
+ return EXIT_SUCCESS;
+ }
+ catch ( std::exception const& e)
+ { std::cerr << "exception: " << e.what() << std::endl; }
+ catch (...)
+ { std::cerr << "unhandled exception" << std::endl; }
+ return EXIT_FAILURE;
+}
+
+#undef CALL_FCONTEXT
+#undef CALL_UCONTEXT
diff --git a/libs/context/performance/zeit.hpp b/libs/context/performance/zeit.hpp
new file mode 100644
index 0000000000..2c082bf220
--- /dev/null
+++ b/libs/context/performance/zeit.hpp
@@ -0,0 +1,53 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef ZEIT_H
+#define ZEIT_H
+
+#include <time.h>
+
+#include <algorithm>
+#include <numeric>
+#include <cstddef>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+
+typedef boost::uint64_t zeit_t;
+
+inline
+zeit_t zeit()
+{
+ timespec t;
+ ::clock_gettime( CLOCK_PROCESS_CPUTIME_ID, & t);
+ return t.tv_sec * 1000000000 + t.tv_nsec;
+}
+
+struct measure_zeit
+{
+ zeit_t operator()()
+ {
+ zeit_t start( zeit() );
+ return zeit() - start;
+ }
+};
+
+inline
+zeit_t overhead_zeit()
+{
+ std::size_t iterations( 10);
+ std::vector< zeit_t > overhead( iterations, 0);
+ for ( std::size_t i( 0); i < iterations; ++i)
+ std::generate(
+ overhead.begin(), overhead.end(),
+ measure_zeit() );
+ BOOST_ASSERT( overhead.begin() != overhead.end() );
+ return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations;
+}
+
+#endif // ZEIT_H
diff --git a/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S b/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S
new file mode 100644
index 0000000000..7724441c5b
--- /dev/null
+++ b/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S
@@ -0,0 +1,101 @@
+/*
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/*******************************************************************
+ * *
+ * ------------------------------------------------------------- *
+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *
+ * ------------------------------------------------------------- *
+ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| 0x20| 0x24| *
+ * ------------------------------------------------------------- *
+ * | v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8 | sp | lr | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 10 | | *
+ * ------------------------------------------------------------- *
+ * | 0x28| | *
+ * ------------------------------------------------------------- *
+ * | pc | | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 11 | 12 | | *
+ * ------------------------------------------------------------- *
+ * | 0x2c| 0x30| | *
+ * ------------------------------------------------------------- *
+ * |sbase|slimit| | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | *
+ * ------------------------------------------------------------- *
+ * | 0x34| 0x38|0x3c| 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58 | *
+ * ------------------------------------------------------------- *
+ * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | s24 | s25 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 23 | 24 | 25 | 26 | 27 | 28 | | *
+ * ------------------------------------------------------------- *
+ * | 0x5c| 0x60| 0x64| 0x68| 0x6c| 0x70| | *
+ * ------------------------------------------------------------- *
+ * | s26 | s27 | s28 | s29 | s30 | s31 | | *
+ * ------------------------------------------------------------- *
+ * *
+ * *****************************************************************/
+
+.text
+.globl jump_fcontext
+.align 2
+.type jump_fcontext,%function
+jump_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__))
+ cmp a4, #0 @ test if fpu env should be preserved
+ beq 1f
+
+ mov a4, a1
+ add a4, #52
+ fstmiax a4, {d8-d15} @ save S16-S31
+
+ mov a4, a2
+ add a4, #52
+ fldmiax a4, {d8-d15} @ restore S16-S31
+1:
+#endif
+
+ mov a1, a3 @ use third arg as return value after jump
+ @ and as first arg in context function
+ ldmia a2, {v1-v8,sp-pc} @ restore v1-V8,SP-PC
+.size jump_fcontext,.-jump_fcontext
+
+.text
+.globl make_fcontext
+.align 2
+.type make_fcontext,%function
+make_fcontext:
+ str a1, [a1,#0] @ save the address of passed context
+ str a2, [a1,#40] @ save address of the context function
+ ldr a2, [a1,#44] @ load the stack base
+
+ push {a1,lr} @ save pointer to fcontext_t
+ mov a1, a2 @ stack pointer as arg for align_stack
+ bl align_stack@PLT @ align stack
+ mov a2, a1 @ begin of aligned stack
+ pop {a1,lr} @ restore pointer to fcontext_t
+
+ str a2, [a1,#32] @ save the aligned stack base
+
+ adr a2, finish @ address of finish; called after context function returns
+ str a2, [a1,#36]
+
+ mov a1, #0
+ bx lr
+
+finish:
+ mov a1, #0 @ exit code is zero
+ bl _exit@PLT @ exit application
+.size make_fcontext,.-make_fcontext
diff --git a/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm b/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm
new file mode 100644
index 0000000000..0f4dd671b1
--- /dev/null
+++ b/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm
@@ -0,0 +1,151 @@
+
+; Copyright Oliver Kowalke 2009.
+; Distributed under the Boost Software License, Version 1.0.
+; (See accompanying file LICENSE_1_0.txt or copy at
+; http://www.boost.org/LICENSE_1_0.txt)
+
+; --------------------------------------------------------------
+; | 0 | 1 | 2 | 3 | 4 | 5 |
+; --------------------------------------------------------------
+; | 0h | 04h | 08h | 0ch | 010h | 014h |
+; --------------------------------------------------------------
+; | EDI | ESI | EBX | EBP | ESP | EIP |
+; --------------------------------------------------------------
+; --------------------------------------------------------------
+; | 6 | 7 | |
+; --------------------------------------------------------------
+; | 018h | 01ch | |
+; --------------------------------------------------------------
+; | ss_base | ss_limit| |
+; --------------------------------------------------------------
+; --------------------------------------------------------------
+; | 8 | |
+; --------------------------------------------------------------
+; | 020h | |
+; --------------------------------------------------------------
+; |fc_execpt| |
+; --------------------------------------------------------------
+; --------------------------------------------------------------
+; | 9 | |
+; --------------------------------------------------------------
+; | 024h | |
+; --------------------------------------------------------------
+; |fc_strage| |
+; --------------------------------------------------------------
+; --------------------------------------------------------------
+; | 10 | 11 | |
+; --------------------------------------------------------------
+; | 028h | 02ch | |
+; --------------------------------------------------------------
+; | fc_mxcsr|fc_x87_cw| |
+; --------------------------------------------------------------
+
+.386
+.XMM
+.model flat, c
+_exit PROTO, value:SDWORD
+align_stack PROTO, vp:DWORD
+seh_fcontext PROTO, except:DWORD, frame:DWORD, context:DWORD, dispatch:DWORD
+.code
+
+jump_fcontext PROC EXPORT
+ mov ecx, [esp+04h] ; load address of the first fcontext_t arg
+ mov [ecx], edi ; save EDI
+ mov [ecx+04h], esi ; save ESI
+ mov [ecx+08h], ebx ; save EBX
+ mov [ecx+0ch], ebp ; save EBP
+
+ assume fs:nothing
+ mov edx, fs:[018h] ; load NT_TIB
+ assume fs:error
+ mov eax, [edx] ; load current SEH exception list
+ mov [ecx+020h], eax ; save current exception list
+ mov eax, [edx+04h] ; load current stack base
+ mov [ecx+018h], eax ; save current stack base
+ mov eax, [edx+08h] ; load current stack limit
+ mov [ecx+01ch], eax ; save current stack limit
+ mov eax, [edx+010h] ; load fiber local storage
+ mov [ecx+024h], eax ; save fiber local storage
+
+ lea eax, [esp+04h] ; exclude the return address
+ mov [ecx+010h], eax ; save as stack pointer
+ mov eax, [esp] ; load return address
+ mov [ecx+014h], eax ; save return address
+
+ mov edx, [esp+08h] ; load address of the second fcontext_t arg
+ mov edi, [edx] ; restore EDI
+ mov esi, [edx+04h] ; restore ESI
+ mov ebx, [edx+08h] ; restore EBX
+ mov ebp, [edx+0ch] ; restore EBP
+
+ mov eax, [esp+010h] ; check if fpu enve preserving was requested
+ test eax, eax
+ je nxt
+
+ stmxcsr [ecx+028h] ; save MMX control word
+ fnstcw [ecx+02ch] ; save x87 control word
+ ldmxcsr [edx+028h] ; restore MMX control word
+ fldcw [edx+02ch] ; restore x87 control word
+nxt:
+ mov ecx, edx
+ assume fs:nothing
+ mov edx, fs:[018h] ; load NT_TIB
+ assume fs:error
+ mov eax, [ecx+020h] ; load SEH exception list
+ mov [edx], eax ; restore next SEH item
+ mov eax, [ecx+018h] ; load stack base
+ mov [edx+04h], eax ; restore stack base
+ mov eax, [ecx+01ch] ; load stack limit
+ mov [edx+08h], eax ; restore stack limit
+ mov eax, [ecx+024h] ; load fiber local storage
+ mov [edx+010h], eax ; restore fiber local storage
+
+ mov eax, [esp+0ch] ; use third arg as return value after jump
+
+ mov esp, [ecx+010h] ; restore ESP
+ mov [esp+04h], eax ; use third arg as first arg in context function
+ mov ecx, [ecx+014h] ; fetch the address to return to
+
+ jmp ecx ; indirect jump to context
+jump_fcontext ENDP
+
+make_fcontext PROC EXPORT
+ mov eax, [esp+04h] ; load address of the fcontext_t arg0
+ mov [eax], eax ; save the address of passed context
+ mov ecx, [esp+08h] ; load the address of the context function
+ mov [eax+014h], ecx ; save the address of the context function
+ mov edx, [eax+018h] ; load the stack base
+
+ push eax ; save pointer to fcontext_t
+ push edx ; stack pointer as arg for align_stack
+ call align_stack ; align stack
+ mov edx, eax ; begin of aligned stack
+ pop eax ; remove arg for align_stack
+ pop eax ; restore pointer to fcontext_t
+
+ lea edx, [edx-014h] ; reserve space for last frame on stack, (ESP + 4) & 15 == 0
+ mov [eax+010h], edx ; save the aligned stack
+
+ mov ecx, seh_fcontext ; set ECX to exception-handler
+ mov [edx+0ch], ecx ; save ECX as SEH handler
+ mov ecx, 0ffffffffh ; set ECX to -1
+ mov [edx+08h], ecx ; save ECX as next SEH item
+ lea ecx, [edx+08h] ; load address of next SEH item
+ mov [eax+02ch], ecx ; save next SEH
+
+ stmxcsr [eax+028h] ; save MMX control word
+ fnstcw [eax+02ch] ; save x87 control word
+
+ mov ecx, finish ; address of finish
+ mov [edx], ecx
+
+ xor eax, eax
+ ret
+
+finish:
+ xor eax, eax
+ push eax ; exit code is zero
+ call _exit ; exit application
+ hlt
+make_fcontext ENDP
+END
diff --git a/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S b/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S
new file mode 100644
index 0000000000..7c94ea068d
--- /dev/null
+++ b/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S
@@ -0,0 +1,122 @@
+/*
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/********************************************************************
+ * *
+ * -------------------------------------------------------------- *
+ * | 0 | 1 | 2 | 3 | 4 | 5 | *
+ * -------------------------------------------------------------- *
+ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | *
+ * -------------------------------------------------------------- *
+ * | EDI | ESI | EBX | EBP | ESP | EIP | *
+ * -------------------------------------------------------------- *
+ * -------------------------------------------------------------- *
+ * | 6 | 7 | | *
+ * -------------------------------------------------------------- *
+ * | 0x18 | 0x1c | | *
+ * -------------------------------------------------------------- *
+ * | sbase | slimit | | *
+ * -------------------------------------------------------------- *
+ * -------------------------------------------------------------- *
+ * | 8 | 9 | | *
+ * -------------------------------------------------------------- *
+ * | 0x20 | 0x24 | | *
+ * -------------------------------------------------------------- *
+ * | fc_mxcsr|fc_x87_cw| | *
+ * -------------------------------------------------------------- *
+ * *
+ * *****************************************************************/
+
+.text
+.globl jump_fcontext
+.align 2
+.type jump_fcontext,@function
+jump_fcontext:
+ movl 0x4(%esp), %ecx /* load address of the first fcontext_t arg */
+ movl %edi, (%ecx) /* save EDI */
+ movl %esi, 0x4(%ecx) /* save ESI */
+ movl %ebx, 0x8(%ecx) /* save EBX */
+ movl %ebp, 0xc(%ecx) /* save EBP */
+
+ leal 0x4(%esp), %eax /* exclude the return address */
+ movl %eax, 0x10(%ecx) /* save as stack pointer */
+ movl (%esp), %eax /* load return address */
+ movl %eax, 0x14(%ecx) /* save return address */
+
+ movl 0x8(%esp), %edx /* load address of the second fcontext_t arg */
+ movl (%edx), %edi /* restore EDI */
+ movl 0x4(%edx), %esi /* restore ESI */
+ movl 0x8(%edx), %ebx /* restore EBX */
+ movl 0xc(%edx), %ebp /* restore EBP */
+
+ movl 0x10(%esp), %eax /* check if fpu enve preserving was requested */
+ test %eax, %eax
+ je 1f
+
+ stmxcsr 0x20(%ecx) /* save MMX control and status word */
+ fnstcw 0x24(%ecx) /* save x87 control word */
+ ldmxcsr 0x20(%edx) /* restore MMX control and status word */
+ fldcw 0x24(%edx) /* restore x87 control word */
+1:
+ movl 0xc(%esp), %eax /* use third arg as return value after jump */
+
+ movl 0x10(%edx), %esp /* restore ESP */
+ movl %eax, 0x4(%esp) /* use third arg as first arg in context function */
+ movl 0x14(%edx), %edx /* fetch the address to return to */
+
+ jmp *%edx /* indirect jump to context */
+.size jump_fcontext,.-jump_fcontext
+
+.text
+.globl make_fcontext
+.align 2
+.type make_fcontext,@function
+make_fcontext:
+ movl 0x4(%esp), %eax /* load address of the fcontext_t */
+ movl %eax, (%eax) /* save the address of current context */
+ movl 0x8(%esp), %ecx /* load the address of the context function */
+ movl %ecx, 0x14(%eax) /* save the address of the context function */
+ movl 0x18(%eax), %edx /* load the stack base */
+
+ pushl %eax /* save pointer to fcontext_t */
+ pushl %ebx /* save EBX */
+ pushl %edx /* stack pointer as arg for align_stack */
+ call 1f
+1: popl %ebx /* address of label 1 */
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx /* compute address of GOT and store it in EBX */
+ call align_stack@PLT /* align stack */
+ movl %eax, %edx /* begin of aligned stack */
+ popl %eax /* remove arg for align_stack */
+ popl %ebx /* restore EBX */
+ popl %eax /* restore pointer to fcontext_t */
+
+ leal -0x14(%edx), %edx /* reserve space for the last frame on stack, (ESP + 4) % 16 == 0 */
+ movl %edx, 0x10(%eax) /* save the aligned stack base */
+
+ stmxcsr 0x20(%eax) /* save MMX control and status word */
+ fnstcw 0x24(%eax) /* save x87 control word */
+
+ call 2f
+2: popl %ecx /* address of label 2 */
+ addl $finish-2b, %ecx /* helper code executed after context function returns */
+ movl %ecx, (%edx)
+
+ xorl %eax, %eax
+ ret
+
+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 */
+
+ xorl %eax, %eax
+ pushl %eax /* exit code is zero */
+ call _exit@PLT /* exit application */
+ hlt
+.size make_fcontext,.-make_fcontext
diff --git a/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S b/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S
new file mode 100644
index 0000000000..a28c87576a
--- /dev/null
+++ b/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S
@@ -0,0 +1,118 @@
+/*
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/********************************************************************
+ * *
+ * -------------------------------------------------------------- *
+ * | 0 | 1 | 2 | 3 | 4 | 5 | *
+ * -------------------------------------------------------------- *
+ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | *
+ * -------------------------------------------------------------- *
+ * | EDI | ESI | EBX | EBP | ESP | EIP | *
+ * -------------------------------------------------------------- *
+ * -------------------------------------------------------------- *
+ * | 6 | 7 | | *
+ * -------------------------------------------------------------- *
+ * | 0x18 | 0x1c | | *
+ * -------------------------------------------------------------- *
+ * | sbase | slimit | | *
+ * -------------------------------------------------------------- *
+ * -------------------------------------------------------------- *
+ * | 8 | 9 | | *
+ * -------------------------------------------------------------- *
+ * | 0x20 | 0x24 | | *
+ * -------------------------------------------------------------- *
+ * | fc_mxcsr|fc_x87_cw| | *
+ * -------------------------------------------------------------- *
+ * *
+ * *****************************************************************/
+
+.text
+.globl _jump_fcontext
+.align 2
+_jump_fcontext:
+ movl 0x4(%esp), %ecx /* load address of the first fcontext_t arg */
+ movl %edi, (%ecx) /* save EDI */
+ movl %esi, 0x4(%ecx) /* save ESI */
+ movl %ebx, 0x8(%ecx) /* save EBX */
+ movl %ebp, 0xc(%ecx) /* save EBP */
+
+ leal 0x4(%esp), %eax /* exclude the return address */
+ movl %eax, 0x10(%ecx) /* save as stack pointer */
+ movl (%esp), %eax /* load return address */
+ movl %eax, 0x14(%ecx) /* save return address */
+
+ movl 0x8(%esp), %edx /* load address of the second fcontext_t arg */
+ movl (%edx), %edi /* restore EDI */
+ movl 0x4(%edx), %esi /* restore ESI */
+ movl 0x8(%edx), %ebx /* restore EBX */
+ movl 0xc(%edx), %ebp /* restore EBP */
+
+ movl 0x10(%esp), %eax /* check if fpu enve preserving was requested */
+ test %eax, %eax
+ je 1f
+
+ stmxcsr 0x20(%ecx) /* save MMX control and status word */
+ fnstcw 0x24(%ecx) /* save x87 control word */
+ ldmxcsr 0x20(%edx) /* restore MMX control and status word */
+ fldcw 0x24(%edx) /* restore x87 control word */
+1:
+ movl 0xc(%esp), %eax /* use third arg as return value after jump */
+
+ movl 0x10(%edx), %esp /* restore ESP */
+ movl %eax, 0x4(%esp) /* use third arg as first arg in context function */
+ movl 0x14(%edx), %edx /* fetch the address to return to */
+
+ jmp *%edx /* indirect jump to context */
+
+.text
+.globl _make_fcontext
+.align 2
+_make_fcontext:
+ movl 0x4(%esp), %eax /* load address of the fcontext_t */
+ movl %eax, (%eax) /* save the address of current context */
+ movl 0x8(%esp), %ecx /* load the address of the context function */
+ movl %ecx, 0x14(%eax) /* save the address of the context function */
+ movl 0x18(%eax), %edx /* load the stack base */
+
+ pushl %eax /* save pointer to fcontext_t */
+ pushl %ebx /* save EBX */
+ pushl %edx /* stack pointer as arg for align_stack */
+ call 1f
+1: popl %ebx /* address of label 1 */
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx /* compute address of GOT and store it in EBX */
+ call align_stack@PLT /* align stack */
+ movl %eax, %edx /* begin of aligned stack */
+ popl %eax /* remove arg for align_stack */
+ popl %ebx /* restore EBX */
+ popl %eax /* restore pointer to fcontext_t */
+
+ leal -0x14(%edx), %edx /* reserve space for the last frame on stack, (ESP + 4) % 16 == 0 */
+ movl %edx, 0x10(%eax) /* save the aligned stack base */
+
+ stmxcsr 0x20(%eax) /* save MMX control and status word */
+ fnstcw 0x24(%eax) /* save x87 control word */
+
+ call 2f
+2: popl %ecx /* address of label 2 */
+ addl $finish-2b, %ecx /* helper code executed after context function returns */
+ movl %ecx, (%edx)
+
+ xorl %eax, %eax
+ ret
+
+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 */
+
+ xorl %eax, %eax
+ pushl %eax /* exit code is zero */
+ call _exit@PLT /* exit application */
+ hlt
diff --git a/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S b/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S
new file mode 100644
index 0000000000..be86f185ec
--- /dev/null
+++ b/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S
@@ -0,0 +1,144 @@
+/*
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/*******************************************************************
+ * *
+ * ------------------------------------------------------------- *
+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *
+ * ------------------------------------------------------------- *
+ * | 0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | *
+ * ------------------------------------------------------------- *
+ * | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | GP | SP | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 10 | 11 | 12 | | *
+ * ------------------------------------------------------------- *
+ * | 80 | 88 | 96 | | *
+ * ------------------------------------------------------------- *
+ * | S8 | RA | PC | | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 13 | 14 | | *
+ * ------------------------------------------------------------- *
+ * | 104 | 112 | | *
+ * ------------------------------------------------------------- *
+ * |sbase|slimt| | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 15 | 16 | 17 | 18 | 19 | 20 | | *
+ * ------------------------------------------------------------- *
+ * | 120 | 128 | 136 | 144 | 152 | 160 | | *
+ * ------------------------------------------------------------- *
+ * | F20 | F22 | F24 | F26 | F28 | F30 | | *
+ * ------------------------------------------------------------- *
+ * *
+ * *****************************************************************/
+
+.text
+.globl jump_fcontext
+.align 2
+.type jump_fcontext,@function
+.ent jump_fcontext
+jump_fcontext:
+ sw $s0, ($a0) # save S0
+ sw $s1, 8($a0) # save S1
+ sw $s2, 16($a0) # save S2
+ sw $s3, 24($a0) # save S3
+ sw $s4, 32($a0) # save S4
+ sw $s5, 40($a0) # save S5
+ sw $s6, 48($a0) # save S6
+ sw $s7, 56($a0) # save S7
+ sw $gp, 64($a0) # save GP
+ sw $sp, 72($a0) # save SP
+ sw $s8, 80($a0) # save S8
+ sw $ra, 88($a0) # save RA
+ sw $ra, 96($a0) # save RA as PC
+
+#if defined(__mips_hard_float)
+ beqz $a3, 1f # test if fpu env should be preserved
+ s.d $f20, 120($a0) # save F20
+ s.d $f22, 128($a0) # save F22
+ s.d $f24, 136($a0) # save F24
+ s.d $f26, 144($a0) # save F26
+ s.d $f28, 152($a0) # save F28
+ s.d $f30, 160($a0) # save F30
+
+ l.d $f20, 120($a1) # restore F20
+ l.d $f22, 128($a1) # restore F22
+ l.d $f24, 136($a1) # restore F24
+ l.d $f26, 144($a1) # restore F26
+ l.d $f28, 152($a1) # restore F28
+ l.d $f30, 160($a1) # restore F30
+1:
+#endif
+
+ lw $s0, ($a1) # restore S0
+ lw $s1, 8($a1) # restore S1
+ lw $s2, 16($a1) # restore S2
+ lw $s3, 24($a1) # restore S3
+ lw $s4, 32($a1) # restore S4
+ lw $s5, 40($a1) # restore S5
+ lw $s6, 48($a1) # restore S6
+ lw $s7, 56($a1) # restore S7
+ lw $gp, 64($a1) # restore GP
+ lw $sp, 72($a1) # restore SP
+ lw $s8, 80($a1) # restore S8
+ lw $ra, 88($a1) # restore RA
+ move $a0, $s2 # restore void pointer as argument
+
+ 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
+.end jump_fcontext
+.size jump_fcontext, .-jump_fcontext
+
+.text
+.globl make_fcontext
+.align 2
+.type make_fcontext,@function
+.ent make_fcontext
+make_fcontext:
+#ifdef __PIC__
+.set noreorder
+.cpload $t9
+.set reorder
+#endif
+ sw $a0, ($a0) # save the current context
+ sw $gp, 24($a0) # save global pointer
+ sw $a1, 96($a0) # save the address of the context function
+ lw $t0, 104($a0) # load the stack base
+
+ sub $sp, $sp, 28
+ sw $ra, 24($sp)
+ sw $a0, 20($sp)
+ move $a0, $t0 # stack pointer as arg for align_stack
+ lw $t9, %call16(align_stack)($gp) # align stack
+ jalr $t9
+ nop
+ move $t0, $v0 # begin of aligned stack
+ lw $ra, 24($sp)
+ lw $a0, 20($sp)
+ addi $sp, $sp, 28
+
+ sub $t0, $t0, 16 # reserve 16 byte of argument space
+ sw $t0, 72($a0) # save the algned stack base
+
+ la $t9, finish # helper code executed after context function returns
+ sw $t9, 88($a0)
+
+ move $v0, $zero
+ jr $ra
+
+finish:
+ move $gp, $s3 # restore GP (global pointer)
+ move $a0, $zero # exit code is zero
+ lw $t9, %call16(_exit)($gp) # exit application
+ jalr $t9
+.end make_fcontext
+.size make_fcontext, .-make_fcontext
diff --git a/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S b/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S
new file mode 100644
index 0000000000..69b6ed90b5
--- /dev/null
+++ b/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S
@@ -0,0 +1,222 @@
+/*
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/*******************************************************************
+ * *
+ * ------------------------------------------------------------- *
+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *
+ * ------------------------------------------------------------- *
+ * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | 32 | 36 | *
+ * ------------------------------------------------------------- *
+ * | R13 | R14 | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | *
+ * ------------------------------------------------------------- *
+ * | 40 | 44 | 48 | 52 | 56 | 60 | 64 | 68 | 72 | 76 | *
+ * ------------------------------------------------------------- *
+ * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | R31 | SP | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 20 | 21 | 22 | | *
+ * ------------------------------------------------------------- *
+ * | 80 | 84 | 88 | | *
+ * ------------------------------------------------------------- *
+ * | CR | LR | PC | | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 23 | 24 | | *
+ * ------------------------------------------------------------- *
+ * | 92 | 96 | | *
+ * ------------------------------------------------------------- *
+ * |sbase|slimt| | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | *
+ * ------------------------------------------------------------- *
+ * | 100 | 104 | 108 | 112 | 116 | 120 | 124 | 128 | 132 | 136 | *
+ * ------------------------------------------------------------- *
+ * | F14 | F15 | F16 | F17 | F18 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | *
+ * ------------------------------------------------------------- *
+ * | 140 | 144 | 148 | 152 | 156 | 160 | 164 | 168 | 172 | 176 | *
+ * ------------------------------------------------------------- *
+ * | F19 | F20 | F21 | F22 | F23 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | *
+ * ------------------------------------------------------------- *
+ * | 180 | 184 | 188 | 192 | 196 | 200 | 204 | 208 | 212 | 216 | *
+ * ------------------------------------------------------------- *
+ * | F24 | F25 | F26 | F27 | F28 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | | *
+ * ------------------------------------------------------------- *
+ * | 220 | 224 | 228 | 232 | 236 | 240 | 244 | 248 | | *
+ * ------------------------------------------------------------- *
+ * | F29 | F30 | F31 | fpscr | | *
+ * ------------------------------------------------------------- *
+ * *
+ * *****************************************************************/
+
+.text
+.globl jump_fcontext
+.align 2
+.type jump_fcontext,@function
+jump_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
+
+ cmpwi cr7, %r6, 0 # test if fpu env should be preserved
+ beq cr7, 1f
+
+ stfd %f14, 100(%r3) # save F14
+ stfd %f15, 108(%r3) # save F15
+ stfd %f16, 116(%r3) # save F16
+ stfd %f17, 124(%r3) # save F17
+ stfd %f18, 132(%r3) # save F18
+ stfd %f19, 140(%r3) # save F19
+ stfd %f20, 148(%r3) # save F20
+ stfd %f21, 156(%r3) # save F21
+ stfd %f22, 164(%r3) # save F22
+ stfd %f23, 172(%r3) # save F23
+ stfd %f24, 180(%r3) # save F24
+ stfd %f25, 188(%r3) # save F25
+ stfd %f26, 196(%r3) # save F26
+ stfd %f27, 204(%r3) # save F27
+ stfd %f28, 212(%r3) # save F28
+ stfd %f29, 220(%r3) # save F29
+ stfd %f30, 228(%r3) # save F30
+ stfd %f31, 236(%r3) # save F31
+ mffs %f0 # load FPSCR
+ stfd %f0, 244(%r3) # save FPSCR
+
+ lfd %f14, 100(%r4) # restore F14
+ lfd %f15, 108(%r4) # restore F15
+ lfd %f16, 116(%r4) # restore F16
+ lfd %f17, 124(%r4) # restore F17
+ lfd %f18, 132(%r4) # restore F18
+ lfd %f19, 140(%r4) # restore F19
+ lfd %f20, 148(%r4) # restore F20
+ lfd %f21, 156(%r4) # restore F21
+ lfd %f22, 164(%r4) # restore F22
+ lfd %f23, 172(%r4) # restore F23
+ lfd %f24, 180(%r4) # restore F24
+ lfd %f25, 188(%r4) # restore F25
+ lfd %f26, 196(%r4) # restore F26
+ lfd %f27, 204(%r4) # restore F27
+ lfd %f28, 212(%r4) # restore F28
+ lfd %f29, 220(%r4) # restore F29
+ lfd %f30, 228(%r4) # restore F30
+ lfd %f31, 236(%r4) # restore F31
+ lfd %f0, 244(%r4) # load FPSCR
+ mtfsf 0xff, %f0 # restore FPSCR
+1:
+
+ 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
+
+ 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
+
+ bctr # jump to context
+.size jump_fcontext, .-jump_fcontext
+
+.text
+.globl make_fcontext
+.align 2
+.type make_fcontext,@function
+make_fcontext:
+ stw %r3, 0(%r3) # save the current context
+ stw %r4, 88(%r3) # save the address of the context function
+ lwz %r0, 92(%r3) # load the stack base
+
+ li %r4, 28
+ subf %r1, %r4, %r1 # reserve space on stack
+ stw %r3, 24(%r1) # store pointer to fcontext_t on stack
+ mflr %r4 # load LR
+ stw %r4, 20(%r1) # store LR on stack
+ mr. %r3, %r0 # context stack as arg to align_stack
+ bl align_stack@plt # call align_stack
+ mr. %r0, %r3 # load result into R0
+ lwz %r4, 20(%r1) # pop LR from stack
+ mtlr %r4 # restore LR
+ lwz %r3, 24(%r1) # pop pointer to fcontext_t from stack
+ addi %r1, %r1, 28 # release space on stack
+
+ li %r4, 32
+ subf %r0, %r4, %r0 # 32 bytes on stack for parameter area(== 8 registers)
+ stw %r0, 76(%r3) # save the aligned stack base
+
+ mflr %r0 # load LR
+ bl 1f # jump to label 1
+1:
+ mflr %r4 # load LR
+ addi %r4, %r4, finish - 1b # address of finish; called after context function returns
+ mtlr %r0 # restore LR
+ stw %r4, 84(%r3)
+
+ li %r3, 0
+ blr
+
+finish:
+ li %r3, 0 # exit code is zero
+ bl _exit@plt # exit application
+.size make_fcontext, .-make_fcontext
diff --git a/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S b/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S
new file mode 100644
index 0000000000..0fcb387355
--- /dev/null
+++ b/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S
@@ -0,0 +1,250 @@
+/*
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/*******************************************************************
+ * *
+ * ------------------------------------------------------------- *
+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *
+ * ------------------------------------------------------------- *
+ * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | 32 | 36 | *
+ * ------------------------------------------------------------- *
+ * | R13 | R14 | R15 | R16 | R17 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | *
+ * ------------------------------------------------------------- *
+ * | 40 | 44 | 48 | 52 | 56 | 60 | 64 | 68 | 72 | 76 | *
+ * ------------------------------------------------------------- *
+ * | R18 | R19 | R20 | R21 | R22 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | *
+ * ------------------------------------------------------------- *
+ * | 80 | 84 | 88 | 92 | 96 | 100 | 104 | 108 | 112 | 116 | *
+ * ------------------------------------------------------------- *
+ * | R23 | R24 | R25 | R26 | R27 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
+ * ------------------------------------------------------------- *
+ * | 120 | 124 | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
+ * ------------------------------------------------------------- *
+ * | R28 | R29 | R30 | R31 | SP | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 40 | 41 | 42 | 43 | 44 | 45 | | *
+ * ------------------------------------------------------------- *
+ * | 160 | 164 | 168 | 172 | 176 | 180 | | *
+ * ------------------------------------------------------------- *
+ * | CR | LR | PC | | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 46 | 47 | 48 | 49 | | *
+ * ------------------------------------------------------------- *
+ * | 184 | 188 | 192 | 196 | | *
+ * ------------------------------------------------------------- *
+ * | sbase | slimt | | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | *
+ * ------------------------------------------------------------- *
+ * | 200 | 204 | 208 | 212 | 216 | 220 | 224 | 228 | 232 | 236 | *
+ * ------------------------------------------------------------- *
+ * | F14 | F15 | F16 | F17 | F18 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | *
+ * ------------------------------------------------------------- *
+ * | 240 | 244 | 248 | 252 | 256 | 260 | 264 | 268 | 272 | 276 | *
+ * ------------------------------------------------------------- *
+ * | F19 | F20 | F21 | F22 | F23 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | *
+ * ------------------------------------------------------------- *
+ * | 280 | 284 | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | *
+ * ------------------------------------------------------------- *
+ * | F24 | F25 | F26 | F27 | F28 | *
+ * ------------------------------------------------------------- *
+ * ------------------------------------------------------------- *
+ * | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | | *
+ * ------------------------------------------------------------- *
+ * | 320 | 324 | 328 | 332 | 336 | 340 | 344 | 348 | | *
+ * ------------------------------------------------------------- *
+ * | F29 | F30 | F31 | fpscr | | *
+ * ------------------------------------------------------------- *
+ * *
+ * *****************************************************************/
+
+.section ".text"
+.align 2
+.globl jump_fcontext
+.section ".opd","aw"
+.align 3
+jump_fcontext:
+.quad .jump_fcontext,.TOC.@tocbase,0
+.previous
+.size jump_fcontext,24
+.type .jump_fcontext,@function
+.globl .jump_fcontext
+.jump_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
+
+ cmpwi cr7, %r6, 0 # test if fpu env should be preserved
+ beq cr7, 1f
+
+ stfd %f14, 200(%r3) # save F14
+ stfd %f15, 208(%r3) # save F15
+ stfd %f16, 216(%r3) # save F16
+ stfd %f17, 224(%r3) # save F17
+ stfd %f18, 232(%r3) # save F18
+ stfd %f19, 240(%r3) # save F19
+ stfd %f20, 248(%r3) # save F20
+ stfd %f21, 256(%r3) # save F21
+ stfd %f22, 264(%r3) # save F22
+ stfd %f23, 272(%r3) # save F23
+ stfd %f24, 280(%r3) # save F24
+ stfd %f25, 288(%r3) # save F25
+ stfd %f26, 296(%r3) # save F26
+ stfd %f27, 304(%r3) # save F27
+ stfd %f28, 312(%r3) # save F28
+ stfd %f29, 320(%r3) # save F29
+ stfd %f30, 328(%r3) # save F30
+ stfd %f31, 336(%r3) # save F31
+ mffs %f0 # load FPSCR
+ stfd %f0, 344(%r3) # save FPSCR
+
+ lfd %f14, 200(%r4) # restore F14
+ lfd %f15, 208(%r4) # restore F15
+ lfd %f16, 216(%r4) # restore F16
+ lfd %f17, 224(%r4) # restore F17
+ lfd %f18, 232(%r4) # restore F18
+ lfd %f19, 240(%r4) # restore F19
+ lfd %f20, 248(%r4) # restore F20
+ lfd %f21, 256(%r4) # restore F21
+ lfd %f22, 264(%r4) # restore F22
+ lfd %f23, 272(%r4) # restore F23
+ lfd %f24, 280(%r4) # restore F24
+ lfd %f25, 288(%r4) # restore F25
+ lfd %f26, 296(%r4) # restore F26
+ lfd %f27, 304(%r4) # restore F27
+ lfd %f28, 312(%r4) # restore F28
+ lfd %f29, 320(%r4) # restore F29
+ lfd %f30, 328(%r4) # restore F30
+ lfd %f31, 336(%r4) # restore F31
+ lfd %f0, 344(%r4) # load FPSCR
+ mtfsf 0xff, %f0 # restore FPSCR
+1:
+
+ 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
+
+ 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
+
+ bctr # jump to context
+.size .jump_fcontext, .-.jump_fcontext
+
+.section ".text"
+.align 2
+.globl make_fcontext
+.section ".opd","aw"
+.align 3
+make_fcontext:
+.quad .make_fcontext,.TOC.@tocbase,0
+.previous
+.size make_fcontext,24
+.type .make_fcontext,@function
+.globl .make_fcontext
+.make_fcontext:
+ std %r3, 0(%r3) # save the current context
+ std %r4, 176(%r3) # save the address of the function supposed to be run
+ ld %r0, 184(%r3) # load the stack base
+
+ li %r4, 56
+ subf %r1, %r4, %r1 # reserve space on stack
+ stw %r3, 48(%r1) # store pointer to fcontext_t on stack
+ mflr %r4 # load LR
+ stw %r4, 40(%r1) # store LR on stack
+ mr. %r3, %r0 # context stack as arg to align_stack
+ bl align_stack@plt # call align_stack
+ mr. %r0, %r3 # load result into R0
+ lwz %r4, 40(%r1) # pop LR from stack
+ mtlr %r4 # restore LR
+ lwz %r3, 48(%r1) # pop pointer to fcontext_t from stack
+ addi %r1, %r1, 56 # release space on stack
+
+ li %r4, 64
+ subf %r0, %r4, %r0 # 64 bytes on stack for parameter area (== 8 registers)
+ std %r0, 152(%r3) # save the stack base
+
+ mflr %r0 # load LR
+ bl 1f # jump to label 1
+1:
+ mflr %r4 # load LR
+ addi %r4, %r4, finish - 1b # calulate absolute address of finish
+ mtlr %r0 # restore LR
+ std %r4, 168(%r3) # save address of finish
+
+ li %r3, 0 # set return value to zero
+ blr
+
+finish:
+ li %r3, 0 # set return value to zero
+ bl _exit@plt # exit application
+.size .make_fcontext, .-.make_fcontext
diff --git a/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm b/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm
new file mode 100644
index 0000000000..f1f8ca12a7
--- /dev/null
+++ b/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm
@@ -0,0 +1,207 @@
+
+; Copyright Oliver Kowalke 2009.
+; Distributed under the Boost Software License, Version 1.0.
+; (See accompanying file LICENSE_1_0.txt or copy at
+; http://www.boost.org/LICENSE_1_0.txt)
+
+; ----------------------------------------------------------------------------------
+; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+; ----------------------------------------------------------------------------------
+; | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c |
+; ----------------------------------------------------------------------------------
+; | R12 | R13 | R14 | R15 |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
+; ----------------------------------------------------------------------------------
+; | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c |
+; ----------------------------------------------------------------------------------
+; | RDI | RSI | RBX | RBP |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 16 | 17 | 18 | 19 | |
+; ----------------------------------------------------------------------------------
+; | 0x40 | 0x44 | 0x48 | 0x4c | |
+; ----------------------------------------------------------------------------------
+; | RSP | RIP | |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 20 | 21 | 22 | 23 | |
+; ----------------------------------------------------------------------------------
+; | 0x50 | 0x54 | 0x58 | 0x5c | |
+; ----------------------------------------------------------------------------------
+; | sbase | slimit | |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 24 | 25 | |
+; ----------------------------------------------------------------------------------
+; | 0x60 | 0x64 | |
+; ----------------------------------------------------------------------------------
+; | fbr_strg | |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 26 | 27 | 28 | 29 | |
+; ----------------------------------------------------------------------------------
+; | 0x68 | 0x6c | 0x70 | 0x74 | |
+; ----------------------------------------------------------------------------------
+; | fc_mxcsr|fc_x87_cw| fc_xmm | |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
+; ----------------------------------------------------------------------------------
+; | 0x78 | 0x7c | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 |
+; ----------------------------------------------------------------------------------
+; | XMM6 | XMM7 |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
+; ----------------------------------------------------------------------------------
+; | 0x98 | 0x9c | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 |
+; ----------------------------------------------------------------------------------
+; | XMM8 | XMM9 |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
+; ----------------------------------------------------------------------------------
+; | 0x118 | 0x11c | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 |
+; ----------------------------------------------------------------------------------
+; | XMM10 | XMM11 |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
+; ----------------------------------------------------------------------------------
+; | 0x138 | 0x13c | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 |
+; ----------------------------------------------------------------------------------
+; | XMM12 | XMM13 |
+; ----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
+; | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
+; ----------------------------------------------------------------------------------
+; | 0x158 | 0x15c | 0x160 | 0x164 | 0x168 | 0x16c | 0x170 | 0x174 |
+; ----------------------------------------------------------------------------------
+; | XMM14 | XMM15 |
+; ----------------------------------------------------------------------------------
+
+EXTERN _exit:PROC ; standard C library function
+EXTERN align_stack:PROC ; stack alignment
+EXTERN seh_fcontext:PROC ; exception handler
+.code
+
+jump_fcontext PROC EXPORT FRAME:seh_fcontext
+ .endprolog
+
+ mov [rcx], r12 ; save R12
+ mov [rcx+08h], r13 ; save R13
+ mov [rcx+010h], r14 ; save R14
+ mov [rcx+018h], r15 ; save R15
+ mov [rcx+020h], rdi ; save RDI
+ mov [rcx+028h], rsi ; save RSI
+ mov [rcx+030h], rbx ; save RBX
+ mov [rcx+038h], rbp ; save RBP
+
+ 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, [r10+010h] ; load current stack limit
+ mov [rcx+058h], rax ; save current stack limit
+ mov rax, [r10+018h] ; load fiber local storage
+ mov [rcx+060h], rax ; save fiber local storage
+
+ test r9, r9
+ je nxt
+
+ stmxcsr [rcx+068h] ; save MMX control and status word
+ fnstcw [rcx+06ch] ; save x87 control word
+ mov r10, [rcx+070h] ; address of aligned XMM storage
+ movaps [r10], xmm6
+ movaps [r10+010h], xmm7
+ movaps [r10+020h], xmm8
+ movaps [r10+030h], xmm9
+ movaps [r10+040h], xmm10
+ movaps [r10+050h], xmm11
+ movaps [r10+060h], xmm12
+ movaps [r10+070h], xmm13
+ movaps [r10+080h], xmm14
+ movaps [r10+090h], xmm15
+
+ ldmxcsr [rdx+068h] ; restore MMX control and status word
+ fldcw [rdx+06ch] ; restore x87 control word
+ mov r10, [rdx+070h] ; address of aligned XMM storage
+ movaps xmm6, [r10]
+ movaps xmm7, [r10+010h]
+ movaps xmm8, [r10+020h]
+ movaps xmm9, [r10+030h]
+ movaps xmm10, [r10+040h]
+ movaps xmm11, [r10+050h]
+ movaps xmm12, [r10+060h]
+ movaps xmm13, [r10+070h]
+ movaps xmm14, [r10+080h]
+ movaps xmm15, [r10+090h]
+nxt:
+
+ lea rax, [rsp+08h] ; exclude the return address
+ mov [rcx+040h], rax ; save as stack pointer
+ 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
+ mov r15, [rdx+018h] ; restore R15
+ mov rdi, [rdx+020h] ; restore RDI
+ mov rsi, [rdx+028h] ; restore RSI
+ mov rbx, [rdx+030h] ; restore RBX
+ mov rbp, [rdx+038h] ; restore RBP
+
+ mov r10, gs:[030h] ; load NT_TIB
+ mov rax, [rdx+050h] ; load stack base
+ mov [r10+08h], rax ; restore stack base
+ mov rax, [rdx+058h] ; load stack limit
+ mov [r10+010h], rax ; restore stack limit
+ mov rax, [rdx+060h] ; load fiber local storage
+ mov [r10+018h], rax ; restore fiber local storage
+
+ mov rsp, [rdx+040h] ; restore RSP
+ 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 r10 ; indirect jump to caller
+jump_fcontext ENDP
+
+make_fcontext PROC EXPORT FRAME ; generate function table entry in .pdata and unwind information in E
+ .endprolog ; .xdata for a function's structured exception handling unwind behavior
+
+ mov [rcx], rcx ; store the address of current context
+ mov [rcx+048h], rdx ; save the address of the function supposed to run
+ mov rdx, [rcx+050h] ; load the address where the context stack beginns
+
+ push rcx ; save pointer to fcontext_t
+ sub rsp, 028h ; reserve shadow space for align_stack
+ mov rcx, rdx ; stack pointer as arg for align_stack
+ mov [rsp+8], rcx
+ call align_stack ; align stack
+ mov rdx, rax ; begin of aligned stack
+ add rsp, 028h
+ pop rcx ; restore pointer to fcontext_t
+
+ lea rdx, [rdx-028h] ; reserve 32byte shadow space + return address on stack, (RSP + 8) % 16 == 0
+ mov [rcx+040h], rdx ; save the address where the context stack beginns
+
+ stmxcsr [rcx+068h] ; save MMX control and status word
+ fnstcw [rcx+06ch] ; save x87 control word
+
+ 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
+
+finish:
+ xor rcx, rcx
+ mov [rsp+08h], rcx
+ call _exit ; exit application
+ hlt
+make_fcontext ENDP
+END
diff --git a/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S b/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S
new file mode 100644
index 0000000000..ad2d42b46c
--- /dev/null
+++ b/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S
@@ -0,0 +1,116 @@
+/*
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/****************************************************************************************
+ * *
+ * ---------------------------------------------------------------------------------- *
+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
+ * ---------------------------------------------------------------------------------- *
+ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
+ * ---------------------------------------------------------------------------------- *
+ * | RBX | R12 | R13 | R14 | *
+ * ---------------------------------------------------------------------------------- *
+ * ---------------------------------------------------------------------------------- *
+ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
+ * ---------------------------------------------------------------------------------- *
+ * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
+ * ---------------------------------------------------------------------------------- *
+ * | R15 | RBP | RSP | RIP | *
+ * ---------------------------------------------------------------------------------- *
+ * ---------------------------------------------------------------------------------- *
+ * | 16 | 17 | 18 | 19 | | *
+ * ---------------------------------------------------------------------------------- *
+ * | 0x40 | 0x44 | 0x48 | 0x4c | | *
+ * ---------------------------------------------------------------------------------- *
+ * | sbase | slimit | | *
+ * ---------------------------------------------------------------------------------- *
+ * ---------------------------------------------------------------------------------- *
+ * | 20 | 21 | | *
+ * ---------------------------------------------------------------------------------- *
+ * | 0x50 | 0x54 | | *
+ * ---------------------------------------------------------------------------------- *
+ * | fc_mxcsr|fc_x87_cw| | *
+ * ---------------------------------------------------------------------------------- *
+ * *
+ * **************************************************************************************/
+
+.text
+.globl jump_fcontext
+.type jump_fcontext,@function
+.align 16
+jump_fcontext:
+ movq %rbx, (%rdi) /* save RBX */
+ movq %r12, 0x8(%rdi) /* save R12 */
+ movq %r13, 0x10(%rdi) /* save R13 */
+ movq %r14, 0x18(%rdi) /* save R14 */
+ movq %r15, 0x20(%rdi) /* save R15 */
+ movq %rbp, 0x28(%rdi) /* save RBP */
+
+ cmp $0, %rcx
+ je 1f
+
+ stmxcsr 0x50(%rdi) /* save MMX control and status word */
+ fnstcw 0x54(%rdi) /* save x87 control word */
+
+ ldmxcsr 0x50(%rsi) /* restore MMX control and status word */
+ fldcw 0x54(%rsi) /* restore x87 control word */
+1:
+
+ 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 */
+ movq 0x10(%rsi), %r13 /* restore R13 */
+ movq 0x18(%rsi), %r14 /* restore R14 */
+ movq 0x20(%rsi), %r15 /* restore R15 */
+ movq 0x28(%rsi), %rbp /* restore RBP */
+
+ movq 0x30(%rsi), %rsp /* restore RSP */
+ movq 0x38(%rsi), %rcx /* fetch the address to return to */
+
+ 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
+
+.text
+.globl make_fcontext
+.type make_fcontext,@function
+.align 16
+make_fcontext:
+ movq %rdi, (%rdi) /* save the address of passed context */
+ movq %rsi, 0x38(%rdi) /* save the address of the context function */
+ movq 0x40(%rdi), %rdx /* load the stack base */
+
+ pushq %rdi /* save pointer to fcontext_t */
+ movq %rdx, %rdi /* stack pointer as arg for align_stack */
+ call align_stack@PLT /* align stack */
+ movq %rax, %rdx /* begin of aligned stack */
+ popq %rdi /* restore pointer to fcontext_t */
+
+ leaq -0x8(%rdx), %rdx /* reserve space for the last frame on stack, (RSP + 8) & 15 == 0 */
+ movq %rdx, 0x30(%rdi) /* save the algined stack base */
+
+ stmxcsr 0x50(%rdi) /* save MMX control and status word */
+ fnstcw 0x54(%rdi) /* save x87 control word */
+
+ leaq finish(%rip), %rcx /* address of finish; called after context function returns */
+ movq %rcx, (%rdx)
+
+ xorq %rax, %rax
+ ret
+
+finish:
+ xorq %rdi, %rdi /* exit code is zero */
+ call _exit@PLT /* exit application */
+ hlt
+.size make_fcontext,.-make_fcontext
+
diff --git a/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S b/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S
new file mode 100644
index 0000000000..eea76e455a
--- /dev/null
+++ b/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S
@@ -0,0 +1,111 @@
+/*
+ Copyright Oliver Kowalke 2009.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+/****************************************************************************************
+ * *
+ * ---------------------------------------------------------------------------------- *
+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
+ * ---------------------------------------------------------------------------------- *
+ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
+ * ---------------------------------------------------------------------------------- *
+ * | RBX | R12 | R13 | R14 | *
+ * ---------------------------------------------------------------------------------- *
+ * ---------------------------------------------------------------------------------- *
+ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
+ * ---------------------------------------------------------------------------------- *
+ * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
+ * ---------------------------------------------------------------------------------- *
+ * | R15 | RBP | RSP | RIP | *
+ * ---------------------------------------------------------------------------------- *
+ * ---------------------------------------------------------------------------------- *
+ * | 16 | 17 | 18 | 19 | | *
+ * ---------------------------------------------------------------------------------- *
+ * | 0x40 | 0x44 | 0x48 | 0x4c | | *
+ * ---------------------------------------------------------------------------------- *
+ * | sbase | slimit | | *
+ * ---------------------------------------------------------------------------------- *
+ * ---------------------------------------------------------------------------------- *
+ * | 20 | 21 | | *
+ * ---------------------------------------------------------------------------------- *
+ * | 0x50 | 0x54 | | *
+ * ---------------------------------------------------------------------------------- *
+ * | fc_mxcsr|fc_x87_cw| | *
+ * ---------------------------------------------------------------------------------- *
+ * *
+ * **************************************************************************************/
+
+.text
+.globl _jump_fcontext
+.align 8
+_jump_fcontext:
+ movq %rbx, (%rdi) /* save RBX */
+ movq %r12, 0x8(%rdi) /* save R12 */
+ movq %r13, 0x10(%rdi) /* save R13 */
+ movq %r14, 0x18(%rdi) /* save R14 */
+ movq %r15, 0x20(%rdi) /* save R15 */
+ movq %rbp, 0x28(%rdi) /* save RBP */
+
+ cmp $0, %rcx
+ je 1f
+
+ stmxcsr 0x50(%rdi) /* save MMX control and status word */
+ fnstcw 0x54(%rdi) /* save x87 control word */
+
+ ldmxcsr 0x50(%rsi) /* restore MMX control and status word */
+ fldcw 0x54(%rsi) /* restore x87 control word */
+1:
+
+ 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 */
+ movq 0x10(%rsi), %r13 /* restore R13 */
+ movq 0x18(%rsi), %r14 /* restore R14 */
+ movq 0x20(%rsi), %r15 /* restore R15 */
+ movq 0x28(%rsi), %rbp /* restore RBP */
+
+ movq 0x30(%rsi), %rsp /* restore RSP */
+ movq 0x38(%rsi), %rcx /* fetch the address to return to */
+
+ 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 */
+
+.text
+.globl _make_fcontext
+.align 8
+_make_fcontext:
+ movq %rdi, (%rdi) /* save the address of current context */
+ movq %rsi, 0x38(%rdi) /* save the address of the function supposed to run */
+ movq 0x40(%rdi), %rdx /* load the stack base */
+
+ pushq %rdi /* save pointer to fcontext_t */
+ movq %rdx, %rdi /* stack pointer as arg for align_stack */
+ call _align_stack /* align stack */
+ movq %rax, %rdx /* begin of aligned stack */
+ popq %rdi /* restore pointer to fcontext_t */
+
+ leaq -0x8(%rdx), %rdx /* reserve space for the last frame on stack, (RSP + 8) % 16 == 0 */
+ movq %rdx, 0x30(%rdi) /* save the address */
+
+ stmxcsr 0x50(%rdi) /* save MMX control and status word */
+ fnstcw 0x54(%rdi) /* save x87 control word */
+
+ leaq finish(%rip), %rcx /* helper code executed after context function returns */
+ movq %rcx, (%rdx)
+
+ xorq %rax, %rax /* set RAX to zero */
+ ret
+
+finish:
+ xorq %rdi, %rdi /* exit code is zero */
+ call _exit /* exit application */
+ hlt
diff --git a/libs/context/src/fcontext.cpp b/libs/context/src/fcontext.cpp
new file mode 100644
index 0000000000..596cbd8e8a
--- /dev/null
+++ b/libs/context/src/fcontext.cpp
@@ -0,0 +1,36 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CONTEXT_SOURCE
+
+#include <boost/context/fcontext.hpp>
+
+#include <cstddef>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace ctx {
+namespace detail {
+
+extern "C" BOOST_CONTEXT_DECL
+void * BOOST_CONTEXT_CALLDECL align_stack( void * vp)
+{
+ void * base = vp;
+ if ( 0 != ( ( ( uintptr_t) base) & 15) )
+ base = ( char * ) ( ( ( ( uintptr_t) base) - 15) & ~0x0F);
+ return base;
+}
+
+}
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
diff --git a/libs/context/src/seh.cpp b/libs/context/src/seh.cpp
new file mode 100644
index 0000000000..9363805cf5
--- /dev/null
+++ b/libs/context/src/seh.cpp
@@ -0,0 +1,83 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CONTEXT_SOURCE
+
+extern "C" {
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include <excpt.h>
+#include <windows.h>
+#include <winnt.h>
+
+#if defined(_MSC_VER)
+# define SNPRINTF _snprintf
+#else
+# define SNPRINTF snprintf
+#endif
+
+static const char * exception_description(
+ _EXCEPTION_RECORD const* record, char * description, size_t len)
+{
+ const DWORD code = record->ExceptionCode;
+ const ULONG_PTR * info = record->ExceptionInformation;
+
+ switch ( code)
+ {
+ case EXCEPTION_ACCESS_VIOLATION:
+ {
+ const char * accessType = ( info[0]) ? "writing" : "reading";
+ const ULONG_PTR address = info[1];
+ SNPRINTF( description, len, "Access violation %s %p", accessType, reinterpret_cast< void * >( address) );
+ return description;
+ }
+ case EXCEPTION_DATATYPE_MISALIGNMENT: return "Datatype misalignment";
+ case EXCEPTION_BREAKPOINT: return "Breakpoint";
+ case EXCEPTION_SINGLE_STEP: return "Single step";
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "Array bounds exceeded";
+ case EXCEPTION_FLT_DENORMAL_OPERAND: return "FPU denormal operand";
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "FPU divide by zero";
+ case EXCEPTION_FLT_INEXACT_RESULT: return "FPU inexact result";
+ case EXCEPTION_FLT_INVALID_OPERATION: return "FPU invalid operation";
+ case EXCEPTION_FLT_OVERFLOW: return "FPU overflow";
+ case EXCEPTION_FLT_STACK_CHECK: return "FPU stack check";
+ case EXCEPTION_FLT_UNDERFLOW: return "FPU underflow";
+ case EXCEPTION_INT_DIVIDE_BY_ZERO: return "Integer divide by zero";
+ case EXCEPTION_INT_OVERFLOW: return "Integer overflow";
+ case EXCEPTION_PRIV_INSTRUCTION: return "Privileged instruction";
+ case EXCEPTION_IN_PAGE_ERROR: return "In page error";
+ case EXCEPTION_ILLEGAL_INSTRUCTION: return "Illegal instruction";
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "Noncontinuable exception";
+ case EXCEPTION_STACK_OVERFLOW: return "Stack overflow";
+ case EXCEPTION_INVALID_DISPOSITION: return "Invalid disposition";
+ case EXCEPTION_GUARD_PAGE: return "Guard page";
+ case EXCEPTION_INVALID_HANDLE: return "Invalid handle";
+ }
+
+ SNPRINTF( description, len, "Unknown (0x%08lX)", code);
+ return description;
+}
+
+EXCEPTION_DISPOSITION seh_fcontext(
+ struct _EXCEPTION_RECORD * record,
+ void *,
+ struct _CONTEXT *,
+ void *)
+{
+ char description[255];
+
+ fprintf( stderr, "exception: %s (%08lX)\n",
+ exception_description( record, description, sizeof( description) ),
+ record->ExceptionCode);
+
+ ExitProcess( -1);
+
+ return ExceptionContinueSearch; // never reached
+}
+
+}
diff --git a/libs/context/src/stack_allocator_posix.cpp b/libs/context/src/stack_allocator_posix.cpp
new file mode 100644
index 0000000000..a373e56d03
--- /dev/null
+++ b/libs/context/src/stack_allocator_posix.cpp
@@ -0,0 +1,84 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CONTEXT_SOURCE
+
+#include <boost/context/stack_allocator.hpp>
+
+extern "C" {
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+}
+
+#include <stdexcept>
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/format.hpp>
+
+#include <boost/context/stack_utils.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace ctx {
+
+void *
+stack_allocator::allocate( std::size_t size) const
+{
+ if ( minimum_stacksize() > size)
+ throw std::invalid_argument(
+ boost::str( boost::format("invalid stack size: must be at least %d bytes")
+ % minimum_stacksize() ) );
+
+ if ( ! is_stack_unbound() && ( maximum_stacksize() < size) )
+ throw std::invalid_argument(
+ boost::str( boost::format("invalid stack size: must not be larger than %d bytes")
+ % maximum_stacksize() ) );
+
+ const std::size_t pages( page_count( size) + 1); // add +1 for guard page
+ std::size_t size_ = pages * pagesize();
+
+ const int fd( ::open("/dev/zero", O_RDONLY) );
+ BOOST_ASSERT( -1 != fd);
+ void * limit =
+# if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+ ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+# else
+ ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+# endif
+ ::close( fd);
+ if ( ! limit) throw std::bad_alloc();
+
+ const int result( ::mprotect( limit, pagesize(), PROT_NONE) );
+ BOOST_ASSERT( 0 == result);
+
+ return static_cast< char * >( limit) + size_;
+}
+
+void
+stack_allocator::deallocate( void * vp, std::size_t size) const
+{
+ if ( vp)
+ {
+ const std::size_t pages( page_count( size) + 1); // add +1 for guard page
+ std::size_t size_ = pages * pagesize();
+ BOOST_ASSERT( 0 < size && 0 < size_);
+ void * limit = static_cast< char * >( vp) - size_;
+ ::munmap( limit, size_);
+ }
+}
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
diff --git a/libs/context/src/stack_allocator_windows.cpp b/libs/context/src/stack_allocator_windows.cpp
new file mode 100644
index 0000000000..518239f0e3
--- /dev/null
+++ b/libs/context/src/stack_allocator_windows.cpp
@@ -0,0 +1,86 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CONTEXT_SOURCE
+
+#include <boost/context/stack_allocator.hpp>
+
+extern "C" {
+#include <windows.h>
+}
+
+#include <stdexcept>
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/format.hpp>
+
+#include <boost/context/stack_utils.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+# if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4244 4267)
+# endif
+
+namespace boost {
+namespace ctx {
+
+void *
+stack_allocator::allocate( std::size_t size) const
+{
+ if ( minimum_stacksize() > size)
+ throw std::invalid_argument(
+ boost::str( boost::format("invalid stack size: must be at least %d bytes")
+ % minimum_stacksize() ) );
+
+ if ( ! is_stack_unbound() && ( maximum_stacksize() < size) )
+ throw std::invalid_argument(
+ boost::str( boost::format("invalid stack size: must not be larger than %d bytes")
+ % maximum_stacksize() ) );
+
+ const std::size_t pages( page_count( size) + 1); // add +1 for guard page
+ std::size_t size_ = pages * pagesize();
+
+#ifndef BOOST_CONTEXT_FIBER
+ void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE);
+ if ( ! limit) throw std::bad_alloc();
+
+ DWORD old_options;
+ const BOOL result = ::VirtualProtect(
+ limit, pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
+ BOOST_ASSERT( FALSE != result);
+
+ return static_cast< char * >( limit) + size_;
+#endif
+}
+
+void
+stack_allocator::deallocate( void * vp, std::size_t size) const
+{
+ if ( vp)
+ {
+ const std::size_t pages( page_count( size) + 1); // add +1 for guard page
+ std::size_t size_ = pages * pagesize();
+ BOOST_ASSERT( 0 < size && 0 < size_);
+ void * limit = static_cast< char * >( vp) - size_;
+ ::VirtualFree( limit, 0, MEM_RELEASE);
+ }
+}
+
+}}
+
+# if defined(BOOST_MSVC)
+# pragma warning(pop)
+# endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
diff --git a/libs/context/src/stack_utils_posix.cpp b/libs/context/src/stack_utils_posix.cpp
new file mode 100644
index 0000000000..6d7c9aecc2
--- /dev/null
+++ b/libs/context/src/stack_utils_posix.cpp
@@ -0,0 +1,80 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CONTEXT_SOURCE
+
+#include <boost/context/stack_utils.hpp>
+
+extern "C" {
+#include <signal.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <unistd.h>
+}
+
+#include <cmath>
+
+#include <boost/assert.hpp>
+
+namespace {
+
+static rlimit stacksize_limit_()
+{
+ rlimit limit;
+ const int result = ::getrlimit( RLIMIT_STACK, & limit);
+ BOOST_ASSERT( 0 == result);
+ return limit;
+}
+
+static rlimit stacksize_limit()
+{
+ static rlimit limit = stacksize_limit_();
+ return limit;
+}
+
+}
+
+namespace boost {
+namespace ctx {
+
+BOOST_CONTEXT_DECL
+std::size_t default_stacksize()
+{
+ static std::size_t size = 256 * 1024;
+ return size;
+}
+
+BOOST_CONTEXT_DECL
+std::size_t minimum_stacksize()
+{ return SIGSTKSZ; }
+
+BOOST_CONTEXT_DECL
+std::size_t maximum_stacksize()
+{
+ BOOST_ASSERT( ! is_stack_unbound() );
+ return static_cast< std::size_t >( stacksize_limit().rlim_max);
+}
+
+BOOST_CONTEXT_DECL
+bool is_stack_unbound()
+{ return RLIM_INFINITY == stacksize_limit().rlim_max; }
+
+BOOST_CONTEXT_DECL
+std::size_t pagesize()
+{
+ static std::size_t pagesize( ::getpagesize() );
+ return pagesize;
+}
+
+BOOST_CONTEXT_DECL
+std::size_t page_count( std::size_t stacksize)
+{
+ return static_cast< std::size_t >(
+ std::ceil(
+ static_cast< float >( stacksize) / pagesize() ) );
+}
+
+}}
diff --git a/libs/context/src/stack_utils_windows.cpp b/libs/context/src/stack_utils_windows.cpp
new file mode 100644
index 0000000000..373033dac2
--- /dev/null
+++ b/libs/context/src/stack_utils_windows.cpp
@@ -0,0 +1,84 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CONTEXT_SOURCE
+
+#include <boost/context/stack_utils.hpp>
+
+extern "C" {
+#include <windows.h>
+}
+
+#include <cmath>
+#include <csignal>
+
+#include <boost/assert.hpp>
+
+namespace {
+
+static SYSTEM_INFO system_info_()
+{
+ SYSTEM_INFO si;
+ ::GetSystemInfo( & si);
+ return si;
+}
+
+static SYSTEM_INFO system_info()
+{
+ static SYSTEM_INFO si = system_info_();
+ return si;
+}
+
+}
+
+namespace boost {
+namespace ctx {
+
+BOOST_CONTEXT_DECL
+std::size_t default_stacksize()
+{
+ static std::size_t size = 256 * 1024;
+ return size;
+}
+
+BOOST_CONTEXT_DECL
+std::size_t minimum_stacksize()
+{
+ static std::size_t stacksize(
+ static_cast< std::size_t >( system_info().dwAllocationGranularity) );
+ return stacksize;
+}
+
+BOOST_CONTEXT_DECL
+std::size_t maximum_stacksize()
+{
+ BOOST_ASSERT( ! is_stack_unbound() );
+ static std::size_t stacksize = 8 * 1024 * 1024;
+ return stacksize;
+}
+
+// Windows seams not to provide a limit for the stacksize
+BOOST_CONTEXT_DECL
+bool is_stack_unbound()
+{ return true; }
+
+BOOST_CONTEXT_DECL
+std::size_t pagesize()
+{
+ static std::size_t pagesize(
+ static_cast< std::size_t >( system_info().dwPageSize) );
+ return pagesize;
+}
+
+BOOST_CONTEXT_DECL
+std::size_t page_count( std::size_t stacksize)
+{
+ return static_cast< std::size_t >(
+ std::ceil(
+ static_cast< float >( stacksize) / pagesize() ) );
+}
+
+}}
diff --git a/libs/context/test/Jamfile.v2 b/libs/context/test/Jamfile.v2
new file mode 100644
index 0000000000..d973dc44ee
--- /dev/null
+++ b/libs/context/test/Jamfile.v2
@@ -0,0 +1,25 @@
+# Boost.Context Library Tests Jamfile
+
+# Copyright Oliver Kowalke 2009.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import common ;
+import feature ;
+import indirect ;
+import modules ;
+import os ;
+import testing ;
+import toolset ;
+
+project boost/context/test
+ : requirements
+ <library>../../test/build//boost_unit_test_framework
+ <library>/boost/context//boost_context
+ <link>static
+ ;
+
+test-suite "context" :
+ [ run test_context.cpp ]
+ ;
diff --git a/libs/context/test/test_context.cpp b/libs/context/test/test_context.cpp
new file mode 100644
index 0000000000..42f09eac84
--- /dev/null
+++ b/libs/context/test/test_context.cpp
@@ -0,0 +1,190 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <utility>
+
+#include <boost/assert.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/context/all.hpp>
+
+namespace ctx = boost::ctx;
+
+ctx::fcontext_t fcm, fc1, fc2;
+int value1 = 0;
+std::string value2;
+double value3 = 0.;
+
+void f1( intptr_t)
+{
+ ++value1;
+ ctx::jump_fcontext( & fc1, & fcm, 0);
+}
+
+void f3( intptr_t)
+{
+ ++value1;
+ ctx::jump_fcontext( & fc1, & fcm, 0);
+ ++value1;
+ ctx::jump_fcontext( & fc1, & fcm, 0);
+}
+
+void f4( intptr_t)
+{
+ ctx::jump_fcontext( & fc1, & fcm, 7);
+}
+
+void f5( intptr_t arg)
+{
+ ctx::jump_fcontext( & fc1, & fcm, arg);
+}
+
+void f6( intptr_t 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)
+{
+ try
+ { 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)
+{
+ double d = * ( double *) arg;
+ d += 3.45;
+ value3 = d;
+ ctx::jump_fcontext( & fc1, & fcm, 0);
+}
+
+void test_start()
+{
+ 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();
+ ctx::make_fcontext( & fc1, f1);
+
+ BOOST_CHECK_EQUAL( 0, value1);
+ ctx::jump_fcontext( & fcm, & fc1, 0);
+ BOOST_CHECK_EQUAL( 1, value1);
+}
+
+void test_jump()
+{
+ 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();
+ ctx::make_fcontext( & fc1, f3);
+
+ BOOST_CHECK_EQUAL( 0, value1);
+ ctx::jump_fcontext( & fcm, & fc1, 0);
+ BOOST_CHECK_EQUAL( 1, value1);
+ ctx::jump_fcontext( & fcm, & fc1, 0);
+ BOOST_CHECK_EQUAL( 2, value1);
+}
+
+void test_result()
+{
+ 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();
+ ctx::make_fcontext( & fc1, f4);
+
+ int result = ( int) ctx::jump_fcontext( & fcm, & fc1, 0);
+ BOOST_CHECK_EQUAL( 7, result);
+}
+
+void test_arg()
+{
+ 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();
+ int i = 7;
+ ctx::make_fcontext( & fc1, f5);
+
+ int result = ( int) ctx::jump_fcontext( & fcm, & fc1, i);
+ BOOST_CHECK_EQUAL( i, result);
+}
+
+void test_transfer()
+{
+ 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();
+ std::pair< int, int > data = std::make_pair( 3, 7);
+ ctx::make_fcontext( & fc1, f6);
+
+ 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()
+{
+ 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();
+ const char * what = "hello world";
+ ctx::make_fcontext( & fc1, f7);
+
+ ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) what);
+ BOOST_CHECK_EQUAL( std::string( what), value2);
+}
+
+void test_fp()
+{
+ 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();
+ double d = 7.13;
+ ctx::make_fcontext( & fc1, f8);
+
+ ctx::jump_fcontext( & fcm, & fc1, (intptr_t) & d);
+ BOOST_CHECK_EQUAL( 10.58, value3);
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+ boost::unit_test::test_suite * test =
+ BOOST_TEST_SUITE("Boost.Context: context test suite");
+
+ test->add( BOOST_TEST_CASE( & test_start) );
+ test->add( BOOST_TEST_CASE( & test_jump) );
+ test->add( BOOST_TEST_CASE( & test_result) );
+ test->add( BOOST_TEST_CASE( & test_arg) );
+ test->add( BOOST_TEST_CASE( & test_transfer) );
+ test->add( BOOST_TEST_CASE( & test_exception) );
+ test->add( BOOST_TEST_CASE( & test_fp) );
+
+ return test;
+}