[前][次][番号順一覧][スレッド一覧]

ruby-changes:54094

From: odaira <ko1@a...>
Date: Tue, 11 Dec 2018 08:23:03 +0900 (JST)
Subject: [ruby-changes:54094] odaira:r66315 (trunk): Native coroutine implementation for ppc64le Linux

odaira	2018-12-11 08:22:56 +0900 (Tue, 11 Dec 2018)

  New Revision: 66315

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66315

  Log:
    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

  Added directories:
    trunk/coroutine/ppc64le/
  Added files:
    trunk/coroutine/ppc64le/Context.S
    trunk/coroutine/ppc64le/Context.h
  Modified files:
    trunk/configure.ac
Index: coroutine/ppc64le/Context.h
===================================================================
--- coroutine/ppc64le/Context.h	(nonexistent)
+++ coroutine/ppc64le/Context.h	(revision 66315)
@@ -0,0 +1,54 @@ https://github.com/ruby/ruby/blob/trunk/coroutine/ppc64le/Context.h#L1
+#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
Index: coroutine/ppc64le/Context.S
===================================================================
--- coroutine/ppc64le/Context.S	(nonexistent)
+++ coroutine/ppc64le/Context.S	(revision 66315)
@@ -0,0 +1,72 @@ https://github.com/ruby/ruby/blob/trunk/coroutine/ppc64le/Context.S#L1
+.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
Index: configure.ac
===================================================================
--- configure.ac	(revision 66314)
+++ configure.ac	(revision 66315)
@@ -2331,6 +2331,9 @@ AS_CASE(["$rb_cv_fiber_coroutine"], [yes https://github.com/ruby/ruby/blob/trunk/configure.ac#L2331
 	[x64-mingw32], [
 	    rb_cv_fiber_coroutine=win64
 	],
+	[powerpc64le-linux], [
+	    rb_cv_fiber_coroutine=ppc64le
+	],
 	[*], [
 	    rb_cv_fiber_coroutine=
 	]

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]