|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r80338 - in trunk: boost/context/detail libs/context/build libs/context/doc libs/context/example libs/context/performance libs/context/src libs/context/src/asm libs/context/test
From: oliver.kowalke_at_[hidden]
Date: 2012-08-31 15:50:10
Author: olli
Date: 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
New Revision: 80338
URL: http://svn.boost.org/trac/boost/changeset/80338
Log:
context: new layout for fcontext_t
- fcontext_t takes pointer to stack (lower addresses) and stack size
- make_fcontext() computes start address of stack pointer depending on
architecture (growing upwards, downwards)
- make_fcontext() preserves frame pointer on intel
- stack alignment corrected on intel
- BOOST_USE_UCONTEXT for performance measurements added
Removed:
trunk/libs/context/doc/config.qbk
Text files modified:
trunk/boost/context/detail/fcontext_arm.hpp | 4
trunk/boost/context/detail/fcontext_i386.hpp | 4
trunk/boost/context/detail/fcontext_i386_win.hpp | 6
trunk/boost/context/detail/fcontext_mips.hpp | 4
trunk/boost/context/detail/fcontext_ppc.hpp | 4
trunk/boost/context/detail/fcontext_x86_64.hpp | 4
trunk/boost/context/detail/fcontext_x86_64_win.hpp | 6
trunk/libs/context/build/Jamfile.v2 | 241 +++++++++++++++++++++++++++++----------
trunk/libs/context/doc/fcontext.qbk | 7
trunk/libs/context/doc/performance.qbk | 3
trunk/libs/context/doc/requirements.qbk | 8
trunk/libs/context/doc/stack.qbk | 12 +
trunk/libs/context/example/exit.cpp | 4
trunk/libs/context/example/jump.cpp | 4
trunk/libs/context/example/transfer.cpp | 2
trunk/libs/context/performance/performance.cpp | 122 +++++++++----------
trunk/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S | 4
trunk/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm | 61 +++++----
trunk/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S | 52 ++++---
trunk/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S | 45 ++++---
trunk/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S | 4
trunk/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S | 4
trunk/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S | 4
trunk/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm | 56 ++++----
trunk/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S | 51 +++++---
trunk/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S | 51 +++++---
trunk/libs/context/src/stack_allocator_posix.cpp | 15 +-
trunk/libs/context/src/stack_allocator_windows.cpp | 17 +-
trunk/libs/context/src/stack_utils_posix.cpp | 48 +++++--
trunk/libs/context/src/stack_utils_windows.cpp | 57 +++++---
trunk/libs/context/test/test_context.cpp | 22 ++-
31 files changed, 573 insertions(+), 353 deletions(-)
Modified: trunk/boost/context/detail/fcontext_arm.hpp
==============================================================================
--- trunk/boost/context/detail/fcontext_arm.hpp (original)
+++ trunk/boost/context/detail/fcontext_arm.hpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -27,11 +27,11 @@
struct stack_t
{
- void * base;
+ void * sp;
std::size_t size;
stack_t() :
- base( 0), size( 0)
+ sp( 0), size( 0)
{}
};
Modified: trunk/boost/context/detail/fcontext_i386.hpp
==============================================================================
--- trunk/boost/context/detail/fcontext_i386.hpp (original)
+++ trunk/boost/context/detail/fcontext_i386.hpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -27,11 +27,11 @@
struct stack_t
{
- void * base;
+ void * sp;
std::size_t size;
stack_t() :
- base( 0), size( 0)
+ sp( 0), size( 0)
{}
};
Modified: trunk/boost/context/detail/fcontext_i386_win.hpp
==============================================================================
--- trunk/boost/context/detail/fcontext_i386_win.hpp (original)
+++ trunk/boost/context/detail/fcontext_i386_win.hpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -36,12 +36,12 @@
struct stack_t
{
- void * base;
- void * limit;
+ void * sp;
std::size_t size;
+ void * limit;
stack_t() :
- base( 0), limit( 0), size( 0)
+ sp( 0), size( 0), limit( 0)
{}
};
Modified: trunk/boost/context/detail/fcontext_mips.hpp
==============================================================================
--- trunk/boost/context/detail/fcontext_mips.hpp (original)
+++ trunk/boost/context/detail/fcontext_mips.hpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -29,11 +29,11 @@
struct stack_t
{
- void * base;
+ void * sp;
std::size_t size;
stack_t() :
- base( 0), size( 0)
+ sp( 0), size( 0)
{}
};
Modified: trunk/boost/context/detail/fcontext_ppc.hpp
==============================================================================
--- trunk/boost/context/detail/fcontext_ppc.hpp (original)
+++ trunk/boost/context/detail/fcontext_ppc.hpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -27,11 +27,11 @@
struct stack_t
{
- void * base;
+ void * sp;
std::size_t size;
stack_t() :
- base( 0), size( 0)
+ sp( 0), size( 0)
{}
};
Modified: trunk/boost/context/detail/fcontext_x86_64.hpp
==============================================================================
--- trunk/boost/context/detail/fcontext_x86_64.hpp (original)
+++ trunk/boost/context/detail/fcontext_x86_64.hpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -27,11 +27,11 @@
struct stack_t
{
- void * base;
+ void * sp;
std::size_t size;
stack_t() :
- base( 0), size( 0)
+ sp( 0), size( 0)
{}
};
Modified: trunk/boost/context/detail/fcontext_x86_64_win.hpp
==============================================================================
--- trunk/boost/context/detail/fcontext_x86_64_win.hpp (original)
+++ trunk/boost/context/detail/fcontext_x86_64_win.hpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -36,12 +36,12 @@
struct stack_t
{
- void * base;
- void * limit;
+ void * sp;
std::size_t size;
+ void * limit;
stack_t() :
- base( 0), limit( 0), size( 0)
+ sp( 0), size( 0), limit( 0)
{}
};
Modified: trunk/libs/context/build/Jamfile.v2
==============================================================================
--- trunk/libs/context/build/Jamfile.v2 (original)
+++ trunk/libs/context/build/Jamfile.v2 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -23,255 +23,374 @@
<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 "$(<)" "$(>)"
+ as -o "$(<)" "$(>)"
}
actions masm
{
- ml /c /Fo"$(<)" "$(>)"
+ ml /c /Fo"$(<)" "$(>)"
}
actions masm64
{
- ml64 /c /Fo"$(<)" "$(>)"
+ ml64 /c /Fo"$(<)" "$(>)"
}
rule configure ( properties * )
{
- local result ;
+ local result ;
+
+# if ( ! ( <toolset>gcc in $(properties)
+# || <toolset>intel in $(properties)
+# || <toolset>msvc in $(properties) ) )
+# {
+# result = <build>no ;
+# ECHO "toolset not supported" ;
+# }
- return $(result) ;
+ return $(result) ;
}
# ARM
alias asm_context_sources
: asm/fcontext_arm_aapcs_elf_gas.S
- : <architecture>arm
- <toolset>gcc
+ : <abi>aapcs
+ <architecture>arm
+ <binary-format>elf
+ <toolset>gcc
;
alias asm_context_sources
: asm/fcontext_arm_aapcs_elf_gas.S
- : <architecture>arm
- <toolset>qcc
+ : <abi>aapcs
+ <architecture>arm
+ <binary-format>elf
+ <toolset>qcc
;
alias asm_context_sources
: [ make asm/fcontext_arm_aapcs_elf_gas.o : asm/fcontext_arm_aapcs_elf_gas.S : @gas ]
- : <architecture>arm
+ : <abi>aapcs
+ <architecture>arm
+ <binary-format>elf
;
# MIPS 32bit
alias asm_context_sources
: asm/fcontext_mips32_o32_elf_gas.S
- : <architecture>mips1
- <toolset>gcc
+ : <abi>o32
+ <architecture>mips1
+ <binary-format>elf
+ <toolset>gcc
;
alias asm_context_sources
: asm/fcontext_mips32_o32_elf_gas.S
- : <architecture>mips1
- <toolset>qcc
+ : <abi>o32
+ <architecture>mips1
+ <binary-format>elf
+ <toolset>qcc
;
alias asm_context_sources
: [ make asm/fcontext_mips32_o32_elf_gas.o : asm/fcontext_mips32_o32_elf_gas.S : @gas ]
- : <architecture>mips1
+ : <abi>o32
+ <architecture>mips1
+ <binary-format>elf
;
# POWERPC 32bit
alias asm_context_sources
: asm/fcontext_ppc32_sysv_elf_gas.S
- : <address-model>32
+ : <abi>sysv
+ <address-model>32
<architecture>power
- <toolset>gcc
+ <binary-format>elf
+ <toolset>gcc
;
alias asm_context_sources
: asm/fcontext_ppc32_sysv_elf_gas.S
- : <address-model>32
+ : <abi>sysv
+ <address-model>32
<architecture>power
- <toolset>qcc
+ <binary-format>elf
+ <toolset>qcc
;
alias asm_context_sources
: [ make asm/fcontext_ppc32_sysv_elf_gas.o : asm/fcontext_ppc32_sysv_elf_gas.S : @gas ]
- : <address-model>32
+ : <abi>sysv
+ <address-model>32
<architecture>power
+ <binary-format>elf
;
# POWERPC 64bit
alias asm_context_sources
: asm/fcontext_ppc64_sysv_elf_gas.S
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>power
- <toolset>gcc
+ <binary-format>elf
+ <toolset>gcc
;
alias asm_context_sources
: asm/fcontext_ppc64_sysv_elf_gas.S
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>power
- <toolset>qcc
+ <binary-format>elf
+ <toolset>qcc
;
alias asm_context_sources
: [ make asm/fcontext_ppc64_sysv_elf_gas.o : asm/fcontext_ppc64_sysv_elf_gas.S : @gas ]
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>power
+ <binary-format>elf
;
# I386
alias asm_context_sources
: asm/fcontext_i386_sysv_elf_gas.S
- : <address-model>32
+ : <abi>sysv
+ <address-model>32
<architecture>x86
- <toolset>gcc
+ <binary-format>elf
+ <toolset>gcc
;
alias asm_context_sources
: asm/fcontext_i386_sysv_elf_gas.S
- : <address-model>32
+ : <abi>sysv
+ <address-model>32
<architecture>x86
- <toolset>qcc
+ <binary-format>elf
+ <toolset>qcc
;
alias asm_context_sources
: asm/fcontext_i386_sysv_elf_gas.S
- : <address-model>32
+ : <abi>sysv
+ <address-model>32
<architecture>x86
- <toolset>intel
+ <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 ]
- : <address-model>32
+ : <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
- : <address-model>32
+ : <abi>sysv
+ <address-model>32
<architecture>x86
+ <binary-format>mach-o
<target-os>darwin
- <toolset>gcc
+ <toolset>qcc
;
alias asm_context_sources
: asm/fcontext_i386_sysv_macho_gas.S
- : <address-model>32
+ : <abi>sysv
+ <address-model>32
<architecture>x86
+ <binary-format>mach-o
<target-os>darwin
- <toolset>intel
+ <toolset>intel
;
alias asm_context_sources
: [ make asm/fcontext_i386_sysv_macho_gas.o : asm/fcontext_i386_sysv_macho_gas.S : @gas ]
- : <address-model>32
+ : <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
- : <address-model>32
+ : <abi>ms
+ <address-model>32
<architecture>x86
+ <binary-format>pe
<target-os>windows
- <toolset>intel
+ <toolset>intel
;
alias asm_context_sources
: asm/fcontext_i386_ms_pe_masm.asm
- : <address-model>32
+ : <abi>ms
+ <address-model>32
<architecture>x86
+ <binary-format>pe
<target-os>windows
- <toolset>msvc
+ <toolset>msvc
;
alias asm_context_sources
: [ make asm/fcontext_i386_ms_pe_masm.o : asm/fcontext_i386_ms_pe_masm.asm : @masm ]
- : <address-model>32
+ : <abi>ms
+ <address-model>32
<architecture>x86
+ <binary-format>pe
<target-os>windows
;
-
# X86_64
alias asm_context_sources
: asm/fcontext_x86_64_sysv_elf_gas.S
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>x86
- <toolset>gcc
+ <binary-format>elf
+ <toolset>gcc
;
alias asm_context_sources
: asm/fcontext_x86_64_sysv_elf_gas.S
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>x86
- <toolset>qcc
+ <binary-format>elf
+ <toolset>qcc
;
alias asm_context_sources
: asm/fcontext_x86_64_sysv_elf_gas.S
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>x86
- <toolset>intel
+ <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 ]
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>x86
+ <binary-format>elf
;
-
alias asm_context_sources
: asm/fcontext_x86_64_sysv_macho_gas.S
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>x86
+ <binary-format>mach-o
<target-os>darwin
- <toolset>gcc
+ <toolset>gcc
;
alias asm_context_sources
: asm/fcontext_x86_64_sysv_macho_gas.S
- : <address-model>64
+ : <abi>sysv
+ <address-model>64
<architecture>x86
+ <binary-format>mach-o
<target-os>darwin
- <toolset>intel
+ <toolset>intel
;
alias asm_context_sources
: [ make asm/fcontext_x86_64_sysv_macho_gas.o : asm/fcontext_x86_64_sysv_macho_gas.S : @gas ]
- : <address-model>64
+ : <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
- : <address-model>64
+ : <abi>ms
+ <address-model>64
<architecture>x86
+ <binary-format>pe
<target-os>windows
- <toolset>intel
+ <toolset>intel
;
alias asm_context_sources
: asm/fcontext_x86_64_ms_pe_masm.asm
- : <address-model>64
+ : <abi>ms
+ <address-model>64
<architecture>x86
+ <binary-format>pe
<target-os>windows
- <toolset>msvc
+ <toolset>msvc
;
alias asm_context_sources
: [ make asm/fcontext_x86_64_ms_pe_masm.o : asm/fcontext_x86_64_ms_pe_masm.asm : @masm64 ]
- : <address-model>64
+ : <abi>ms
+ <address-model>64
<architecture>x86
+ <binary-format>pe
<target-os>windows
;
Deleted: trunk/libs/context/doc/config.qbk
==============================================================================
--- trunk/libs/context/doc/config.qbk 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
+++ (empty file)
@@ -1,60 +0,0 @@
-[/
- 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]
Modified: trunk/libs/context/doc/fcontext.qbk
==============================================================================
--- trunk/libs/context/doc/fcontext.qbk (original)
+++ trunk/libs/context/doc/fcontext.qbk 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -11,7 +11,8 @@
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].
+[@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".
@@ -40,8 +41,8 @@
// 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 the size of the stack.
+__fcontext__ requires a pointer (__fc_base__) as well as the size of the
+stack.
Calling __jump_fcontext__ invokes the __context_fn__ in a newly created context
complete with registers, flags, stack and instruction pointers. When control
Modified: trunk/libs/context/doc/performance.qbk
==============================================================================
--- trunk/libs/context/doc/performance.qbk (original)
+++ trunk/libs/context/doc/performance.qbk 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -14,6 +14,9 @@
to a single CPU. The code was compiled using the build options,
'variant = release cxxflags = -DBOOST_DISABLE_ASSERTS'.
+Applying `-DBOOST_USE_UCONTEXT` to cxxflags the performance of `ucontext` will
+be measured too.
+
The numbers in the table are the number of cycles per iteration, based upon an
average computed over 10 iterations.
Modified: trunk/libs/context/doc/requirements.qbk
==============================================================================
--- trunk/libs/context/doc/requirements.qbk (original)
+++ trunk/libs/context/doc/requirements.qbk 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -12,7 +12,11 @@
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).]
+[important Please note that `address-model=64` must be given to bjam command line
+on 64bit Windows for 64bit build; otherwise 32bit code will be generated.]
+
+[important For cross-compiling the lib you must specify certain additional
+properties at bjam command line: `target-os`, `abi`, `binary-format`,
+`architecture` and `address-model`.]
[endsect]
Modified: trunk/libs/context/doc/stack.qbk
==============================================================================
--- trunk/libs/context/doc/stack.qbk (original)
+++ trunk/libs/context/doc/stack.qbk 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -50,9 +50,9 @@
__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.
+It creates a __guard_page__ at the end of the stack 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]
@@ -77,12 +77,14 @@
[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.]]
+If the stack is unbound then the present implementation returns the maximum of
+`256 kB` and `minimum_stacksize()`.]]
]
[heading `std::size_t minimum_stacksize()`]
[variablelist
-[[Returns:] [Returns the minimum size in bytes of stack defined by the environment.]]
+[[Returns:] [Returns the minimum size in bytes of stack defined by the
+environment plus a pagesize (guard page).]]
[[Throws:] [Nothing.]]
]
Modified: trunk/libs/context/example/exit.cpp
==============================================================================
--- trunk/libs/context/example/exit.cpp (original)
+++ trunk/libs/context/example/exit.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -37,11 +37,11 @@
ctx::fcontext_t fcm;
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
+ fc1.fc_stack.sp = alloc.allocate(ctx::minimum_stacksize());
fc1.fc_stack.size = ctx::minimum_stacksize();
ctx::make_fcontext( & fc1, f1);
- fc2.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
+ fc2.fc_stack.sp = alloc.allocate(ctx::minimum_stacksize());
fc2.fc_stack.size = ctx::minimum_stacksize();
ctx::make_fcontext( & fc2, f2);
Modified: trunk/libs/context/example/jump.cpp
==============================================================================
--- trunk/libs/context/example/jump.cpp (original)
+++ trunk/libs/context/example/jump.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -37,11 +37,11 @@
{
ctx::stack_allocator alloc1, alloc2;
- fc1.fc_stack.base = alloc1.allocate(ctx::minimum_stacksize());
+ fc1.fc_stack.sp = alloc1.allocate(ctx::minimum_stacksize());
fc1.fc_stack.size = ctx::minimum_stacksize();
ctx::make_fcontext( & fc1, f1);
- fc2.fc_stack.base = alloc2.allocate(ctx::minimum_stacksize());
+ fc2.fc_stack.sp = alloc2.allocate(ctx::minimum_stacksize());
fc2.fc_stack.size = ctx::minimum_stacksize();
ctx::make_fcontext( & fc2, f2);
Modified: trunk/libs/context/example/transfer.cpp
==============================================================================
--- trunk/libs/context/example/transfer.cpp (original)
+++ trunk/libs/context/example/transfer.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -32,7 +32,7 @@
{
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate(ctx::minimum_stacksize());
+ fc1.fc_stack.sp = alloc.allocate(ctx::minimum_stacksize());
fc1.fc_stack.size = ctx::minimum_stacksize();
ctx::make_fcontext( & fc1, f1);
Modified: trunk/libs/context/performance/performance.cpp
==============================================================================
--- trunk/libs/context/performance/performance.cpp (original)
+++ trunk/libs/context/performance/performance.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -19,7 +19,7 @@
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/program_options.hpp>
-#ifndef BOOST_WINDOWS
+#ifdef BOOST_USE_UCONTEXT
#include <ucontext.h>
#endif
@@ -32,48 +32,51 @@
namespace ctx = boost::ctx;
-bool preserve_fpu = false;
+bool pres_fpu = false;
-#define CALL_FUNCTION(z,n,unused) \
- fn();
+#define CALL_FCONTEXT(z,n,unused) ctx::jump_fcontext( & fcm, & fc, 7, pres_fpu);
-#define CALL_UCONTEXT(z,n,unused) \
- ::swapcontext( & ucm, & uc);
+#ifdef BOOST_USE_UCONTEXT
+# define CALL_UCONTEXT(z,n,unused) ::swapcontext( & ucm, & uc);
+#endif
+
+#define CALL_FUNCTION(z,n,unused) fn();
-#define CALL_FCONTEXT(z,n,unused) \
- ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
-#ifndef BOOST_WINDOWS
+ctx::fcontext_t fc, fcm;
+
+#ifdef BOOST_USE_UCONTEXT
ucontext_t uc, ucm;
#endif
-ctx::fcontext_t fc, fcm;
-static void f3()
-{ }
-#ifndef BOOST_WINDOWS
+static void f1( intptr_t)
+{ while ( true) ctx::jump_fcontext( & fc, & fcm, 7, pres_fpu); }
+
+#ifdef BOOST_USE_UCONTEXT
static void f2()
-{
- while ( true)
- ::swapcontext( & uc, & ucm);
-}
+{ while ( true) ::swapcontext( & uc, & ucm); }
#endif
-static void f1( intptr_t)
-{
- while ( true)
- ctx::jump_fcontext( & fc, & fcm, 7, preserve_fpu);
-}
+static void f3()
+{}
+
#ifdef BOOST_CONTEXT_CYCLE
-cycle_t test_function_cycle( cycle_t ov)
+cycle_t test_fcontext_cycle( cycle_t ov)
{
- boost::function< void() > fn( boost::bind( f3) );
+ ctx::stack_allocator alloc;
+ fc.fc_stack.sp = alloc.allocate(ctx::default_stacksize());
+ fc.fc_stack.size = ctx::default_stacksize();
+ ctx::make_fcontext( & fc, f1);
+
+ ctx::jump_fcontext( & fcm, & fc, 7, pres_fpu);
+
// cache warum-up
-BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~)
+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_FUNCTION, ~)
+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
@@ -84,15 +87,13 @@
return total;
}
-#ifndef BOOST_WINDOWS
+# ifdef BOOST_USE_UCONTEXT
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_sp = alloc.allocate(ctx::default_stacksize());
uc.uc_stack.ss_size = ctx::default_stacksize();
::makecontext( & uc, f2, 7);
@@ -110,22 +111,16 @@
return total;
}
-#endif
+# endif
-cycle_t test_fcontext_cycle( cycle_t ov)
+cycle_t test_function_cycle( cycle_t ov)
{
- ctx::stack_allocator alloc;
- fc.fc_stack.base = alloc.allocate(ctx::default_stacksize());
- fc.fc_stack.size = ctx::default_stacksize();
- ctx::make_fcontext( & fc, f1);
-
- ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
-
+ boost::function< void() > fn( boost::bind( f3) );
// cache warum-up
-BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
+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_FCONTEXT, ~)
+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
@@ -137,15 +132,22 @@
}
#endif
+
#if _POSIX_C_SOURCE >= 199309L
-zeit_t test_function_zeit( zeit_t ov)
+zeit_t test_fcontext_zeit( zeit_t ov)
{
- boost::function< void() > fn( boost::bind( f3) );
+ ctx::stack_allocator alloc;
+ fc.fc_stack.sp = alloc.allocate(ctx::default_stacksize());
+ fc.fc_stack.size = ctx::default_stacksize();
+ ctx::make_fcontext( & fc, f1);
+
+ ctx::jump_fcontext( & fcm, & fc, 7, pres_fpu);
+
// cache warum-up
-BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~)
+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_FUNCTION, ~)
+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
@@ -156,15 +158,13 @@
return total;
}
-#ifndef BOOST_WINDOWS
+# ifdef BOOST_USE_UCONTEXT
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_sp = alloc.allocate(ctx::default_stacksize());
uc.uc_stack.ss_size = ctx::default_stacksize();
::makecontext( & uc, f2, 7);
@@ -182,22 +182,16 @@
return total;
}
-#endif
+# endif
-zeit_t test_fcontext_zeit( zeit_t ov)
+zeit_t test_function_zeit( zeit_t ov)
{
- ctx::stack_allocator alloc;
- fc.fc_stack.base = alloc.allocate(ctx::default_stacksize());
- fc.fc_stack.size = ctx::default_stacksize();
- ctx::make_fcontext( & fc, f1);
-
- ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu);
-
+ boost::function< void() > fn( boost::bind( f3) );
// cache warum-up
-BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~)
+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_FCONTEXT, ~)
+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
@@ -222,10 +216,10 @@
unsigned int res = test_fcontext_cycle( ov);
std::cout << "fcontext: average of " << res << " cycles per switch" << std::endl;
-#ifndef BOOST_WINDOWS
+# ifdef BOOST_USE_UCONTEXT
res = test_ucontext_cycle( ov);
std::cout << "ucontext: average of " << res << " cycles per switch" << std::endl;
-#endif
+# endif
res = test_function_cycle( ov);
std::cout << "boost::function: average of " << res << " cycles per switch" << std::endl;
}
@@ -238,10 +232,10 @@
unsigned int res = test_fcontext_zeit( ov);
std::cout << "fcontext: average of " << res << " ns per switch" << std::endl;
-#ifndef BOOST_WINDOWS
+# ifdef BOOST_USE_UCONTEXT
res = test_ucontext_zeit( ov);
std::cout << "ucontext: average of " << res << " ns per switch" << std::endl;
-#endif
+# endif
res = test_function_zeit( ov);
std::cout << "boost::function: average of " << res << " ns per switch" << std::endl;
}
Modified: trunk/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_arm_aapcs_elf_gas.S 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -26,7 +26,7 @@
* ------------------------------------------------------------- *
* | 0x2c| 0x30| | *
* ------------------------------------------------------------- *
- * |sbase|slimit| | *
+ * | sp | size| | *
* ------------------------------------------------------------- *
* ------------------------------------------------------------- *
* | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | *
@@ -79,6 +79,8 @@
make_fcontext:
str a2, [a1,#40] @ save address of context function
ldr a2, [a1,#44] @ load address of context stack base
+ ldr a3, [a1,#48] @ load size of context stack
+ add a2, a3 @ compute start address of context stack
push {a1,lr} @ save pointer to fcontext_t
mov a1, a2 @ context stack pointer as arg for align_stack
Modified: trunk/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm
==============================================================================
--- trunk/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm (original)
+++ trunk/libs/context/src/asm/fcontext_i386_ms_pe_masm.asm 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -16,7 +16,7 @@
; --------------------------------------------------------------
; | 018h | 01ch | 020h | |
; --------------------------------------------------------------
-; | base | limit | size | |
+; | sp | size | base | |
; --------------------------------------------------------------
; --------------------------------------------------------------
; | 9 | |
@@ -61,9 +61,9 @@
mov eax, [edx] ; load current SEH exception list
mov [ecx+024h], eax ; save current exception list
mov eax, [edx+04h] ; load current stack base
- mov [ecx+018h], eax ; save current stack base
+ mov [ecx+020h], eax ; save current stack base
mov eax, [edx+08h] ; load current stack limit
- mov [ecx+01ch], eax ; save current stack limit
+ mov [ecx+018h], eax ; save current stack limit
mov eax, [edx+010h] ; load fiber local storage
mov [ecx+028h], eax ; save fiber local storage
@@ -93,9 +93,9 @@
assume fs:error
mov eax, [ecx+024h] ; load SEH exception list
mov [edx], eax ; restore next SEH item
- mov eax, [ecx+018h] ; load stack base
+ mov eax, [ecx+020h] ; load stack base
mov [edx+04h], eax ; restore stack base
- mov eax, [ecx+01ch] ; load stack limit
+ mov eax, [ecx+018h] ; load stack limit
mov [edx+08h], eax ; restore stack limit
mov eax, [ecx+028h] ; load fiber local storage
mov [edx+010h], eax ; restore fiber local storage
@@ -110,44 +110,51 @@
jump_fcontext ENDP
make_fcontext PROC EXPORT
- mov eax, [esp+04h] ; load address of the fcontext_t
- mov ecx, [esp+08h] ; load address of the context function
- mov [eax+014h], ecx ; save address of the context function
- mov edx, [eax+018h] ; load address of context stack base
- mov ecx, [eax+020h] ; load context stack size
- neg ecx ; negate stacksize for LEA
- lea ecx, [edx+ecx] ; compute context stack limit
- mov [eax+01ch], ecx ; save context stack limit
+ push ebp ; save previous frame pointer; get the stack 16 byte aligned
+ mov ebp, esp ; set EBP to ESP
+ sub esp, 010h ; allocate stack space
+
+ mov eax, [ebp+08h] ; load address of fcontext_t
+ mov ecx, [ebp+0ch] ; load address of context function
+ mov [eax+014h], ecx ; save address of context function
+ mov edx, [eax+018h] ; load address of context stack (limit)
+ mov ecx, [eax+01ch] ; load context stack size
+ lea edx, [edx+ecx] ; compute top address of context stack (base)
+ mov [eax+020h], edx ; save top address of context stack (base)
- push eax ; save pointer to fcontext_t
- push edx ; context stack as arg for align_stack
+ mov [esp+04h], eax ; save pointer to fcontext_t
+ mov [esp], edx ; context stack as arg for align_stack
call align_stack ; call align_stack
mov edx, eax ; begin of aligned context stack
- pop eax ; remove arg for align_stack
- pop eax ; restore pointer to fcontext_t
+ mov eax, [esp+04h] ; restore pointer to fcontext_t
+
+ stmxcsr [eax+02ch] ; save MMX control word
+ fnstcw [eax+030h] ; save x87 control word
- lea edx, [edx-014h] ; reserve space for last frame on context stack, (ESP + 4) & 15 == 0
- mov [eax+010h], edx ; save the aligned stack
+ lea edx, [edx-01ch] ; reserve space for last frame and seh on context stack, (ESP - 0x4) % 16 == 0
+ mov [eax+010h], edx ; save address in EDX as stack pointer for context stack
mov ecx, seh_fcontext ; set ECX to exception-handler
- mov [edx+0ch], ecx ; save ECX as SEH handler
+ mov [edx+018h], 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 [edx+014h], ecx ; save ECX as next SEH item
+ lea ecx, [edx+014h] ; load address of next SEH item
mov [eax+024h], ecx ; save next SEH
- stmxcsr [eax+02ch] ; save MMX control word
- fnstcw [eax+030h] ; save x87 control word
+ mov ecx, finish ; abs address of finish
+ mov [edx], ecx ; save address of finish as return address for context function
+ ; entered after context function returns
- mov ecx, finish ; address of finish
- mov [edx], ecx
+ add esp, 010h ; deallocate stack space
+ pop ebp
xor eax, eax
ret
finish:
+ ; ESP == stack pointer of context function + 0x4
xor eax, eax
- push eax ; exit code is zero
+ mov [esp], eax ; exit code is zero
call _exit ; exit application
hlt
make_fcontext ENDP
Modified: trunk/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_i386_sysv_elf_gas.S 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -19,7 +19,7 @@
* -------------------------------------------------------------- *
* | 0x18 | 0x1c | | *
* -------------------------------------------------------------- *
- * | sbase | slimit | | *
+ * | sp | size | | *
* -------------------------------------------------------------- *
* -------------------------------------------------------------- *
* | 8 | 9 | | *
@@ -76,46 +76,54 @@
.align 2
.type make_fcontext,@function
make_fcontext:
- movl 0x4(%esp), %eax /* load address of the fcontext_t */
- movl 0x8(%esp), %ecx /* load address of the context function */
- movl %ecx, 0x14(%eax) /* save address of the context function */
+ pushl %ebp /* save previous frame pointer; get the stack 16 byte aligned */
+ movl %esp, %ebp /* set EBP to ESP */
+ subl $0x10, %esp /* allocate stack space */
+
+ movl 0x8(%ebp), %eax /* load address of fcontext_t */
+ movl 0xc(%ebp), %ecx /* load address of context function */
+ movl %ecx, 0x14(%eax) /* save address of context function */
movl 0x18(%eax), %edx /* load address of context stack base */
+ movl 0x1c(%eax), %ecx /* load size of context stack */
+ leal (%edx,%ecx), %edx /* compute top address of context stack */
- pushl %eax /* save pointer to fcontext_t */
- pushl %ebx /* save EBX */
- pushl %edx /* context stack pointer as arg for align_stack */
+ movl %ebx, 0x8(%esp) /* save EBX */
+ movl %eax, 0x4(%esp) /* save pointer to fcontext_t */
+ movl %edx, (%esp) /* context 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_at_PLT /* call align_stack */
movl %eax, %edx /* begin of aligned context 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 context stack, (ESP + 4) % 16 == 0 */
- movl %edx, 0x10(%eax) /* save the aligned context stack base */
+ movl 0x4(%esp), %eax /* restore pointer to fcontext_t */
+ movl 0x8(%esp), %ebx /* restore EBX */
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)
+ leal -0xc(%edx), %edx /* reserve space for the last frame on context stack; (ESP - 0x4) % 16 == 0 */
+ movl %edx, 0x10(%eax) /* save address in EDX as stack pointer for context function */
+
+ call 2f
+2: popl %ecx /* address of label 2 */
+ addl $finish-2b, %ecx /* compute abs address of label finish */
+ movl %ecx, (%edx) /* save address of finish as return address for context functions */
+ /* entered after context function returns */
- xorl %eax, %eax
+ addl $0x10, %esp /* deallocate stack space */
+ pop %ebp
+
+ xorl %eax, %eax
ret
finish:
- leal -0xc(%esp), %esp
-
+ /* ESP == stack pointer of context function + 0x4 */
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 */
+ xorl %eax, %eax
+ movl %eax, (%esp) /* exit code is zero */
call _exit_at_PLT /* exit application */
hlt
.size make_fcontext,.-make_fcontext
Modified: trunk/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_i386_sysv_macho_gas.S 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -19,7 +19,7 @@
* -------------------------------------------------------------- *
* | 0x18 | 0x1c | | *
* -------------------------------------------------------------- *
- * | sbase | slimit | | *
+ * | sp | size | | *
* -------------------------------------------------------------- *
* -------------------------------------------------------------- *
* | 8 | 9 | | *
@@ -73,37 +73,44 @@
.globl _make_fcontext
.align 2
_make_fcontext:
- movl 0x4(%esp), %eax /* load address of the fcontext_t */
- movl 0x8(%esp), %ecx /* load address of the context function */
- movl %ecx, 0x14(%eax) /* save address of the context function */
+ pushl %ebp /* save previous frame pointer; get the stack 16 byte aligned */
+ movl %esp, %ebp /* set EBP to ESP */
+ subl $0x10, %esp /* allocate stack space */
+
+ movl 0x8(%ebp), %eax /* load address of fcontext_t */
+ movl 0xc(%ebp), %ecx /* load address of context function */
+ movl %ecx, 0x14(%eax) /* save address of context function */
movl 0x18(%eax), %edx /* load address of context stack base */
+ movl 0x1c(%eax), %ecx /* load size of context stack */
+ leal (%edx,%ecx), %edx /* compute top address of context stack */
- pushl %eax /* save pointer to fcontext_t */
- pushl %ebx /* save EBX */
- pushl %edx /* context stack pointer as arg for align_stack */
+ movl %eax, 0x4(%esp) /* save pointer to fcontext_t */
+ movl %edx, (%esp) /* context stack pointer as arg for align_stack */
call _align_stack /* call align_stack */
movl %eax, %edx /* begin of aligned context 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 context stack, (ESP + 4) % 16 == 0 */
- movl %edx, 0x10(%eax) /* save the aligned context stack base */
+ movl 0x4(%esp), %eax /* restore pointer to fcontext_t */
stmxcsr 0x20(%eax) /* save MMX control and status word */
fnstcw 0x24(%eax) /* save x87 control word */
+ leal -0xc(%edx), %edx /* reserve space for the last frame on context stack, (ESP - 0x4) % 16 == 0 */
+ movl %edx, 0x10(%eax) /* save address in EDX as stack pointer for context function */
+
call 1f
-1: popl %ecx /* address of lable 1 */
- addl $finish-1b, %ecx /* helper code executed after context function returns */
- movl %ecx, (%edx)
+1: popl %ecx /* address of label 1 */
+ addl $finish-1b, %ecx /* compute abs address of label finish */
+ movl %ecx, (%edx) /* save address of finish as return address for context function */
+ /* entered after context function returns */
+
+ addl $0x10, %esp /* deallocate stack space */
+ pop %ebp
xorl %eax, %eax
ret
finish:
- leal -0xc(%esp), %esp
- xorl %eax, %eax
- pushl %eax /* exit code is zero */
+ /* ESP == stack pointer of context function + 0x4 */
+ xorl %eax, %eax
+ movl %eax, (%esp) /* exit code is zero */
call _exit /* exit application */
hlt
Modified: trunk/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_mips32_o32_elf_gas.S 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -26,7 +26,7 @@
* ------------------------------------------------------------- *
* | 104 | 112 | | *
* ------------------------------------------------------------- *
- * |sbase|slimt| | *
+ * | sp | size| | *
* ------------------------------------------------------------- *
* ------------------------------------------------------------- *
* | 15 | 16 | 17 | 18 | 19 | 20 | | *
@@ -112,6 +112,8 @@
sw $gp, 24($a0) # save global pointer
sw $a1, 96($a0) # save address of context function
lw $t0, 104($a0) # load address of context stack base
+ lw $t1, 112($a0) # load size of context stack
+ add $t0, $t1, $t0 # compute start address of context stack
sub $sp, $sp, 28
sw $ra, 24($sp)
Modified: trunk/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_ppc32_sysv_elf_gas.S 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -33,7 +33,7 @@
* ------------------------------------------------------------- *
* | 92 | 96 | | *
* ------------------------------------------------------------- *
- * |sbase|slimt| | *
+ * | sp | size| | *
* ------------------------------------------------------------- *
* ------------------------------------------------------------- *
* | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | *
@@ -186,6 +186,8 @@
make_fcontext:
stw %r4, 88(%r3) # save address of context function
lwz %r0, 92(%r3) # load address of context stack base
+ lwz %r4, 96(%r3) # load size of context stack
+ add %r0, %r4, %r0 # compute start address of context stack
li %r4, 28
subf %r1, %r4, %r1 # reserve space on stack
Modified: trunk/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_ppc64_sysv_elf_gas.S 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -47,7 +47,7 @@
* ------------------------------------------------------------- *
* | 184 | 188 | 192 | 196 | | *
* ------------------------------------------------------------- *
- * | sbase | slimt | | *
+ * | sp | size | | *
* ------------------------------------------------------------- *
* ------------------------------------------------------------- *
* | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | *
@@ -214,6 +214,8 @@
.make_fcontext:
std %r4, 176(%r3) # save address of context function
ld %r0, 184(%r3) # load address of context stack base
+ ld %r4, 192(%r3) # load size of context stack
+ add %r0, %r4, %r0 # compute start address of context stack
li %r4, 56
subf %r1, %r4, %r1 # reserve space on stack
Modified: trunk/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm
==============================================================================
--- trunk/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm (original)
+++ trunk/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -30,7 +30,7 @@
; ----------------------------------------------------------------------------------
; | 0x50 | 0x54 | 0x58 | 0x5c | 0x60 | 0x64 | |
; ----------------------------------------------------------------------------------
-; | base | limit | size | |
+; | sp | size | base | |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 26 | 27 | |
@@ -101,9 +101,9 @@
mov r10, gs:[030h] ; load NT_TIB
mov rax, [r10+08h] ; load current stack base
- mov [rcx+050h], rax ; save current stack base
+ mov [rcx+060h], rax ; save current stack base
mov rax, [r10+010h] ; load current stack limit
- mov [rcx+058h], rax ; save current stack limit
+ mov [rcx+050h], rax ; save current stack limit
mov rax, [r10+018h] ; load fiber local storage
mov [rcx+068h], rax ; save fiber local storage
@@ -112,7 +112,7 @@
stmxcsr [rcx+070h] ; save MMX control and status word
fnstcw [rcx+074h] ; save x87 control word
- mov r10, [rcx+078h] ; address of aligned XMM storage
+ mov r10, [rcx+078h] ; address of aligned XMM storage
movaps [r10], xmm6
movaps [r10+010h], xmm7
movaps [r10+020h], xmm8
@@ -126,7 +126,7 @@
ldmxcsr [rdx+070h] ; restore MMX control and status word
fldcw [rdx+074h] ; restore x87 control word
- mov r10, [rdx+078h] ; address of aligned XMM storage
+ mov r10, [rdx+078h] ; address of aligned XMM storage
movaps xmm6, [r10]
movaps xmm7, [r10+010h]
movaps xmm8, [r10+020h]
@@ -154,9 +154,9 @@
mov rbp, [rdx+038h] ; restore RBP
mov r10, gs:[030h] ; load NT_TIB
- mov rax, [rdx+050h] ; load stack base
+ mov rax, [rdx+060h] ; load stack base
mov [r10+08h], rax ; restore stack base
- mov rax, [rdx+058h] ; load stack limit
+ mov rax, [rdx+050h] ; load stack limit
mov [r10+010h], rax ; restore stack limit
mov rax, [rdx+068h] ; load fiber local storage
mov [r10+018h], rax ; restore fiber local storage
@@ -170,40 +170,44 @@
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
+make_fcontext PROC EXPORT FRAME ; generate function table entry in .pdata and unwind information in
.endprolog ; .xdata for a function's structured exception handling unwind behavior
+ push rbp ; save previous frame pointer; get the stack 16 byte aligned
+ mov rbp, rsp ; set RBP to RSP
+ sub rsp, 040h ; allocate shadow space
+
mov [rcx+048h], rdx ; save address of context function
- mov rdx, [rcx+050h] ; load address of context stack base
- mov r8, [rcx+060h] ; load context stack size
- neg r8 ; negate r8 for LEA
- lea r8, [rdx+r8] ; compute the address of context stack limit
- mov [rcx+058h], r8 ; save the address of context stack limit
+ mov rdx, [rcx+050h] ; load address of context stack pointer (limit)
+ mov r8, [rcx+058h] ; load context stack size
+ lea rdx, [rdx+r8] ; compute top address of context stack (base)
+ mov [rcx+060h], rdx ; save top address of context stack (base)
- push rcx ; save pointer to fcontext_t
- sub rsp, 028h ; reserve shadow space for align_stack
+ mov [rbp-08h], rcx ; save pointer to fcontext_t
mov rcx, rdx ; context stack pointer as arg for align_stack
- mov [rsp+8], rcx
call align_stack ; call align_stack
mov rdx, rax ; begin of aligned context 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 begins
+ mov rcx, [rbp-08h] ; restore pointer to fcontext_t
stmxcsr [rcx+070h] ; save MMX control and status word
fnstcw [rcx+074h] ; 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
+ lea rdx, [rdx-028h] ; reserve 32byte shadow space + return address on stack, (RSP - 0x8) % 16 == 0
+ mov [rcx+040h], rdx ; save address in RDX as stack pointer for context function
+
+ lea rax, finish ; compute abs address of label finish
+ mov [rdx], rax ; save address of finish as return address for context function
+ ; entered after context function returns
+
+ add rsp, 040h ; deallocate shadow space
+ pop rbp ; restore previous frame pointer
- xor rax, rax ; set RAX to zero
+ xor rax, rax
ret
finish:
- xor rcx, rcx
- mov [rsp+08h], rcx
+ ; RSP == stack pointer in fcontext + 0x8
+ xor rcx, rcx ; exit code is zero
call _exit ; exit application
hlt
make_fcontext ENDP
Modified: trunk/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_x86_64_sysv_elf_gas.S 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -26,7 +26,7 @@
* ---------------------------------------------------------------------------------- *
* | 0x40 | 0x44 | 0x48 | 0x4c | | *
* ---------------------------------------------------------------------------------- *
- * | sbase | slimit | | *
+ * | sp | size | | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 20 | 21 | | *
@@ -86,30 +86,41 @@
.type make_fcontext,@function
.align 16
make_fcontext:
- movq %rsi, 0x38(%rdi) /* save address of context function */
- movq 0x40(%rdi), %rdx /* load address of context stack base */
+ pushq %rbp /* save previous frame pointer; get the stack 16 byte aligned */
+ movq %rsp, %rbp /* set RBP to RSP */
+ subq $0x10, %rsp /* allocate stack space */
+
+ movq %rsi, 0x38(%rdi) /* save address of context function */
+ movq 0x40(%rdi), %rdx /* load address of context stack base */
+ movq 0x48(%rdi), %rax /* load size of context stack */
+ leaq (%rdx,%rax), %rdx /* compute top address of context stack */
+
+ movq %rdi, (%rsp) /* save pointer to fcontext_t */
+ movq %rdx, %rdi /* context stack pointer as arg for align_stack */
+ call align_stack_at_PLT /* align context stack */
+ movq %rax, %rdx /* begin of aligned context stack */
+ movq (%rsp), %rdi /* restore pointer to fcontext_t */
+
+ stmxcsr 0x50(%rdi) /* save MMX control and status word */
+ fnstcw 0x54(%rdi) /* save x87 control word */
+
+ leaq -0x8(%rdx), %rdx /* reserve space for the last frame on context stack, (RSP - 0x8) % 16 == 0 */
+ movq %rdx, 0x30(%rdi) /* save address in RDX as stack pointer for context function */
+
+ leaq finish(%rip), %rcx /* compute abs address of label finish */
+ movq %rcx, (%rdx) /* save address of finish as return address for context function */
+ /* entered after context function returns */
- pushq %rdi /* save pointer to fcontext_t */
- movq %rdx, %rdi /* context stack pointer as arg for align_stack */
- call align_stack_at_PLT /* align context stack */
- movq %rax, %rdx /* begin of aligned context stack */
- popq %rdi /* restore pointer to fcontext_t */
+ addq $0x10, %rsp /* deallocate shadow space */
+ popq %rbp /* restore previous frame pointer */
- leaq -0x8(%rdx), %rdx /* reserve space for the last frame on context stack, (RSP + 8) & 15 == 0 */
- movq %rdx, 0x30(%rdi) /* save the algined context 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
+ xorq %rax, %rax
ret
finish:
- xorq %rdi, %rdi /* exit code is zero */
- call _exit_at_PLT /* exit application */
+ /* RSP == stack pointer of context function + 0x8 */
+ xorq %rdi, %rdi /* exit code is zero */
+ call _exit_at_PLT /* exit application */
hlt
.size make_fcontext,.-make_fcontext
Modified: trunk/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S
==============================================================================
--- trunk/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S (original)
+++ trunk/libs/context/src/asm/fcontext_x86_64_sysv_macho_gas.S 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -26,7 +26,7 @@
* ---------------------------------------------------------------------------------- *
* | 0x40 | 0x44 | 0x48 | 0x4c | | *
* ---------------------------------------------------------------------------------- *
- * | sbase | slimit | | *
+ * | sp | size | | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 20 | 21 | | *
@@ -83,28 +83,39 @@
.globl _make_fcontext
.align 8
_make_fcontext:
- movq %rsi, 0x38(%rdi) /* save address of context function */
- movq 0x40(%rdi), %rdx /* load address of context stack base */
+ pushq %rbp /* save previous frame pointer; get the stack 16 byte aligned */
+ movq %rsp, %rbp /* set RBP to RSP */
+ subq $0x10, %rsp /* allocate stack space */
+
+ movq %rsi, 0x38(%rdi) /* save address of context function */
+ movq 0x40(%rdi), %rdx /* load address of context stack base */
+ movq 0x48(%rdi), %rax /* load size of context stack */
+ leaq (%rdx,%rax), %rdx /* compute top address of context stack */
+
+ movq %rdi, (%rsp) /* save pointer to fcontext_t */
+ movq %rdx, %rdi /* context stack pointer as arg for align_stack */
+ call _align_stack /* call align_stack */
+ movq %rax, %rdx /* begin of aligned context stack */
+ movq (%rsp), %rdi /* restore pointer to fcontext_t */
+
+ stmxcsr 0x50(%rdi) /* save MMX control and status word */
+ fnstcw 0x54(%rdi) /* save x87 control word */
+
+ leaq -0x8(%rdx), %rdx /* reserve space for the last frame on context stack, (RSP - 0x8) % 16 == 0 */
+ movq %rdx, 0x30(%rdi) /* save address in RDX as stack pointer for context function */
+
+ leaq finish(%rip), %rcx /* compute abs address of label finish */
+ movq %rcx, (%rdx) /* save address of finish as return address for context function */
+ /* entered after context function returns */
- pushq %rdi /* save pointer to fcontext_t */
- movq %rdx, %rdi /* context stack pointer as arg for align_stack */
- call _align_stack /* call align_stack */
- movq %rax, %rdx /* begin of aligned context stack */
- popq %rdi /* restore pointer to fcontext_t */
+ addq $0x10, %rsp /* deallocate shadow space */
+ popq %rbp /* restore previous frame pointer */
- leaq -0x8(%rdx), %rdx /* reserve space for the last frame on context stack, (RSP + 8) % 16 == 0 */
- movq %rdx, 0x30(%rdi) /* save the algined context stack base */
-
- 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 */
+ xorq %rax, %rax
ret
finish:
- xorq %rdi, %rdi /* exit code is zero */
- call _exit /* exit application */
+ /* RSP == stack pointer of context function + 0x8 */
+ xorq %rdi, %rdi /* exit code is zero */
+ call _exit /* exit application */
hlt
Modified: trunk/libs/context/src/stack_allocator_posix.cpp
==============================================================================
--- trunk/libs/context/src/stack_allocator_posix.cpp (original)
+++ trunk/libs/context/src/stack_allocator_posix.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -44,8 +44,10 @@
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 std::size_t pages( page_count( size) );
+ BOOST_ASSERT( 2 <= pages); // one page is reserved for protection
+ const std::size_t size_( pages * pagesize() );
+ BOOST_ASSERT( 0 < size && 0 < size_);
const int fd( ::open("/dev/zero", O_RDONLY) );
BOOST_ASSERT( -1 != fd);
@@ -61,7 +63,7 @@
const int result( ::mprotect( limit, pagesize(), PROT_NONE) );
BOOST_ASSERT( 0 == result);
- return static_cast< char * >( limit) + size_;
+ return limit;
}
void
@@ -69,11 +71,10 @@
{
if ( vp)
{
- const std::size_t pages( page_count( size) + 1); // add +1 for guard page
- std::size_t size_ = pages * pagesize();
+ const std::size_t pages = page_count( size);
+ const std::size_t size_ = pages * pagesize();
BOOST_ASSERT( 0 < size && 0 < size_);
- void * limit = static_cast< char * >( vp) - size_;
- ::munmap( limit, size_);
+ ::munmap( vp, size_);
}
}
Modified: trunk/libs/context/src/stack_allocator_windows.cpp
==============================================================================
--- trunk/libs/context/src/stack_allocator_windows.cpp (original)
+++ trunk/libs/context/src/stack_allocator_windows.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -46,10 +46,11 @@
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 std::size_t pages( page_count( size) );
+ BOOST_ASSERT( 2 <= pages); // one page is reserved for protection
+ const std::size_t size_ = pages * pagesize();
+ BOOST_ASSERT( 0 < size && 0 < size_);
-#ifndef BOOST_CONTEXT_FIBER
void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE);
if ( ! limit) throw std::bad_alloc();
@@ -58,8 +59,7 @@
limit, pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
BOOST_ASSERT( FALSE != result);
- return static_cast< char * >( limit) + size_;
-#endif
+ return limit;
}
void
@@ -67,11 +67,10 @@
{
if ( vp)
{
- const std::size_t pages( page_count( size) + 1); // add +1 for guard page
- std::size_t size_ = pages * pagesize();
+ const std::size_t pages = page_count( size);
+ const std::size_t size_ = pages * pagesize();
BOOST_ASSERT( 0 < size && 0 < size_);
- void * limit = static_cast< char * >( vp) - size_;
- ::VirtualFree( limit, 0, MEM_RELEASE);
+ ::VirtualFree( vp, 0, MEM_RELEASE);
}
}
Modified: trunk/libs/context/src/stack_utils_posix.cpp
==============================================================================
--- trunk/libs/context/src/stack_utils_posix.cpp (original)
+++ trunk/libs/context/src/stack_utils_posix.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -6,6 +6,8 @@
#define BOOST_CONTEXT_SOURCE
+#include <algorithm>
+
#include <boost/context/stack_utils.hpp>
extern "C" {
@@ -39,21 +41,41 @@
return limit;
}
+static std::size_t compute_default_stacksize_()
+{
+ std::size_t size = 256 * 1024; // 256 kB
+ if ( boost::ctx::is_stack_unbound() )
+ return std::max( size, boost::ctx::minimum_stacksize() );
+
+ BOOST_ASSERT( boost::ctx::maximum_stacksize() >= boost::ctx::minimum_stacksize() );
+ return boost::ctx::maximum_stacksize() == boost::ctx::minimum_stacksize()
+ ? boost::ctx::minimum_stacksize()
+ : std::min( size, boost::ctx::maximum_stacksize() );
+}
+
}
namespace boost {
namespace ctx {
BOOST_CONTEXT_DECL
-std::size_t default_stacksize()
+std::size_t pagesize()
{
- static std::size_t size = 256 * 1024;
+ static std::size_t size = ::getpagesize();
return size;
}
BOOST_CONTEXT_DECL
-std::size_t minimum_stacksize()
-{ return SIGSTKSZ; }
+std::size_t page_count( std::size_t stacksize)
+{
+ return static_cast< std::size_t >(
+ std::ceil(
+ static_cast< float >( stacksize) / pagesize() ) );
+}
+
+BOOST_CONTEXT_DECL
+bool is_stack_unbound()
+{ return RLIM_INFINITY == stacksize_limit().rlim_max; }
BOOST_CONTEXT_DECL
std::size_t maximum_stacksize()
@@ -63,22 +85,18 @@
}
BOOST_CONTEXT_DECL
-bool is_stack_unbound()
-{ return RLIM_INFINITY == stacksize_limit().rlim_max; }
-
-BOOST_CONTEXT_DECL
-std::size_t pagesize()
+std::size_t minimum_stacksize()
{
- static std::size_t pagesize( ::getpagesize() );
- return pagesize;
+ // space for guard page added
+ static std::size_t size = SIGSTKSZ + pagesize();
+ return size;
}
BOOST_CONTEXT_DECL
-std::size_t page_count( std::size_t stacksize)
+std::size_t default_stacksize()
{
- return static_cast< std::size_t >(
- std::ceil(
- static_cast< float >( stacksize) / pagesize() ) );
+ static std::size_t size = compute_default_stacksize_();
+ return size;
}
}}
Modified: trunk/libs/context/src/stack_utils_windows.cpp
==============================================================================
--- trunk/libs/context/src/stack_utils_windows.cpp (original)
+++ trunk/libs/context/src/stack_utils_windows.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -5,6 +5,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CONTEXT_SOURCE
+#define NOMINMAX
#include <boost/context/stack_utils.hpp>
@@ -32,53 +33,67 @@
return si;
}
+static std::size_t compute_default_stacksize_()
+{
+ std::size_t size = 256 * 1024; // 256 kB
+ if ( boost::ctx::is_stack_unbound() )
+ return std::max( size, boost::ctx::minimum_stacksize() );
+
+ BOOST_ASSERT( boost::ctx::maximum_stacksize() >= boost::ctx::minimum_stacksize() );
+ return boost::ctx::maximum_stacksize() == boost::ctx::minimum_stacksize()
+ ? boost::ctx::minimum_stacksize()
+ : std::min( size, boost::ctx::maximum_stacksize() );
+}
+
}
namespace boost {
namespace ctx {
BOOST_CONTEXT_DECL
-std::size_t default_stacksize()
+std::size_t pagesize()
{
- static std::size_t size = 256 * 1024;
+ static std::size_t size =
+ static_cast< std::size_t >( system_info().dwPageSize);
return size;
}
BOOST_CONTEXT_DECL
-std::size_t minimum_stacksize()
+std::size_t page_count( std::size_t stacksize)
{
- static std::size_t stacksize(
- static_cast< std::size_t >( system_info().dwAllocationGranularity) );
- return stacksize;
+ return static_cast< std::size_t >(
+ std::ceil(
+ static_cast< float >( stacksize) / pagesize() ) );
}
+// 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 maximum_stacksize()
{
BOOST_ASSERT( ! is_stack_unbound() );
- static std::size_t stacksize = 8 * 1024 * 1024;
- return stacksize;
+ static std::size_t size = 1 * 1024 * 1024 * 1024; // 1GB
+ return size;
}
-// 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()
+std::size_t minimum_stacksize()
{
- static std::size_t pagesize(
- static_cast< std::size_t >( system_info().dwPageSize) );
- return pagesize;
+ // space for guard page added
+ static std::size_t size =
+ static_cast< std::size_t >( system_info().dwAllocationGranularity)
+ + pagesize();
+ return size;
}
BOOST_CONTEXT_DECL
-std::size_t page_count( std::size_t stacksize)
+std::size_t default_stacksize()
{
- return static_cast< std::size_t >(
- std::ceil(
- static_cast< float >( stacksize) / pagesize() ) );
+ static std::size_t size = compute_default_stacksize_();
+ return size;
}
}}
Modified: trunk/libs/context/test/test_context.cpp
==============================================================================
--- trunk/libs/context/test/test_context.cpp (original)
+++ trunk/libs/context/test/test_context.cpp 2012-08-31 15:50:07 EDT (Fri, 31 Aug 2012)
@@ -74,13 +74,20 @@
ctx::jump_fcontext( & fc1, & fcm, 0);
}
+void test_stack_utils()
+{
+ if ( ! ctx::is_stack_unbound() )
+ BOOST_CHECK( ctx::maximum_stacksize() >= ctx::default_stacksize() );
+ BOOST_CHECK( ctx::default_stacksize() >= ctx::minimum_stacksize() );
+}
+
void test_start()
{
value1 = 0;
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
+ fc1.fc_stack.sp = alloc.allocate( ctx::minimum_stacksize() );
fc1.fc_stack.size = ctx::minimum_stacksize();
ctx::make_fcontext( & fc1, f1);
@@ -95,7 +102,7 @@
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
+ fc1.fc_stack.sp = alloc.allocate( ctx::minimum_stacksize() );
fc1.fc_stack.size = ctx::minimum_stacksize();
ctx::make_fcontext( & fc1, f3);
@@ -110,7 +117,7 @@
{
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
+ fc1.fc_stack.sp = alloc.allocate( ctx::minimum_stacksize() );
fc1.fc_stack.size = ctx::minimum_stacksize();
ctx::make_fcontext( & fc1, f4);
@@ -122,7 +129,7 @@
{
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
+ fc1.fc_stack.sp = alloc.allocate( ctx::minimum_stacksize() );
fc1.fc_stack.size = ctx::minimum_stacksize();
int i = 7;
ctx::make_fcontext( & fc1, f5);
@@ -135,7 +142,7 @@
{
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
+ fc1.fc_stack.sp = alloc.allocate( ctx::minimum_stacksize() );
fc1.fc_stack.size = ctx::minimum_stacksize();
std::pair< int, int > data = std::make_pair( 3, 7);
ctx::make_fcontext( & fc1, f6);
@@ -151,7 +158,7 @@
{
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
+ fc1.fc_stack.sp = alloc.allocate( ctx::minimum_stacksize() );
fc1.fc_stack.size = ctx::minimum_stacksize();
const char * what = "hello world";
ctx::make_fcontext( & fc1, f7);
@@ -164,7 +171,7 @@
{
ctx::stack_allocator alloc;
- fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() );
+ fc1.fc_stack.sp = alloc.allocate( ctx::minimum_stacksize() );
fc1.fc_stack.size = ctx::minimum_stacksize();
double d = 7.13;
ctx::make_fcontext( & fc1, f8);
@@ -178,6 +185,7 @@
boost::unit_test::test_suite * test =
BOOST_TEST_SUITE("Boost.Context: context test suite");
+ test->add( BOOST_TEST_CASE( & test_stack_utils) );
test->add( BOOST_TEST_CASE( & test_start) );
test->add( BOOST_TEST_CASE( & test_jump) );
test->add( BOOST_TEST_CASE( & test_result) );
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk