[Stackless-checkins] CVS: slpdev/src/2.3/dev/Stackless/core slp_transfer.c, 1.26, 1.27 stackless_impl.h, 1.94, 1.95 stacklesseval.c, 1.155, 1.156

Christian Tismer tismer at centera.de
Thu Jun 3 20:02:15 CEST 2004


Update of /home/cvs/slpdev/src/2.3/dev/Stackless/core
In directory centera.de:/tmp/cvs-serv17074/Stackless/core

Modified Files:
	slp_transfer.c stackless_impl.h stacklesseval.c 
Log Message:
hmm, all undone.
Seems to need just -O0

Index: slp_transfer.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.3/dev/Stackless/core/slp_transfer.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -C2 -d -r1.26 -r1.27
*** slp_transfer.c	3 Jun 2004 17:34:21 -0000	1.26
--- slp_transfer.c	3 Jun 2004 18:02:11 -0000	1.27
***************
*** 46,352 ****
  #include "platf/slp_platformselect.h"
  
- /* these functions must be here, too, to prevend inlining */
- 
- /******************************************************
- 
-   The C Stack
- 
-  ******************************************************/
- 
- static PyCStackObject *cstack_cache[CSTACK_SLOTS] = { NULL };
- static int cstack_cachecount = 0;
- 
- /* this function will get called by PyStacklessEval_Fini */
- void slp_cstack_cacheclear(void)
- {
- 	int i;
- 	PyCStackObject *stack;
- 
- 	for (i=0; i < CSTACK_SLOTS; i++) {
- 		while (cstack_cache[i] != NULL) {
- 			stack = cstack_cache[i];
- 			cstack_cache[i] = (PyCStackObject *) stack->startaddr;
- 			PyMem_Free(stack);
- 		}
- 	}
- 	cstack_cachecount = 0;
- }
- 
- static void
- cstack_dealloc(PyCStackObject *cst)
- {
- 	slp_cstack_chain = cst;
- 	SLP_CHAIN_REMOVE(PyCStackObject, &slp_cstack_chain, cst, next, 
- 			 prev);
- 	if (cst->ob_size >= CSTACK_SLOTS) {
- 		PyMem_Free(cst);
- 	}
- 	else {
- 		if (cstack_cachecount >= CSTACK_MAXCACHE)
- 		slp_cstack_cacheclear();
- 		cst->startaddr = (int *) cstack_cache[cst->ob_size];
- 		cstack_cache[cst->ob_size] = cst;
- 		++cstack_cachecount;
- 	}
- }
- 
- 
- /* slp_cstack_save/restore moved to slp_transfer */
- 
- static char cstack_doc[] =
- "A CStack object serves to save the stack slice which is involved\n\
- during a recursive Python call. It will also be used for pickling\n\
- of program state. This structure is highly platform dependant.\n\
- Note: For inspection, str() can dump it as a string.\
- ";
- 
- #if SIZEOF_VOIDP == SIZEOF_INT
- #define T_ADDR T_UINT
- #else
- #define T_ADDR T_ULONG
- #endif
- 
- 
- static PyMemberDef cstack_members[] = {
- 	{"size", T_INT, offsetof(PyCStackObject, ob_size), READONLY},
- 	{"next", T_OBJECT, offsetof(PyCStackObject, next), READONLY},
- 	{"prev", T_OBJECT, offsetof(PyCStackObject, prev), READONLY},
- 	{"task", T_OBJECT, offsetof(PyCStackObject, task), READONLY},
- 	{"startaddr", T_ADDR, offsetof(PyCStackObject, startaddr), READONLY},
- 	{0}
- };
- 
- /* simple string interface for inspection */
- 
- static PyObject *
- cstack_str(PyObject *o)
- {
- 	PyCStackObject *cst = (PyCStackObject*)o;
- 	return PyString_FromStringAndSize((char*)&cst->stack,
- 	    cst->ob_size*sizeof(cst->stack[0]));
- }
- 
- PyTypeObject PyCStack_Type = {
- 	PyObject_HEAD_INIT(&PyType_Type)
- 	0,
- 	"stackless.cstack",
- 	sizeof(PyCStackObject),
- 	sizeof(PyObject *),
- 	(destructor)cstack_dealloc,	/* tp_dealloc */
- 	0,				/* tp_print */
- 	0,				/* tp_getattr */
- 	0,				/* tp_setattr */
- 	0,				/* tp_compare */
- 	0,				/* tp_repr */
- 	0,				/* tp_as_number */
- 	0,				/* tp_as_sequence */
- 	0,				/* tp_as_mapping */
- 	0,				/* tp_hash */
- 	0,				/* tp_call */
- 	(reprfunc)cstack_str,		/* tp_str */
- 	PyObject_GenericGetAttr,	/* tp_getattro */
- 	PyObject_GenericSetAttr,	/* tp_setattro */
- 	0,				/* tp_as_buffer */
- 	Py_TPFLAGS_DEFAULT,		/* tp_flags */
- 	cstack_doc,			/* tp_doc */
- 	0,				/* tp_traverse */
- 	0,				/* tp_clear */
- 	0,				/* tp_richcompare */
- 	0,				/* tp_weaklistoffset */
- 	0,				/* tp_iter */
- 	0,				/* tp_iternext */
- 	0,				/* tp_methods */
- 	cstack_members,			/* tp_members */
- };
- 
- /* 
-  * slp_eval_frame moved to slp_transfer.c
-  * to avoid optimization in gcc 3.3.2
-  */
- 
- void slp_kill_tasks_with_stacks(PyThreadState *ts)
- {
- 	int count = 0;
- 
- 	while (1) {
- 		PyCStackObject *csfirst = slp_cstack_chain, *cs;
- 		PyTaskletObject *t;
- 
- 		if (csfirst == NULL)
- 			break;
- 		for (cs = csfirst; ; cs = cs->next) {
- 			if (count && cs == csfirst) {
- 				/* nothing found */
- 				return;
- 			}
- 			++count;
- 			if (cs->task == NULL)
- 				continue;
- 			if (ts != NULL && cs->tstate != ts)
- 				continue;
- 			break;
- 		} 
- 		count = 0;
- 		t = cs->task;
- 		Py_INCREF(t);
- 
- 		PyTasklet_Kill(t);
- 		PyErr_Clear();
- 
- 		if (t->f.frame == 0) {
- 			/* ensure a valid tstate */
- 			t->cstate->tstate = slp_initial_tstate;
- 		}
- 		Py_DECREF(t);
- 	}
- }
- 
- PyCStackObject *
- slp_cstack_new(PyCStackObject **cst, int *stackref, PyTaskletObject *task)
- {
- 	PyThreadState *ts = PyThreadState_GET();
- 	int *stackbase = ts->st.cstack_base;
- 	int size = stackbase - stackref;
- 
- 	if (size < 0)
- 		RUNTIME_ERROR("negative stack size", NULL);
- 	if (*cst && (*cst)->ob_size == size && (*cst)->ob_refcnt == 1) {
- 		/* reuse it */
- 		(*cst)->task = task;
- 		return *cst;
- 	}
- 	    
- 	if (*cst != NULL) {
- 		if ((*cst)->task == task)
- 			(*cst)->task = NULL;
- 		Py_DECREF(*cst);
- 	}
- 	if (size < CSTACK_SLOTS && ((*cst) = cstack_cache[size])) {
- 		/* take stack from cache */
- 		cstack_cache[size] = (PyCStackObject *) (*cst)->startaddr;
- 		--cstack_cachecount;
- 	}
- 	else {
- 		/* PyObject_NewVar is inlined */
- 		*cst = (PyCStackObject *)
- 		       PyObject_MALLOC(sizeof(PyCStackObject) + 
- 				       (size-1) * sizeof(int*));
- 		if (*cst == NULL) return NULL;
- 	}
- 	(void) PyObject_INIT_VAR(*cst, &PyCStack_Type, size);
- 
- 	(*cst)->startaddr = stackbase;
- 	(*cst)->next = (*cst)->prev = NULL;
- 	SLP_CHAIN_INSERT(PyCStackObject, &slp_cstack_chain, *cst, next, prev);
- 	(*cst)->serial = ts->st.serial;
- 	(*cst)->task = task;
- 	(*cst)->tstate = ts;
- 	(*cst)->nesting_level = ts->st.nesting_level;
- 	return *cst;
- }
- 
- int
- slp_cstack_save(PyCStackObject *cstprev)
- {
- 	int stsizeb = (cstprev)->ob_size * sizeof(int*);
- 
- 	memcpy((cstprev)->stack, (cstprev)->startaddr - 
- 				 (cstprev)->ob_size, stsizeb);
- 	return stsizeb;
- }
- 
- void
- slp_cstack_restore(PyCStackObject *cst)
- {
- 	cst->tstate->st.nesting_level = cst->nesting_level;
- 	/* mark task as no longer responsible for cstack instance */
- 	cst->task = NULL;
- 	memcpy(cst->startaddr - cst->ob_size, &cst->stack,
- 	       (cst->ob_size) * sizeof(int*));
- }
- 
- static int
- make_initial_stub(void)
- {
- 	PyThreadState *ts = PyThreadState_GET();
- 
- 	if (ts->st.initial_stub != NULL) {
- 		Py_DECREF(ts->st.initial_stub);
- 		ts->st.initial_stub = NULL;
- 	}
- 	ts->st.serial_last_jump = ++ts->st.serial;
- 	if (slp_transfer(&ts->st.initial_stub, NULL, NULL)) return -1;
- 	ts->st.initial_stub->serial = ts->st.serial;
- 	/* 
- 	 * from here, we always arrive with a compatible cstack
- 	 * that also can be used by main, if it is running
- 	 * in soft-switching mode.
- 	 * To insure that, it was necessary to re-create the
- 	 * initial stub for *every* run of a new main.
- 	 * This will vanish with greenlet-like stack management.
- 	 */
- 
- 	return 0;
- }
- 
- static PyObject *
- climb_stack_and_eval_frame(PyFrameObject *f)
- {
- 	/* 
- 	 * a similar case to climb_stack_and_transfer,
- 	 * but here we need to incorporate a gap in the
- 	 * stack into main and keep this gap on the stack.
- 	 * This way, initial_stub is always valid to be
- 	 * used to return to the main c stack.
- 	 */
- 	PyThreadState *ts = PyThreadState_GET();
- 	int probe;
- 	int needed = &probe - ts->st.cstack_base;
- 	/* in rare cases, the need might have vanished due to the recursion */
- 	int * goobledigoobs;
- 
- 	if (needed > 0) {
- 		goobledigoobs = alloca(needed * sizeof(int));
- 		if (goobledigoobs == NULL)
- 			return NULL;
- 	}
- 	return slp_eval_frame(f);
- }
- 
- PyObject *
- slp_eval_frame(PyFrameObject *f)
- {
- 	PyThreadState *ts = PyThreadState_GET();
- 	PyFrameObject *fprev = f->f_back;
- 	int * stackref;
- 
- 	if (fprev == NULL && ts->st.main == NULL) {
- 		/* this is the initial frame, so mark the stack base */
- 
- 		/* 
- 		 * careful, this caused me a major headache.
- 		 * it is *not* sufficient to just check for fprev == NULL.
- 		 * Reason: (observed with wxPython):
- 		 * A toplevel frame is run as a tasklet. When its frame
- 		 * is deallocated (in tasklet_end), a Python object
- 		 * with a __del__ method is destroyed. This __del__
- 		 * will run as a toplevel frame, with f_back == NULL!
- 		 */
- 
- 		stackref = STACK_REFPLUS + (int*) &f;
- 		if (ts->st.cstack_base == NULL)
- 			ts->st.cstack_base = stackref-CSTACK_GOODGAP;
- 		if (stackref > ts->st.cstack_base)
- 			return climb_stack_and_eval_frame(f);
- 
- 		ts->frame = f;
- 		if (make_initial_stub())
- 			return NULL;
- 		return slp_run_tasklet();
- 	}
- 	Py_INCREF(Py_None);
- 	return slp_frame_dispatch(f, fprev, Py_None);
- }
- 
  static int
  climb_stack_and_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
--- 46,49 ----

Index: stackless_impl.h
===================================================================
RCS file: /home/cvs/slpdev/src/2.3/dev/Stackless/core/stackless_impl.h,v
retrieving revision 1.94
retrieving revision 1.95
diff -C2 -d -r1.94 -r1.95
*** stackless_impl.h	3 Jun 2004 17:34:21 -0000	1.94
--- stackless_impl.h	3 Jun 2004 18:02:11 -0000	1.95
***************
*** 43,47 ****
  PyAPI_FUNC(int) slp_cstack_save(PyCStackObject *cstprev);
  PyAPI_FUNC(void) slp_cstack_restore(PyCStackObject *cst);
- PyAPI_FUNC(void) slp_cstack_cacheclear(void);
  
  PyAPI_FUNC(int) slp_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
--- 43,46 ----

Index: stacklesseval.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.3/dev/Stackless/core/stacklesseval.c,v
retrieving revision 1.155
retrieving revision 1.156
diff -C2 -d -r1.155 -r1.156
*** stacklesseval.c	3 Jun 2004 17:34:21 -0000	1.155
--- stacklesseval.c	3 Jun 2004 18:02:12 -0000	1.156
***************
*** 37,40 ****
--- 37,337 ----
  
  
+ /******************************************************
+ 
+   The C Stack
+ 
+  ******************************************************/
+ 
+ static PyCStackObject *cstack_cache[CSTACK_SLOTS] = { NULL };
+ static int cstack_cachecount = 0;
+ 
+ /* this function will get called by PyStacklessEval_Fini */
+ static void slp_cstack_cacheclear(void)
+ {
+ 	int i;
+ 	PyCStackObject *stack;
+ 
+ 	for (i=0; i < CSTACK_SLOTS; i++) {
+ 		while (cstack_cache[i] != NULL) {
+ 			stack = cstack_cache[i];
+ 			cstack_cache[i] = (PyCStackObject *) stack->startaddr;
+ 			PyMem_Free(stack);
+ 		}
+ 	}
+ 	cstack_cachecount = 0;
+ }
+ 
+ static void
+ cstack_dealloc(PyCStackObject *cst)
+ {
+ 	slp_cstack_chain = cst;
+ 	SLP_CHAIN_REMOVE(PyCStackObject, &slp_cstack_chain, cst, next, 
+ 			 prev);
+ 	if (cst->ob_size >= CSTACK_SLOTS) {
+ 		PyMem_Free(cst);
+ 	}
+ 	else {
+ 		if (cstack_cachecount >= CSTACK_MAXCACHE)
+ 		slp_cstack_cacheclear();
+ 		cst->startaddr = (int *) cstack_cache[cst->ob_size];
+ 		cstack_cache[cst->ob_size] = cst;
+ 		++cstack_cachecount;
+ 	}
+ }
+ 
+ 
+ PyCStackObject *
+ slp_cstack_new(PyCStackObject **cst, int *stackref, PyTaskletObject *task)
+ {
+ 	PyThreadState *ts = PyThreadState_GET();
+ 	int *stackbase = ts->st.cstack_base;
+ 	int size = stackbase - stackref;
+ 
+ 	if (size < 0)
+ 		RUNTIME_ERROR("negative stack size", NULL);
+ 	if (*cst && (*cst)->ob_size == size && (*cst)->ob_refcnt == 1) {
+ 		/* reuse it */
+ 		(*cst)->task = task;
+ 		return *cst;
+ 	}
+ 	    
+ 	if (*cst != NULL) {
+ 		if ((*cst)->task == task)
+ 			(*cst)->task = NULL;
+ 		Py_DECREF(*cst);
+ 	}
+ 	if (size < CSTACK_SLOTS && ((*cst) = cstack_cache[size])) {
+ 		/* take stack from cache */
+ 		cstack_cache[size] = (PyCStackObject *) (*cst)->startaddr;
+ 		--cstack_cachecount;
+ 	}
+ 	else {
+ 		/* PyObject_NewVar is inlined */
+ 		*cst = (PyCStackObject *)
+ 		       PyObject_MALLOC(sizeof(PyCStackObject) + 
+ 				       (size-1) * sizeof(int*));
+ 		if (*cst == NULL) return NULL;
+ 	}
+ 	(void) PyObject_INIT_VAR(*cst, &PyCStack_Type, size);
+ 
+ 	(*cst)->startaddr = stackbase;
+ 	(*cst)->next = (*cst)->prev = NULL;
+ 	SLP_CHAIN_INSERT(PyCStackObject, &slp_cstack_chain, *cst, next, prev);
+ 	(*cst)->serial = ts->st.serial;
+ 	(*cst)->task = task;
+ 	(*cst)->tstate = ts;
+ 	(*cst)->nesting_level = ts->st.nesting_level;
+ 	return *cst;
+ }
+ 
+ int
+ slp_cstack_save(PyCStackObject *cstprev)
+ {
+ 	int stsizeb = (cstprev)->ob_size * sizeof(int*);
+ 
+ 	memcpy((cstprev)->stack, (cstprev)->startaddr - 
+ 				 (cstprev)->ob_size, stsizeb);
+ 	return stsizeb;
+ }
+ 
+ void
+ slp_cstack_restore(PyCStackObject *cst)
+ {
+ 	cst->tstate->st.nesting_level = cst->nesting_level;
+ 	/* mark task as no longer responsible for cstack instance */
+ 	cst->task = NULL;
+ 	memcpy(cst->startaddr - cst->ob_size, &cst->stack,
+ 	       (cst->ob_size) * sizeof(int*));
+ }
+ 
+ 
+ static char cstack_doc[] =
+ "A CStack object serves to save the stack slice which is involved\n\
+ during a recursive Python call. It will also be used for pickling\n\
+ of program state. This structure is highly platform dependant.\n\
+ Note: For inspection, str() can dump it as a string.\
+ ";
+ 
+ #if SIZEOF_VOIDP == SIZEOF_INT
+ #define T_ADDR T_UINT
+ #else
+ #define T_ADDR T_ULONG
+ #endif
+ 
+ 
+ static PyMemberDef cstack_members[] = {
+ 	{"size", T_INT, offsetof(PyCStackObject, ob_size), READONLY},
+ 	{"next", T_OBJECT, offsetof(PyCStackObject, next), READONLY},
+ 	{"prev", T_OBJECT, offsetof(PyCStackObject, prev), READONLY},
+ 	{"task", T_OBJECT, offsetof(PyCStackObject, task), READONLY},
+ 	{"startaddr", T_ADDR, offsetof(PyCStackObject, startaddr), READONLY},
+ 	{0}
+ };
+ 
+ /* simple string interface for inspection */
+ 
+ static PyObject *
+ cstack_str(PyObject *o)
+ {
+ 	PyCStackObject *cst = (PyCStackObject*)o;
+ 	return PyString_FromStringAndSize((char*)&cst->stack,
+ 	    cst->ob_size*sizeof(cst->stack[0]));
+ }
+ 
+ PyTypeObject PyCStack_Type = {
+ 	PyObject_HEAD_INIT(&PyType_Type)
+ 	0,
+ 	"stackless.cstack",
+ 	sizeof(PyCStackObject),
+ 	sizeof(PyObject *),
+ 	(destructor)cstack_dealloc,	/* tp_dealloc */
+ 	0,				/* tp_print */
+ 	0,				/* tp_getattr */
+ 	0,				/* tp_setattr */
+ 	0,				/* tp_compare */
+ 	0,				/* tp_repr */
+ 	0,				/* tp_as_number */
+ 	0,				/* tp_as_sequence */
+ 	0,				/* tp_as_mapping */
+ 	0,				/* tp_hash */
+ 	0,				/* tp_call */
+ 	(reprfunc)cstack_str,		/* tp_str */
+ 	PyObject_GenericGetAttr,	/* tp_getattro */
+ 	PyObject_GenericSetAttr,	/* tp_setattro */
+ 	0,				/* tp_as_buffer */
+ 	Py_TPFLAGS_DEFAULT,		/* tp_flags */
+ 	cstack_doc,			/* tp_doc */
+ 	0,				/* tp_traverse */
+ 	0,				/* tp_clear */
+ 	0,				/* tp_richcompare */
+ 	0,				/* tp_weaklistoffset */
+ 	0,				/* tp_iter */
+ 	0,				/* tp_iternext */
+ 	0,				/* tp_methods */
+ 	cstack_members,			/* tp_members */
+ };
+ 
+ 
+ static int
+ make_initial_stub(void)
+ {
+ 	PyThreadState *ts = PyThreadState_GET();
+ 
+ 	if (ts->st.initial_stub != NULL) {
+ 		Py_DECREF(ts->st.initial_stub);
+ 		ts->st.initial_stub = NULL;
+ 	}
+ 	ts->st.serial_last_jump = ++ts->st.serial;
+ 	if (slp_transfer(&ts->st.initial_stub, NULL, NULL)) return -1;
+ 	ts->st.initial_stub->serial = ts->st.serial;
+ 	/* 
+ 	 * from here, we always arrive with a compatible cstack
+ 	 * that also can be used by main, if it is running
+ 	 * in soft-switching mode.
+ 	 * To insure that, it was necessary to re-create the
+ 	 * initial stub for *every* run of a new main.
+ 	 * This will vanish with greenlet-like stack management.
+ 	 */
+ 
+ 	return 0;
+ }
+ 
+ static PyObject *
+ climb_stack_and_eval_frame(PyFrameObject *f)
+ {
+ 	/* 
+ 	 * a similar case to climb_stack_and_transfer,
+ 	 * but here we need to incorporate a gap in the
+ 	 * stack into main and keep this gap on the stack.
+ 	 * This way, initial_stub is always valid to be
+ 	 * used to return to the main c stack.
+ 	 */
+ 	PyThreadState *ts = PyThreadState_GET();
+ 	int probe;
+ 	int needed = &probe - ts->st.cstack_base;
+ 	/* in rare cases, the need might have vanished due to the recursion */
+ 	int * goobledigoobs;
+ 
+ 	if (needed > 0) {
+ 		goobledigoobs = alloca(needed * sizeof(int));
+ 		if (goobledigoobs == NULL)
+ 			return NULL;
+ 	}
+ 	return slp_eval_frame(f);
+ }
+ 
+ 
+ PyObject *
+ slp_eval_frame(PyFrameObject *f)
+ {
+ 	PyThreadState *ts = PyThreadState_GET();
+ 	PyFrameObject *fprev = f->f_back;
+ 	int * stackref;
+ 
+ 	if (fprev == NULL && ts->st.main == NULL) {
+ 		/* this is the initial frame, so mark the stack base */
+ 
+ 		/* 
+ 		 * careful, this caused me a major headache.
+ 		 * it is *not* sufficient to just check for fprev == NULL.
+ 		 * Reason: (observed with wxPython):
+ 		 * A toplevel frame is run as a tasklet. When its frame
+ 		 * is deallocated (in tasklet_end), a Python object
+ 		 * with a __del__ method is destroyed. This __del__
+ 		 * will run as a toplevel frame, with f_back == NULL!
+ 		 */
+ 
+ 		stackref = STACK_REFPLUS + (int*) &f;
+ 		if (ts->st.cstack_base == NULL)
+ 			ts->st.cstack_base = stackref-CSTACK_GOODGAP;
+ 		if (stackref > ts->st.cstack_base)
+ 			return climb_stack_and_eval_frame(f);
+ 
+ 		ts->frame = f;
+ 		if (make_initial_stub())
+ 			return NULL;
+ 		return slp_run_tasklet();
+ 	}
+ 	Py_INCREF(Py_None);
+ 	return slp_frame_dispatch(f, fprev, Py_None);
+ }
+ 
+ void slp_kill_tasks_with_stacks(PyThreadState *ts)
+ {
+ 	int count = 0;
+ 
+ 	while (1) {
+ 		PyCStackObject *csfirst = slp_cstack_chain, *cs;
+ 		PyTaskletObject *t;
+ 
+ 		if (csfirst == NULL)
+ 			break;
+ 		for (cs = csfirst; ; cs = cs->next) {
+ 			if (count && cs == csfirst) {
+ 				/* nothing found */
+ 				return;
+ 			}
+ 			++count;
+ 			if (cs->task == NULL)
+ 				continue;
+ 			if (ts != NULL && cs->tstate != ts)
+ 				continue;
+ 			break;
+ 		} 
+ 		count = 0;
+ 		t = cs->task;
+ 		Py_INCREF(t);
+ 
+ 		PyTasklet_Kill(t);
+ 		PyErr_Clear();
+ 
+ 		if (t->f.frame == 0) {
+ 			/* ensure a valid tstate */
+ 			t->cstate->tstate = slp_initial_tstate;
+ 		}
+ 		Py_DECREF(t);
+ 	}
+ }
+ 
  void PyStackless_kill_tasks_with_stacks(int allthreads)
  {


_______________________________________________
Stackless-checkins mailing list
Stackless-checkins at stackless.com
http://www.stackless.com/mailman/listinfo/stackless-checkins



More information about the Stackless-checkins mailing list