Patch from Chris Emerson for PPC. cothreads stuff was causing segfaults, because...
authorRichard Boulton <richard@tartarus.org>
Thu, 21 Sep 2000 00:57:09 +0000 (00:57 +0000)
committerRichard Boulton <richard@tartarus.org>
Thu, 21 Sep 2000 00:57:09 +0000 (00:57 +0000)
Original commit message from CVS:
Patch from Chris Emerson for PPC.  cothreads stuff was causing segfaults,
because the stack needs to be initialised with a particular structure on
PPC, unlike x86 where it simply has items pushed or popped.
Added Chris to AUTHORS, for his trouble.

AUTHORS
gst/cothreads.c
gst/gsti386.h
gst/gstppc.h
test/cothreads/cothreads.c

diff --git a/AUTHORS b/AUTHORS
index 5e038ae..a7e2454 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,3 +1,4 @@
 Erik Walthinsen <omega@cse.ogi.edu>
 Wim Taymans <wim.taymans@tvd.be>
 Richard Boulton <richard@tartarus.org>
+Chris Emerson (PPC port)
index 7d422c8..32062fe 100644 (file)
@@ -152,6 +152,7 @@ void cothread_switch(cothread_state *thread) {
     // switch to it
     longjmp(thread->jmp,1);
   } else {
+    SETUP_STACK(thread->sp);
     SET_SP(thread->sp);
     // start it
     //JUMP(cothread_stub);
index beab1ae..b7faf1d 100644 (file)
@@ -10,4 +10,6 @@
 #define JUMP(target) \
     __asm__("jmp " SYMBOL_NAME_STR(cothread_stub))
 
+#define SETUP_STACK(sp) do ; while(0)
+
 #endif /* GST_HGUARD_GSTI386_H */
index be633df..9678bae 100644 (file)
@@ -4,12 +4,23 @@
 /* FIXME: Hmm - does this work?
  */
 #define GET_SP(target) \
-       __asm__("stw 1,%0" : "=m"(target) : : "r1");
+    __asm__("stw 1,%0" : "=m"(target) : : "r1");
 
 #define SET_SP(source) \
-       __asm__("lwz 1,%0" : "=m"(source))
+    __asm__("lwz 1,%0" : "=m"(source))
 
 #define JUMP(target) \
     __asm__("b " SYMBOL_NAME_STR(cothread_stub))
 
+struct minimal_ppc_stackframe {
+    unsigned long back_chain;
+    unsigned long LR_save;
+    unsigned long unused1;
+    unsigned long unused2;
+};
+
+#define SETUP_STACK(sp) \
+    sp = ((unsigned long *)(sp)) - 4; \
+    ((struct minimal_ppc_stackframe *)sp)->back_chain = 0;
+
 #endif /* GST_HGUARD_GSTPPC_H */
index 4d57fe0..43d43a9 100644 (file)
@@ -8,18 +8,21 @@
 #include <unistd.h>
 #include <sys/mman.h>
 
+#define DEBUG_ENABLED
+#include "gst/gst.h"
 #include "cothreads.h"
+#include "gst/gstarch.h"
 
 pthread_key_t _cothread_key = -1;
 
 cothread_state *cothread_create(cothread_context *ctx) {
   cothread_state *s;
 
-  printf("pthread_self() %ld\n",pthread_self());
+  DEBUG("cothread: pthread_self() %ld\n",pthread_self());
   //if (pthread_self() == 0) {
   if (0) {
     s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
-    printf("new stack at %p\n",s);
+    DEBUG("cothread: new stack at %p\n",s);
   } else {
     char *sp = CURRENT_STACK_FRAME;
     unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
@@ -41,7 +44,7 @@ cothread_state *cothread_create(cothread_context *ctx) {
 
   ctx->threads[ctx->nthreads++] = s;
 
-  printf("created cothread at %p %p\n",s, s->sp);
+  DEBUG("cothread: created cothread at %p %p\n",s, s->sp);
 
   return s;
 }
@@ -76,7 +79,7 @@ cothread_context *cothread_init() {
   ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
   ctx->threads[0]->pc = 0;
 
-  fprintf(stderr,"0th thread is at %p %p\n",ctx->threads[0], ctx->threads[0]->sp);
+  DEBUG("cothread: 0th thread is at %p %p\n",ctx->threads[0], ctx->threads[0]->sp);
 
   // we consider the initiating process to be cothread 0
   ctx->nthreads = 1;
@@ -94,58 +97,87 @@ void cothread_stub() {
   cothread_context *ctx = pthread_getspecific(_cothread_key);
   register cothread_state *thread = ctx->threads[ctx->current];
 
-  printf("cothread_stub() entered\n");
+  DEBUG("cothread: cothread_stub() entered\n");
   thread->flags |= COTHREAD_STARTED;
   if (thread->func)
     thread->func(thread->argc,thread->argv);
   thread->flags &= ~COTHREAD_STARTED;
   thread->pc = 0;
+  DEBUG("cothread: cothread_stub() exit\n");
   //printf("uh, yeah, we shouldn't be here, but we should deal anyway\n");
 }
 
 void cothread_switch(cothread_state *thread) {
   cothread_context *ctx;
   cothread_state *current;
-  int enter = 0;
+  int enter;
 //  int i;
+//
+  DEBUG("thread = %p\n", thread);
 
   if (thread == NULL)
     return;
 
+  DEBUG("ctx = %p\n", ctx);
+
   ctx = thread->ctx;
+  
+  DEBUG("ctx->threads = %p\n", ctx->threads);
 
   current = ctx->threads[ctx->current];
+
+  DEBUG("ctx->current = %d\n", ctx->current);
+  DEBUG("current->threadnum = %d\n", current->threadnum);
+  DEBUG("current = %p\n", current);
   if (current == NULL) {
-    fprintf(stderr,"there's no current thread, help!\n");
+    g_print("cothread: there's no current thread, help!\n");
     exit(2);
   }
 
+  /*
   if (current == thread) {
-    fprintf(stderr,"trying to switch to same thread, legal but not necessary\n");
-    return;
+    g_print("cothread: trying to switch to same thread, legal but not necessary\n");
+    //return;
   }
+  */
 
   // find the number of the thread to switch to
   ctx->current = thread->threadnum;
-  fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
+  DEBUG("cothread: about to switch to thread #%d\n",ctx->current);
 
   /* save the current stack pointer, frame pointer, and pc */
-  __asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
+  GET_SP(current->sp);
   enter = setjmp(current->jmp);
-  if (enter != 0)
+  DEBUG("cothread: SP is %p\n", current->sp);
+  DEBUG("cothread: after thread #%d %d\n",ctx->current, enter);
+  if (enter != 0) {
     return;
+  }
   enter = 1;
 
-  fprintf(stderr,"set stack to %p\n", thread->sp);
+  DEBUG("cothread: set stack to %p\n", thread->sp);
   /* restore stack pointer and other stuff of new cothread */
   if (thread->flags & COTHREAD_STARTED) {
-    fprintf(stderr,"in thread \n");
-    __asm__("movl %0, %%esp\n" : "=m"(thread->sp));
+    void *temp1, *temp2;
+    DEBUG("cothread: in thread \n");
+    GET_SP(temp1);
+    SET_SP(thread->sp);
+    GET_SP(temp2);
+    DEBUG("SP %p -> %p\n", temp1, temp2);
     // switch to it
     longjmp(thread->jmp,1);
   } else {
-    __asm__("movl %0, %%esp\n" : "=m"(thread->sp));
+    void *temp1, *temp2;
+    SETUP_STACK(thread->sp);
+    GET_SP(temp1);
+    SET_SP(thread->sp);
+    GET_SP(temp2);
+    DEBUG("thead[2].num = %d\n", ctx->threads[2]->threadnum);
+    DEBUG("SP %p -> %p\n", temp1, temp2);
+    DEBUG("thead[2].num = %d\n", ctx->threads[2]->threadnum);
     // start it
-    __asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
+    //JUMP(cothread_stub);
+    cothread_stub();
+    DEBUG("cothread: exit thread \n");
   }
 }