2000-11-11 15:13:50 +00:00
|
|
|
/* GStreamer
|
|
|
|
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2000-09-07 20:35:15 +00:00
|
|
|
#include <pthread.h>
|
2000-01-30 09:03:00 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <setjmp.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
/* we make too much noise for normal debugging... */
|
|
|
|
#define GST_DEBUG_FORCE_DISABLE
|
|
|
|
|
2000-12-15 01:57:34 +00:00
|
|
|
#include "gstdebug.h"
|
|
|
|
#include "cothreads.h"
|
|
|
|
#include "gstarch.h"
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
pthread_key_t _cothread_key = -1;
|
|
|
|
|
2000-11-29 10:05:47 +00:00
|
|
|
/* Disablig this define allows you to shut off a few checks in
|
|
|
|
* cothread_switch. This likely will speed things up fractionally */
|
|
|
|
#define COTHREAD_PARANOID
|
|
|
|
|
2000-11-11 15:13:50 +00:00
|
|
|
/**
|
|
|
|
* cothread_create:
|
|
|
|
* @ctx: the cothread context
|
|
|
|
*
|
|
|
|
* create a new cotread state in the given context
|
|
|
|
*
|
|
|
|
* Returns: the new cothread state
|
|
|
|
*/
|
2000-11-04 18:54:07 +00:00
|
|
|
cothread_state*
|
|
|
|
cothread_create (cothread_context *ctx)
|
|
|
|
{
|
2000-01-30 09:03:00 +00:00
|
|
|
cothread_state *s;
|
|
|
|
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG("pthread_self() %ld\n",pthread_self());
|
2000-11-01 22:11:48 +00:00
|
|
|
//if (0) {
|
|
|
|
if (pthread_self() == 0) {
|
2000-01-30 09:03:00 +00:00
|
|
|
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
|
2000-12-27 03:13:20 +00:00
|
|
|
DEBUG("new stack (case 1) at %p\n",s);
|
2000-01-30 09:03:00 +00:00
|
|
|
} else {
|
|
|
|
char *sp = CURRENT_STACK_FRAME;
|
|
|
|
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
|
|
|
|
~(STACK_SIZE - 1));
|
|
|
|
s = (cothread_state *)(stack_end + ((ctx->nthreads - 1) *
|
|
|
|
COTHREAD_STACKSIZE));
|
2000-12-27 03:13:20 +00:00
|
|
|
DEBUG("new stack (case 2) at %p\n",s);
|
2000-01-30 09:03:00 +00:00
|
|
|
if (mmap((char *)s,COTHREAD_STACKSIZE*(sizeof(int)),
|
2000-12-27 03:13:20 +00:00
|
|
|
PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS,
|
2000-01-30 09:03:00 +00:00
|
|
|
-1,0) < 0) {
|
|
|
|
perror("mmap'ing cothread stack space");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s->ctx = ctx;
|
|
|
|
s->threadnum = ctx->nthreads;
|
|
|
|
s->flags = 0;
|
2000-09-07 20:35:15 +00:00
|
|
|
s->sp = ((int *)s + COTHREAD_STACKSIZE);
|
2000-09-22 23:35:14 +00:00
|
|
|
s->top_sp = s->sp;
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
ctx->threads[ctx->nthreads++] = s;
|
|
|
|
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG("created cothread at %p %p\n",s, s->sp);
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2000-11-11 15:13:50 +00:00
|
|
|
/**
|
|
|
|
* cothread_setfunc:
|
|
|
|
* @thread: the cothread state
|
|
|
|
* @func: the function to call
|
|
|
|
* @argc: the argument count for the cothread function
|
|
|
|
* @argv: the arguments for the cothread function
|
|
|
|
*
|
|
|
|
* Set the cothread function
|
|
|
|
*/
|
2000-11-04 18:54:07 +00:00
|
|
|
void
|
|
|
|
cothread_setfunc (cothread_state *thread,
|
|
|
|
cothread_func func,
|
|
|
|
int argc,
|
|
|
|
char **argv)
|
|
|
|
{
|
2000-01-30 09:03:00 +00:00
|
|
|
thread->func = func;
|
|
|
|
thread->argc = argc;
|
|
|
|
thread->argv = argv;
|
|
|
|
thread->pc = (int *)func;
|
|
|
|
}
|
|
|
|
|
2000-11-11 15:13:50 +00:00
|
|
|
/**
|
|
|
|
* cothread_init:
|
|
|
|
*
|
|
|
|
* create and initialize a new cotread context
|
|
|
|
*
|
|
|
|
* Returns: the new cothread context
|
|
|
|
*/
|
2000-11-04 18:54:07 +00:00
|
|
|
cothread_context*
|
|
|
|
cothread_init (void)
|
|
|
|
{
|
2000-01-30 09:03:00 +00:00
|
|
|
cothread_context *ctx = (cothread_context *)malloc(sizeof(cothread_context));
|
|
|
|
|
|
|
|
if (_cothread_key == -1) {
|
2000-11-04 18:54:07 +00:00
|
|
|
if (pthread_key_create (&_cothread_key,NULL) != 0) {
|
|
|
|
perror ("pthread_key_create");
|
2000-02-27 23:18:38 +00:00
|
|
|
return NULL;
|
2000-01-30 09:03:00 +00:00
|
|
|
}
|
|
|
|
}
|
2000-11-04 18:54:07 +00:00
|
|
|
pthread_setspecific (_cothread_key,ctx);
|
2000-01-30 09:03:00 +00:00
|
|
|
|
2000-11-04 18:54:07 +00:00
|
|
|
memset (ctx->threads,0,sizeof(ctx->threads));
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
ctx->threads[0] = (cothread_state *)malloc(sizeof(cothread_state));
|
|
|
|
ctx->threads[0]->ctx = ctx;
|
|
|
|
ctx->threads[0]->threadnum = 0;
|
|
|
|
ctx->threads[0]->func = NULL;
|
|
|
|
ctx->threads[0]->argc = 0;
|
|
|
|
ctx->threads[0]->argv = NULL;
|
|
|
|
ctx->threads[0]->flags = COTHREAD_STARTED;
|
2000-09-07 20:35:15 +00:00
|
|
|
ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
|
2000-01-30 09:03:00 +00:00
|
|
|
ctx->threads[0]->pc = 0;
|
|
|
|
|
2000-12-27 03:13:20 +00:00
|
|
|
DEBUG("0th thread is at %p, sp %p\n",ctx->threads[0], ctx->threads[0]->sp);
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
// we consider the initiating process to be cothread 0
|
|
|
|
ctx->nthreads = 1;
|
|
|
|
ctx->current = 0;
|
2000-11-06 00:15:51 +00:00
|
|
|
ctx->data = g_hash_table_new(g_str_hash, g_str_equal);
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
2000-11-11 15:13:50 +00:00
|
|
|
/**
|
|
|
|
* cothread_main:
|
|
|
|
* @ctx: the cothread context
|
|
|
|
*
|
|
|
|
* Returns: the new cothread state
|
|
|
|
*/
|
2000-11-04 18:54:07 +00:00
|
|
|
cothread_state*
|
|
|
|
cothread_main(cothread_context *ctx)
|
|
|
|
{
|
2000-12-03 00:17:52 +00:00
|
|
|
DEBUG("returning %p, the 0th cothread\n",ctx->threads[0]);
|
2000-01-30 09:03:00 +00:00
|
|
|
return ctx->threads[0];
|
|
|
|
}
|
|
|
|
|
2000-11-04 18:54:07 +00:00
|
|
|
void
|
|
|
|
cothread_stub (void)
|
|
|
|
{
|
2000-01-30 09:03:00 +00:00
|
|
|
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
|
|
|
register cothread_state *thread = ctx->threads[ctx->current];
|
|
|
|
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG_ENTER("");
|
2000-01-30 09:03:00 +00:00
|
|
|
thread->flags |= COTHREAD_STARTED;
|
2000-09-07 20:35:15 +00:00
|
|
|
if (thread->func)
|
|
|
|
thread->func(thread->argc,thread->argv);
|
2000-01-30 09:03:00 +00:00
|
|
|
thread->flags &= ~COTHREAD_STARTED;
|
|
|
|
thread->pc = 0;
|
2000-09-22 23:35:14 +00:00
|
|
|
thread->sp = thread->top_sp;
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG_LEAVE("");
|
2000-12-03 00:17:52 +00:00
|
|
|
// printf("uh, yeah, we shouldn't be here, but we should deal anyway\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cothread_getcurrent:
|
|
|
|
*
|
|
|
|
* Returns: the current cothread id
|
|
|
|
*/
|
|
|
|
int cothread_getcurrent(void) {
|
|
|
|
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
|
|
|
if (!ctx) return -1;
|
|
|
|
return ctx->current;
|
2000-01-30 09:03:00 +00:00
|
|
|
}
|
|
|
|
|
2000-11-11 15:13:50 +00:00
|
|
|
/**
|
|
|
|
* cothread_set_data:
|
|
|
|
* @thread: the cothread state
|
|
|
|
* @key: a key for the data
|
|
|
|
* @data: the data
|
|
|
|
*
|
|
|
|
* adds data to a cothread
|
|
|
|
*/
|
2000-11-06 00:15:51 +00:00
|
|
|
void
|
|
|
|
cothread_set_data (cothread_state *thread,
|
|
|
|
gchar *key,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
|
|
|
|
|
|
|
g_hash_table_insert(ctx->data, key, data);
|
|
|
|
}
|
|
|
|
|
2000-11-11 15:13:50 +00:00
|
|
|
/**
|
|
|
|
* cothread_get_data:
|
|
|
|
* @thread: the cothread state
|
|
|
|
* @key: a key for the data
|
|
|
|
*
|
|
|
|
* get data from the cothread
|
|
|
|
*
|
|
|
|
* Returns: the data assiciated with the key
|
|
|
|
*/
|
2000-11-06 00:15:51 +00:00
|
|
|
gpointer
|
|
|
|
cothread_get_data (cothread_state *thread,
|
|
|
|
gchar *key)
|
|
|
|
{
|
|
|
|
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
|
|
|
|
|
|
|
return g_hash_table_lookup(ctx->data, key);
|
|
|
|
}
|
|
|
|
|
2000-11-11 15:13:50 +00:00
|
|
|
/**
|
|
|
|
* cothread_switch:
|
|
|
|
* @thread: the cothread state
|
|
|
|
*
|
|
|
|
* switches to the given cothread state
|
|
|
|
*/
|
2000-11-04 18:54:07 +00:00
|
|
|
void
|
|
|
|
cothread_switch (cothread_state *thread)
|
|
|
|
{
|
2000-01-30 09:03:00 +00:00
|
|
|
cothread_context *ctx;
|
|
|
|
cothread_state *current;
|
2000-09-16 10:58:23 +00:00
|
|
|
int enter;
|
2000-01-30 09:03:00 +00:00
|
|
|
|
2000-11-29 10:05:47 +00:00
|
|
|
#ifdef COTHREAD_PARANOID
|
|
|
|
if (thread == NULL) goto nothread;
|
|
|
|
#endif
|
2000-01-30 09:03:00 +00:00
|
|
|
ctx = thread->ctx;
|
2000-11-29 10:05:47 +00:00
|
|
|
#ifdef COTHREAD_PARANOID
|
|
|
|
if (ctx == NULL) goto nocontext;
|
|
|
|
#endif
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
current = ctx->threads[ctx->current];
|
2000-11-29 10:05:47 +00:00
|
|
|
#ifdef COTHREAD_PARANOID
|
|
|
|
if (current == NULL) goto nocurrent;
|
|
|
|
#endif
|
|
|
|
if (current == thread) goto selfswitch;
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
// find the number of the thread to switch to
|
|
|
|
ctx->current = thread->threadnum;
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG("about to switch to thread #%d\n",ctx->current);
|
2000-01-30 09:03:00 +00:00
|
|
|
|
|
|
|
/* save the current stack pointer, frame pointer, and pc */
|
2000-09-15 22:44:10 +00:00
|
|
|
GET_SP(current->sp);
|
2000-11-01 22:11:48 +00:00
|
|
|
enter = setjmp(current->jmp);
|
2000-09-16 10:58:23 +00:00
|
|
|
if (enter != 0) {
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG("enter thread #%d %d %p<->%p (%d)\n",current->threadnum, enter,
|
2000-09-22 23:35:14 +00:00
|
|
|
current->sp, current->top_sp, current->top_sp-current->sp);
|
2000-01-30 09:03:00 +00:00
|
|
|
return;
|
2000-09-16 10:58:23 +00:00
|
|
|
}
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG("exit thread #%d %d %p<->%p (%d)\n",current->threadnum, enter,
|
2000-09-22 23:35:14 +00:00
|
|
|
current->sp, current->top_sp, current->top_sp-current->sp);
|
2000-01-30 09:03:00 +00:00
|
|
|
enter = 1;
|
|
|
|
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG("set stack to %p\n", thread->sp);
|
2000-01-30 09:03:00 +00:00
|
|
|
/* restore stack pointer and other stuff of new cothread */
|
|
|
|
if (thread->flags & COTHREAD_STARTED) {
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG("in thread \n");
|
2000-09-15 22:44:10 +00:00
|
|
|
SET_SP(thread->sp);
|
2000-01-30 09:03:00 +00:00
|
|
|
// switch to it
|
2000-11-01 22:11:48 +00:00
|
|
|
longjmp(thread->jmp,1);
|
2000-01-30 09:03:00 +00:00
|
|
|
} else {
|
2000-09-21 00:57:09 +00:00
|
|
|
SETUP_STACK(thread->sp);
|
2000-09-16 10:58:23 +00:00
|
|
|
SET_SP(thread->sp);
|
2000-01-30 09:03:00 +00:00
|
|
|
// start it
|
2000-09-16 10:58:23 +00:00
|
|
|
cothread_stub();
|
Changes made to the DEBUG system. New header file gstdebug.h holds the stuff to keep it out of gst.h's hair. DEBUG ...
Original commit message from CVS:
Changes made to the DEBUG system. New header file gstdebug.h holds the
stuff to keep it out of gst.h's hair. DEBUG prints out the process id,
cothread id, source filename and line number. Two new macros DEBUG_ENTER
and DEBUG_LEAVE are used to show the entry and exit of a given function.
This eventually might be used to construct call trace graphs, even taking
cothreads into account. This would be quite useful in visualizing the
scheduling mechanism.
Minor changes to various debug messages.
Also sitting in gstdebug.h is a prototypical DEBUG_ENTER that's capable of
performing DEBUG_LEAVE automatically. It does this by utilizing a
little-known GCC extension that allows one to call a function with the
same parameters as the current function. The macro uses this to basically
call itself. A boolean is used to ensure that when it calls itself it
actually runs the body of the function. In the meantime it prints stuff
out before and after the real function, as well as constructing a
debugging string. This can be used eventually to provide call-wide data
on the DEBUG lines, instead of having to replicate data on each call to
DEBUG. More research is needed into how this would most cleanly be fit
into some other chunk of code, like GStreamer (I think of this DEBUG trick
as a separate project, sorta).
Unfortunately, the aforementioned DEBUG trick interacts quite poorly with
cothreads. Almost any time it's used in a function that has anything
remotely to do with a cothread context (as in, it runs in one), a segfault
results from the __builtin_apply call, which is the heart of the whole
thing. If someone who really knows assembly could analyze the resulting
code to see what's really going on, we might find a way to fix either the
macro or the cothreads (I'm thinking that there's something we missed in
constructing the cothreads themselves) so this works in all cases.
In the meantime, please insert both DEBUG_ENTER and DEBUG_LEAVE in your
functions. Be sure to put DEBUG_ENTER after your variable declarations
and before any functional code, not to put the function name in any DEBUG
strings (it's already there, trust me), and put a DEBUG_LEAVE if you care
enough.
Changes are going to happen in the way DEBUGs and other printouts occur,
so stay tuned.
2000-12-04 09:35:08 +00:00
|
|
|
DEBUG("exit thread \n");
|
2000-09-22 23:35:14 +00:00
|
|
|
ctx->current = 0;
|
2000-01-30 09:03:00 +00:00
|
|
|
}
|
2000-11-29 10:05:47 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
#ifdef COTHREAD_PARANOID
|
|
|
|
nothread:
|
|
|
|
g_print("cothread: there's no thread, strange...\n");
|
|
|
|
return;
|
|
|
|
nocontext:
|
|
|
|
g_print("cothread: there's no context, help!\n");
|
|
|
|
exit(2);
|
|
|
|
nocurrent:
|
|
|
|
g_print("cothread: there's no current thread, help!\n");
|
|
|
|
exit(2);
|
|
|
|
#endif /* COTHREAD_PARANOID */
|
|
|
|
selfswitch:
|
|
|
|
g_print("cothread: trying to switch to same thread, legal but not necessary\n");
|
|
|
|
return;
|
2000-01-30 09:03:00 +00:00
|
|
|
}
|