From 01596ff37a9268d76199be8d6e601344393c097d Mon Sep 17 00:00:00 2001 From: FritzFlorian Date: Thu, 30 Jan 2020 13:17:46 +0100 Subject: [PATCH] Change context_switch app to use context_switcher library. --- app/context_switch/CMakeLists.txt | 10 +++------- app/context_switch/fiber_call.h | 68 -------------------------------------------------------------------- app/context_switch/fiber_call_arm32.s | 53 ----------------------------------------------------- app/context_switch/fiber_call_x86_64.s | 78 ------------------------------------------------------------------------------ app/context_switch/fiber_continue_arm32.s | 38 -------------------------------------- app/context_switch/fiber_continue_x86_64.s | 56 -------------------------------------------------------- app/context_switch/main.cpp | 10 +++++----- 7 files changed, 8 insertions(+), 305 deletions(-) delete mode 100644 app/context_switch/fiber_call.h delete mode 100644 app/context_switch/fiber_call_arm32.s delete mode 100644 app/context_switch/fiber_call_x86_64.s delete mode 100644 app/context_switch/fiber_continue_arm32.s delete mode 100644 app/context_switch/fiber_continue_x86_64.s diff --git a/app/context_switch/CMakeLists.txt b/app/context_switch/CMakeLists.txt index 99f4482..059a778 100644 --- a/app/context_switch/CMakeLists.txt +++ b/app/context_switch/CMakeLists.txt @@ -2,10 +2,8 @@ add_subdirectory(deboost.context) if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") SET(SWITCH_ASSEMBLY "custom_stack_callback_x86_64.s") - SET(FIBER_ASSEMBLY "fiber_call_x86_64.s" "fiber_continue_x86_64.s") elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - SET(SWITCH_ASSEMBLY "custom_stack_callback_arm32.s" fiber_call.h context_switcher.cpp) - SET(FIBER_ASSEMBLY "fiber_call_arm32.s" "fiber_continue_arm32.s") + SET(SWITCH_ASSEMBLY "custom_stack_callback_arm32.s") else () MESSAGE(FATAL_ERROR "Platform (${CMAKE_SYSTEM_PROCESSOR} on ${CMAKE_SYSTEM_NAME}) not supported! Please see Readme for instructions to port.") endif () @@ -13,9 +11,7 @@ endif () add_executable(context_switch main.cpp - ${SWITCH_ASSEMBLY} - fiber_call.h - ${FIBER_ASSEMBLY}) + ${SWITCH_ASSEMBLY}) # Example for adding the library to your app (as a cmake project dependency) -target_link_libraries(context_switch fcontext) +target_link_libraries(context_switch fcontext context_switcher) diff --git a/app/context_switch/fiber_call.h b/app/context_switch/fiber_call.h deleted file mode 100644 index c6bae39..0000000 --- a/app/context_switch/fiber_call.h +++ /dev/null @@ -1,68 +0,0 @@ - -#ifndef PREDICTABLE_PARALLEL_PATTERNS_APP_CONTEXT_SWITCH_FIBER_CALL_H_ -#define PREDICTABLE_PARALLEL_PATTERNS_APP_CONTEXT_SWITCH_FIBER_CALL_H_ - -#include -#include -#include -#include - -namespace pls { -namespace internal { -namespace base { - -using continuation_t = void *; -using stack_pointer_t = char *; -using callback_t = continuation_t (*)(continuation_t, void *); - -template -struct lambda_capture { - F lambda_; - - explicit lambda_capture(F &&lambda) : lambda_{std::forward(lambda)} {} - - continuation_t operator()(continuation_t continuation) { - return lambda_(continuation); - } -}; - -template -continuation_t execute_callable(continuation_t continuation, void *param) { - T *callable = reinterpret_cast(param); - continuation_t result = (*callable)(continuation); - - callable->~T(); - return result; -} - -extern "C" { -continuation_t __fiber_call(stack_pointer_t stack_base, - void *callback_arg, - callback_t callback, - stack_pointer_t stack_limit); -continuation_t __fiber_continue(continuation_t continuation); -} - -template -static lambda_capture *place_lambda_capture(F &&lambda, char *memory) { - return new(memory) lambda_capture(std::forward(lambda)); -} - -template -continuation_t fiber_call(stack_pointer_t stack_memory, size_t stack_size, F &&lambda) { - stack_pointer_t lambda_memory = stack_memory + stack_size - sizeof(lambda_capture); - auto *captured_lambda = place_lambda_capture(std::forward(lambda), lambda_memory); - - stack_pointer_t stack_base = lambda_memory; - stack_pointer_t stack_limit = stack_memory; - - callback_t callback = execute_callable>; - - return __fiber_call(stack_base, captured_lambda, callback, stack_limit); -} - -} -} -} - -#endif //PREDICTABLE_PARALLEL_PATTERNS_APP_CONTEXT_SWITCH_FIBER_CALL_H_ diff --git a/app/context_switch/fiber_call_arm32.s b/app/context_switch/fiber_call_arm32.s deleted file mode 100644 index 03a1c86..0000000 --- a/app/context_switch/fiber_call_arm32.s +++ /dev/null @@ -1,53 +0,0 @@ - .arm - .text - .global __fiber_call - .type __fiber_call, %function - -__fiber_call: - /* Parameter List (in order) - * r0 = new stack pointer - * r1 = first parameter to callback - * r2 = callback function pointer - * r3 = new stack limit (not used on most platforms) - * - * Return - * r0 = continuation that returned control back to the caller (null if fallthrough) - * - * Variables - * r4 = temporary for the old stack pointer */ - - /* ========== Save State ========== */ - /* store programm counter for later return */ - push {lr} - /* store callee saved registers */ - push {r4-r12,lr} - /* ========== Save State ========== */ - - /* Perform change to new stack */ - /* Keep old stack as second parameter to our callback function. */ - mov r4, sp - /* Make sure that stack start is properly aligned. */ - and r0, r0, #-16 - /* Switch to new stack pointer. */ - mov sp, r0 - - /* Perform actual function call, this will now be on the new stack */ - /* r0 = first parametor to callback (continuation) */ - /* r1 = second parameter to callback (arbetary pointer) */ - mov r0, r4 - blx r2 - - /* Restore state of returned continuation. */ - /* To do so we first reset the stack pointer (which we get returned in r0). */ - /* After that we execute our standard restore procedere to pop the state from the stack. */ - mov sp, r0 - - /* ========== Restore State ========== */ - /* restore callee saved registers */ - pop {r4-r12,lr} - /* ========== Restore State ========== */ - - /* Just return back from the call. */ - /* This is the end of a fiber, so we have no continuation. */ - eor r0, r0, r0 - pop {pc} diff --git a/app/context_switch/fiber_call_x86_64.s b/app/context_switch/fiber_call_x86_64.s deleted file mode 100644 index 1232f1c..0000000 --- a/app/context_switch/fiber_call_x86_64.s +++ /dev/null @@ -1,78 +0,0 @@ - .file "fiber_call_x86_64.s" - .text - .global __fiber_call - .type __fiber_call, @function - -.align 16 -__fiber_call: - # Parameter List (in order) - # rdi = new stack pointer - # rsi = first parameter to callback - # rdx = callback function pointer - # rcx = new stack limit (not used on most platforms) - - # Return - # rax = continuation that returned control back to the caller (null if fallthrough) - - # Variables - # r12 = temporary for the old stack pointer - - ############### Save State ############### - # Make space for all register state we will store. - leaq -0x38(%rsp), %rsp - - # Store calee saved general registers. - movq %r12, 0x00(%rsp) - movq %r13, 0x08(%rsp) - movq %r14, 0x10(%rsp) - movq %r15, 0x18(%rsp) - movq %rbx, 0x20(%rsp) - movq %rbp, 0x28(%rsp) - # Store MMX control- and status-word - stmxcsr 0x30(%rsp) - # Store x87 control-word - fnstcw 0x34(%rsp) - ############### Save State ############### - - # Perform change to new stack. - # Keep old stack as second parameter to our callback function. - movq %rsp, %r12 - # Make sure that stack start is properly aligned. - andq $-16, %rdi - # Switch to new stack pointer. - movq %rdi, %rsp - - # Perform actual function call, this will now be on the new stack - # rdi = first parametor to callback (continuation) - # rsi = second parameter to callback (arbetary pointer) - movq %r12, %rdi - call *%rdx - - # Restore state of returned continuation. - # To do so we first reset the stack pointer (which we get returned in rax). - # After that we execute our standard restore procedere to pop the state from the stack. - movq %rax, %rsp - - ############ Restore State ############ - # restore calee saved general registers - movq 0x00(%rsp), %r12 - movq 0x08(%rsp), %r13 - movq 0x10(%rsp), %r14 - movq 0x18(%rsp), %r15 - movq 0x20(%rsp), %rbx - movq 0x28(%rsp), %rbp - # restore MMX control- and status-word - ldmxcsr 0x30(%rsp) - # restore x87 control-word - fldcw 0x34(%rsp) - - # Free space for restored state - leaq 0x38(%rsp), %rsp - ############ Restore State ############ - - # TODO: Maybe look into a 'cleanup' hook for freeing the stack space here. - - # Just return back from the call. - # This is the end of a fiber, so we have no continuation. - xor %rax, %rax - ret diff --git a/app/context_switch/fiber_continue_arm32.s b/app/context_switch/fiber_continue_arm32.s deleted file mode 100644 index d99596b..0000000 --- a/app/context_switch/fiber_continue_arm32.s +++ /dev/null @@ -1,38 +0,0 @@ - .arm - .text - .global __fiber_continue - .type __fiber_continue, %function - -__fiber_continue: - /* Parameter List (in order) - * r0 = pointer to continuation (should hold value of target stack will be filled with this continuation) - * - * Return - * r0 = continuation that returned control back to the caller (null if fallthrough) - * - * Variables - * r1 = temporary for the old stack pointer */ - - /* ========== Save State ========== */ - /* store programm counter for later return */ - push {lr} - /* store callee saved registers */ - push {r4-r12,lr} - /* ========== Save State ========== */ - - /* Perform change to new stack */ - /* Keep old stack as result from this function. */ - mov r1, sp - /* Switch to new stack pointer. */ - mov sp, r0 - - - /* ========== Restore State ========== */ - /* restore callee saved registers */ - pop {r4-r12,lr} - /* ========== Restore State ========== */ - - /* Just return back from the call. */ - /* This is the end of a fiber, so we have no continuation. */ - mov r0, r1 - pop {pc} diff --git a/app/context_switch/fiber_continue_x86_64.s b/app/context_switch/fiber_continue_x86_64.s deleted file mode 100644 index 6044737..0000000 --- a/app/context_switch/fiber_continue_x86_64.s +++ /dev/null @@ -1,56 +0,0 @@ - .file "fiber_continue_x86_64.s" - .text - .global __fiber_continue - .type __fiber_continue, @function - -.align 16 -__fiber_continue: - # Parameter List (in order) - # rdi = pointer to continuation (should hold value of target stack will be filled with this continuation) - - # Return - # rax = continuation that returned control back to the caller (null if fallthrough) - - ############### Save State ############### - # Make space for all register state we will store. - leaq -0x38(%rsp), %rsp - - # Store calee saved general registers. - movq %r12, 0x00(%rsp) - movq %r13, 0x08(%rsp) - movq %r14, 0x10(%rsp) - movq %r15, 0x18(%rsp) - movq %rbx, 0x20(%rsp) - movq %rbp, 0x28(%rsp) - # Store MMX control- and status-word - stmxcsr 0x30(%rsp) - # Store x87 control-word - fnstcw 0x34(%rsp) - ############### Save State ############### - - # Perform change to new stack. - # Keep old stack as result from this function - movq %rsp, %rax - # switch to new stack pointer - movq %rdi, %rsp - - ############ Restore State ############ - # restore calee saved general registers - movq 0x00(%rsp), %r12 - movq 0x08(%rsp), %r13 - movq 0x10(%rsp), %r14 - movq 0x18(%rsp), %r15 - movq 0x20(%rsp), %rbx - movq 0x28(%rsp), %rbp - # restore MMX control- and status-word - ldmxcsr 0x30(%rsp) - # restore x87 control-word - fldcw 0x34(%rsp) - - # Free space for restored state - leaq 0x38(%rsp), %rsp - ############ Restore State ############ - - # Return the context we came from as a continuation. - # Result is already in rax. - ret diff --git a/app/context_switch/main.cpp b/app/context_switch/main.cpp index b87d5f8..8fdbfcb 100644 --- a/app/context_switch/main.cpp +++ b/app/context_switch/main.cpp @@ -2,10 +2,12 @@ #include #include #include +#include #include "fcontext/fcontext.h" -#include "fiber_call.h" +#include "context_switcher/context_switcher.h" +#include "context_switcher/continuation.h" using namespace std; @@ -128,13 +130,11 @@ long measure_fcontext_callcc() { } long measure_custom() { - using namespace pls::internal::base; - auto start_time = chrono::steady_clock::now(); for (unsigned int i = 0; i < NUM_RUNS; i++) { - fiber_call(custom_stack_1, STACK_SIZE, [](continuation_t continuation) { + context_switcher::enter_context(custom_stack_1, STACK_SIZE, [](context_switcher::continuation &&continuation) { callback(); - return continuation; + return std::move(continuation); }); } auto end_time = chrono::steady_clock::now(); -- libgit2 0.26.0