Source: python-greenlet
Severity: important
Tags: upstream patch

The 0.3.1 version of python-greenlet does not seem to behave on
armhf.  The following code will show the problem:

from greenlet import greenlet

def test1():
        print 12
        gr2.switch()
        print 34

def test2():
        print 56
        gr1.switch()
        print 78

print 'Correct answer is:'
print '12'
print '56'
print '34'

print 'Actual answer is:'
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()


However, the 0.3.3 version will not compile, either.  So, the attached
patch (sorry, not my best work ever ... I'm in a hurry) does two things:
(1) add -fomit-frame-pointer to the compile so that r7 can actually be
saved, and (2) changes platform/switch_arm32_gcc.h to incorporate the
latest upstream changes (which were insufficient) and be more conversative
in what gets saved on task switch.  With the changes, 0.3.3 builds on
armhf and passes the test suite with no errors.
Index: python-greenlet-0.3.3/setup.py
===================================================================
--- python-greenlet-0.3.3.orig/setup.py	2012-02-08 18:34:38.000000000 +0000
+++ python-greenlet-0.3.3/setup.py	2012-04-27 21:34:57.000000000 +0000
@@ -7,6 +7,10 @@
 if sys.platform == "openbsd4" and os.uname()[-1] == "i386":
     os.environ["CFLAGS"] = ("%s %s" % (os.environ.get("CFLAGS", ""), "-Os")).lstrip()
 
+# workaround segfaults on ARMv7
+if sys.platform == "linux2" and os.uname()[-1] == "armv7l":
+    os.environ["CFLAGS"] = ("%s %s" % (os.environ.get("CFLAGS", ""), "-fomit-frame-pointer")).lstrip()
+
 try:
     from setuptools import setup, Extension
     setuptools_args = dict(test_suite='tests.test_collector', zip_safe=False)
Index: python-greenlet-0.3.3/platform/switch_arm32_gcc.h
===================================================================
--- python-greenlet-0.3.3.orig/platform/switch_arm32_gcc.h	2012-02-08 18:34:38.000000000 +0000
+++ python-greenlet-0.3.3/platform/switch_arm32_gcc.h	2012-04-27 21:40:55.000000000 +0000
@@ -25,7 +25,20 @@
 
 #ifdef SLP_EVAL
 #define STACK_MAGIC 0
-#define REGS_TO_SAVE "r4", "r5", "r6", "r7", "r8", "r9", "lr"
+#define REGS_TO_SAVE_GENERAL "r4", "r5", "r6", "r7", "r8", "r9", \
+			     "r10", "r11", "ip", "sp", "lr", "pc"
+#if defined(__SOFTFP__)
+#define REGS_TO_SAVE REGS_TO_SAVE_GENERAL
+#elif defined(__VFP_FP__)
+#define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "d8", "d9", "d10", "d11", \
+                                           "d12", "d13", "d14", "d15"
+#elif defined(__MAVERICK__)
+#define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "mvf4", "mvf5", "mvf6", "mvf7", \
+                                           "mvf8", "mvf9", "mvf10", "mvf11", \
+                                           "mvf12", "mvf13", "mvf14", "mvf15"
+#else
+#define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "f4", "f5", "f6", "f7"
+#endif
 
 static int
 slp_switch(void)
@@ -33,8 +46,8 @@
         void *fp;
         register int *stackref, stsizediff;
         __asm__ volatile ("" : : : REGS_TO_SAVE);
-        __asm__ volatile ("str fp,%0" : "=m" (fp));
-        __asm__ ("mov %0,sp" : "=g" (stackref));
+        __asm__ volatile ("mov r0, fp\n\tstr r0, %0" : "=m" (fp) : : "r0");
+        __asm__ ("mov %0,sp" : "=r" (stackref));
         {
                 SLP_SAVE_STATE(stackref, stsizediff);
                 __asm__ volatile (
@@ -45,9 +58,9 @@
                     );
                 SLP_RESTORE_STATE();
         }
-        __asm__ volatile ("ldr fp,%0" : : "m" (fp));
+        __asm__ volatile ("ldr r0, %0\n\tmov fp, r0" : : "m" (fp) : "r0");
         __asm__ volatile ("" : : : REGS_TO_SAVE);
         return 0;
 }
 
-#endif
\ No newline at end of file
+#endif

Reply via email to