Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9061
Modified Files: Tag: desiredata kernel.c Log Message: stack trace is recorded as execution goes. It barely even slows down pd.
Index: kernel.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/Attic/kernel.c,v retrieving revision 1.1.2.53 retrieving revision 1.1.2.54 diff -C2 -d -r1.1.2.53 -r1.1.2.54 *** kernel.c 14 Jul 2007 22:47:11 -0000 1.1.2.53 --- kernel.c 15 Jul 2007 03:43:32 -0000 1.1.2.54 *************** *** 469,498 **** static void stackerror(t_pd *x) {pd_error(x,"stack overflow");}
! /* T.Grill - define for a modified, more portable method to detect stack overflows */ ! /* tb: threadsafe stack overflow detection */ ! #define ENTER STACK_INC; if(stackcount >= STACKITER) {stackerror(x); LEAVE; return;} ! #define LEAVE STACK_DEC; ! #ifdef ATOMIC ! #include "m_atomic.h" ! #define STACK_INC int* scp = &stackcount; ATOMIC_INC(scp) ! #define STACK_DEC ATOMIC_DEC(scp) ! #else /* ATOMIC */ ! #define STACK_INC ++stackcount ! #define STACK_DEC --stackcount ! #endif /* ATOMIC */ ! /* tb: } */
! /* T.Grill - count iterations rather than watch the stack pointer */ ! static int stackcount = 0; /* iteration counter */ ! #define STACKITER 1000 /* maximum iterations allowed */
/* matju's 2007.07.14 inlet-based stack check needs to be implemented in: pd_bang pd_float pd_pointer pd_symbol pd_string pd_list pd_typedmess */ ! void pd_bang(t_pd *x) {ENTER; x->_class->bangmethod(x); LEAVE;} ! void pd_float(t_pd *x, t_float f) {ENTER; x->_class->floatmethod(x,f); LEAVE;} ! void pd_pointer(t_pd *x, t_gpointer *gp) {ENTER; x->_class->pointermethod(x,gp); LEAVE;} ! void pd_symbol(t_pd *x, t_symbol *s) {ENTER; x->_class->symbolmethod(x,s); LEAVE;} ! /* void pd_string(t_pd *x, const char *s){ENTER; x->_class->stringmethod(x,s); LEAVE;} future use */ ! void pd_list(t_pd *x, t_symbol *s, int ac, t_atom *av) {ENTER; x->_class->listmethod(x,&s_list,ac,av); LEAVE;}
/* this file handles Max-style patchable objects, i.e., objects which --- 469,498 ---- static void stackerror(t_pd *x) {pd_error(x,"stack overflow");}
! #define STACKSIZE 1024 ! struct t_call { ! t_pd *self; /* receiver */ ! t_symbol *s; /* selector */ ! /* insert temporary profiling variables here */ ! };
! /* to enable multithreading, make those variables "thread-local". this means that they have to go in ! a thread-specific place instead of plain global. do not ever use tim's atomic counters for this, ! as they count all threads together as if they're one, and they're especially incompatible with ! use of the desiredata-specific stack[] variable. */ ! t_call pd_stack[STACKSIZE]; ! int pd_stackn = 0; /* iteration counter */ ! ! #define ENTER(SELECTOR) if(pd_stackn >= STACKSIZE) {stackerror(x); LEAVE; return;} \ ! pd_stack[pd_stackn].self = x; pd_stack[pd_stackn].s = SELECTOR; pd_stackn++; ! #define LEAVE pd_stackn--;
/* matju's 2007.07.14 inlet-based stack check needs to be implemented in: pd_bang pd_float pd_pointer pd_symbol pd_string pd_list pd_typedmess */ ! void pd_bang(t_pd *x) {ENTER(&s_bang); x->_class->bangmethod(x); LEAVE;} ! void pd_float(t_pd *x, t_float f) {ENTER(&s_float); x->_class->floatmethod(x,f); LEAVE;} ! void pd_pointer(t_pd *x, t_gpointer *gp) {ENTER(&s_pointer); x->_class->pointermethod(x,gp); LEAVE;} ! void pd_symbol(t_pd *x, t_symbol *s) {ENTER(&s_symbol); x->_class->symbolmethod(x,s); LEAVE;} ! /* void pd_string(t_pd *x, const char *s){ENTER(&s_symbol); x->_class->stringmethod(x,s); LEAVE;} future use */ ! void pd_list(t_pd *x, t_symbol *s, int ac, t_atom *av) {ENTER(s); x->_class->listmethod(x,&s_list,ac,av); LEAVE;}
/* this file handles Max-style patchable objects, i.e., objects which *************** *** 1374,1377 **** --- 1374,1378 ---- }
+ /* !@#$ this has to be changed to fit with gensym2 changes */ t_symbol s_pointer = {"pointer", 0, 0}; t_symbol s_float = {"float", 0, 0}; *************** *** 1413,1419 **** void pd_typedmess_2(t_pd *x, t_symbol *s, int argc, t_atom *argv) { t_class *c = x->_class; - t_methodentry *m; t_atomtype *wp, wanttype; ! t_int ai[MAXPDARG+1], *ap = ai; t_floatarg ad[MAXPDARG+1], *dp = ad; int narg = 0; --- 1414,1419 ---- void pd_typedmess_2(t_pd *x, t_symbol *s, int argc, t_atom *argv) { t_class *c = x->_class; t_atomtype *wp, wanttype; ! t_int ai[MAXPDARG+1], *ap = ai; t_floatarg ad[MAXPDARG+1], *dp = ad; int narg = 0; *************** *** 1423,1427 **** if (!argc) c->floatmethod(x, 0.); else if (argv->a_type == A_FLOAT) c->floatmethod(x, argv->a_float); ! else goto badarg; return; } --- 1423,1427 ---- if (!argc) c->floatmethod(x, 0.); else if (argv->a_type == A_FLOAT) c->floatmethod(x, argv->a_float); ! else pd_error(x, "expected one float, in class [%s]", c->name->name); return; } *************** *** 1429,1433 **** if (s == &s_list) {c->listmethod(x,s,argc,argv); return;} if (s == &s_symbol) {c->symbolmethod(x, argc && argv->a_type==A_SYMBOL ? argv->a_symbol : &s_); return;} ! m = c->methods; for (int i = c->nmethod; i--; m++) if (m->me_name == s) { wp = m->me_arg; --- 1429,1433 ---- if (s == &s_list) {c->listmethod(x,s,argc,argv); return;} if (s == &s_symbol) {c->symbolmethod(x, argc && argv->a_type==A_SYMBOL ? argv->a_symbol : &s_); return;} ! t_methodentry *m = c->methods; for (int i = c->nmethod; i--; m++) if (m->me_name == s) { wp = m->me_arg; *************** *** 1443,1481 **** case A_POINTER: if (!argc) goto badarg; ! else { ! if (argv->a_type!=A_POINTER) goto badarg; ! *ap = t_int(argv->a_gpointer); ! argc--; ! argv++; ! } narg++; ap++; break; ! case A_FLOAT: ! if (!argc) goto badarg; ! case A_DEFFLOAT: ! if (!argc) *dp = 0; else { if (argv->a_type!=A_FLOAT) goto badarg; *dp = argv->a_float; ! argc--; ! argv++; } dp++; break; ! case A_SYMBOL: ! if (!argc) goto badarg; ! case A_DEFSYM: ! if (!argc) *ap = t_int(&s_); else { ! if (argv->a_type == A_SYMBOL) *ap = (t_int)(argv->a_symbol); /* if it's an unfilled "dollar" argument it appears as zero here; cheat and bash it to the null symbol. Unfortunately, this lets real zeros pass as symbols too, which seems wrong... */ ! else if (x == &pd_objectmaker && argv->a_type == A_FLOAT ! && argv->a_float == 0) *ap = t_int(&s_); else goto badarg; ! argc--; ! argv++; } narg++; --- 1443,1471 ---- case A_POINTER: if (!argc) goto badarg; ! if (argv->a_type!=A_POINTER) goto badarg; ! *ap = t_int(argv->a_gpointer); ! argc--; argv++; narg++; ap++; break; ! case A_FLOAT: if (!argc) goto badarg; ! case A_DEFFLOAT: if (!argc) *dp = 0; else { if (argv->a_type!=A_FLOAT) goto badarg; *dp = argv->a_float; ! argc--; argv++; } dp++; break; ! case A_SYMBOL: if (!argc) goto badarg; ! case A_DEFSYM: if (!argc) *ap = t_int(&s_); else { ! if (argv->a_type == A_SYMBOL) *ap = t_int(argv->a_symbol); /* if it's an unfilled "dollar" argument it appears as zero here; cheat and bash it to the null symbol. Unfortunately, this lets real zeros pass as symbols too, which seems wrong... */ ! else if (x == &pd_objectmaker && argv->a_type == A_FLOAT && argv->a_float == 0) *ap = t_int(&s_); else goto badarg; ! argc--; argv++; } narg++; *************** *** 1506,1510 ****
void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) { ! ENTER; pd_typedmess_2(x,s,argc,argv); LEAVE; }
--- 1496,1500 ----
void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) { ! ENTER(s); pd_typedmess_2(x,s,argc,argv); LEAVE; }