From 59030bfc59ea2d9fd5350b03cbb8c9bcdb326c51 Mon Sep 17 00:00:00 2001 From: Richard Boulton Date: Thu, 21 Sep 2000 00:57:09 +0000 Subject: [PATCH] Patch from Chris Emerson for PPC. cothreads stuff was causing segfaults, because the stack needs to be initialised w... 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 | 1 + gst/cothreads.c | 1 + gst/gsti386.h | 2 ++ gst/gstppc.h | 15 +++++++++-- test/cothreads/cothreads.c | 66 ++++++++++++++++++++++++++++++++++------------ 5 files changed, 66 insertions(+), 19 deletions(-) diff --git a/AUTHORS b/AUTHORS index 5e038ae..a7e2454 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,3 +1,4 @@ Erik Walthinsen Wim Taymans Richard Boulton +Chris Emerson (PPC port) diff --git a/gst/cothreads.c b/gst/cothreads.c index 7d422c8..32062fe 100644 --- a/gst/cothreads.c +++ b/gst/cothreads.c @@ -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); diff --git a/gst/gsti386.h b/gst/gsti386.h index beab1ae..b7faf1d 100644 --- a/gst/gsti386.h +++ b/gst/gsti386.h @@ -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 */ diff --git a/gst/gstppc.h b/gst/gstppc.h index be633df..9678bae 100644 --- a/gst/gstppc.h +++ b/gst/gstppc.h @@ -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 */ diff --git a/test/cothreads/cothreads.c b/test/cothreads/cothreads.c index 4d57fe0..43d43a9 100644 --- a/test/cothreads/cothreads.c +++ b/test/cothreads/cothreads.c @@ -8,18 +8,21 @@ #include #include +#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"); } } -- 2.7.4