mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Native coroutine implementation for ppc64le Linux
* configure.ac: enable fiber coroutine for powerpc64le-linux * coroutine/ppc64le/Context.S: coroutine_transfer implementation * coroutine/ppc64le/Context.h: coroutine implementation git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66315 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
dff1e89bfb
commit
3a5cc345f8
3 changed files with 129 additions and 0 deletions
|
@ -2331,6 +2331,9 @@ AS_CASE(["$rb_cv_fiber_coroutine"], [yes|''], [
|
|||
[x64-mingw32], [
|
||||
rb_cv_fiber_coroutine=win64
|
||||
],
|
||||
[powerpc64le-linux], [
|
||||
rb_cv_fiber_coroutine=ppc64le
|
||||
],
|
||||
[*], [
|
||||
rb_cv_fiber_coroutine=
|
||||
]
|
||||
|
|
72
coroutine/ppc64le/Context.S
Normal file
72
coroutine/ppc64le/Context.S
Normal file
|
@ -0,0 +1,72 @@
|
|||
.text
|
||||
.align 2
|
||||
|
||||
.globl coroutine_transfer
|
||||
.type coroutine_transfer, @function
|
||||
coroutine_transfer:
|
||||
# Make space on the stack for caller registers
|
||||
addi 1,1,-152
|
||||
|
||||
# Save caller registers
|
||||
std 14,0(1)
|
||||
std 15,8(1)
|
||||
std 16,16(1)
|
||||
std 17,24(1)
|
||||
std 18,32(1)
|
||||
std 19,40(1)
|
||||
std 20,48(1)
|
||||
std 21,56(1)
|
||||
std 22,64(1)
|
||||
std 23,72(1)
|
||||
std 24,80(1)
|
||||
std 25,88(1)
|
||||
std 26,96(1)
|
||||
std 27,104(1)
|
||||
std 28,112(1)
|
||||
std 29,120(1)
|
||||
std 30,128(1)
|
||||
std 31,136(1)
|
||||
|
||||
# Save return address
|
||||
mflr 0
|
||||
std 0,144(1)
|
||||
|
||||
# Save stack pointer to first argument
|
||||
std 1,0(3)
|
||||
|
||||
# Load stack pointer from second argument
|
||||
ld 1,0(4)
|
||||
|
||||
# Restore caller registers
|
||||
ld 14,0(1)
|
||||
ld 15,8(1)
|
||||
ld 16,16(1)
|
||||
ld 17,24(1)
|
||||
ld 18,32(1)
|
||||
ld 19,40(1)
|
||||
ld 20,48(1)
|
||||
ld 21,56(1)
|
||||
ld 22,64(1)
|
||||
ld 23,72(1)
|
||||
ld 24,80(1)
|
||||
ld 25,88(1)
|
||||
ld 26,96(1)
|
||||
ld 27,104(1)
|
||||
ld 28,112(1)
|
||||
ld 29,120(1)
|
||||
ld 30,128(1)
|
||||
ld 31,136(1)
|
||||
|
||||
# Load return address
|
||||
ld 0,144(1)
|
||||
mtlr 0
|
||||
|
||||
# Pop stack frame
|
||||
addi 1,1,152
|
||||
|
||||
# Jump to return address
|
||||
blr
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
54
coroutine/ppc64le/Context.h
Normal file
54
coroutine/ppc64le/Context.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define COROUTINE __attribute__((noreturn)) void
|
||||
|
||||
const size_t COROUTINE_REGISTERS =
|
||||
19 /* 18 general purpose registers (r14-r31) and 1 return address */
|
||||
+ 4; /* space for fiber_entry() to store the link register */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void **stack_pointer;
|
||||
} coroutine_context;
|
||||
|
||||
typedef COROUTINE(* coroutine_start)(coroutine_context *from, coroutine_context *self);
|
||||
|
||||
static inline void coroutine_initialize(
|
||||
coroutine_context *context,
|
||||
coroutine_start start,
|
||||
void *stack_pointer,
|
||||
size_t stack_size
|
||||
) {
|
||||
/* Force 16-byte alignment */
|
||||
context->stack_pointer = (void**)((uintptr_t)stack_pointer & ~0xF);
|
||||
|
||||
if (!start) {
|
||||
assert(!context->stack_pointer);
|
||||
/* We are main coroutine for this thread */
|
||||
return;
|
||||
}
|
||||
|
||||
context->stack_pointer -= COROUTINE_REGISTERS;
|
||||
memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
|
||||
|
||||
/* Skip a global prologue that sets the TOC register */
|
||||
context->stack_pointer[18] = ((char*)start) + 8;
|
||||
}
|
||||
|
||||
coroutine_context * coroutine_transfer(coroutine_context * current, coroutine_context * target);
|
||||
|
||||
static inline void coroutine_destroy(coroutine_context * context)
|
||||
{
|
||||
context->stack_pointer = NULL;
|
||||
}
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in a new issue