Hi all,

Currently I'm working on a stackless python 2.6.2 implementation on a single 
threaded embedded device.  The application running inserts and removes tasklets 
asynchronously based on hardware callbacks.  I am trying to write a scheduling 
loop in C that will reinsert tasklets to the run queue and call 
stackless.run(100).  The problem that I am running into is that _Py_Ticker 
value never gets reset. This causes every single call to stackless.run(100) 
after the first call will hit the stackless_interupt_call in ceval.c line 2995, 
and no more code gets executed.  My scheduling routine is attached in the file 
my_scheduler.c in the method scheduler_run().  I have been using the 
test_scheduler.py script to test my module.  I also wrote a test script called 
test_stackless that mimics the behavior that I'm trying to accomplish.  In 
addition, I also verified that I got the same result when I moved the test() 
method to its own module.  I am missing a step in setting up the call to 
stackless.schedule() in my c code?
#ifndef _LINKEDLIST_H_
#define _LINKEDLIST_H_

typedef struct __list_node
{
	void* Data;
	struct __list_node* Next;
	
} ListNode;


int LinkedListEpoch(void);
ListNode *list_create(void);
int list_add(ListNode *head, void* listEntry);
int list_remove(ListNode *head, void* listEntry);

#endif


#include "Python.h"
#include "stackless_api.h"
#include "LinkedList.h"

PyObject *my_scheduler_error;

ListNode *ReinsertPendingPointer = NULL;

ListNode *list_create(void)
{
	ListNode* node = NULL;
	node = malloc(sizeof(ListNode));
	if(node == NULL)
	{
		errno = ENOMEM;
		return -1;
	}
	node->Data = NULL;
	node->Next = NULL;
	return node;	
}

int list_add(ListNode *head, void* listEntry)
{
	ListNode* node;
	
	if(head == NULL)
	{
		errno = EINVAL;
		return -1;
	}
	
	node = head;
	while(node->Next != NULL)
	{
		node = node->Next;
	}
	
	// Create and insert the new node into the linked-list
	node->Next = malloc(sizeof(ListNode));
	if(node->Next == NULL)
	{
		errno = ENOMEM;
		return -1;
	}

	node = node->Next;
	node->Data = listEntry;	
	node->Next = NULL;

	/*===== Add the pending structure to the list -----*/

	return 0;
}

int list_remove(ListNode *head, void* listEntry)
{
	ListNode* prev;
	ListNode* current;
	
	prev = head;
	current = prev->Next;
	
	while(current != NULL && current->Data != listEntry)
	{
		prev = current;
		current = current->Next;
	}
	
	if(current == NULL || current->Data != listEntry)
	{
		return -1;
	}
	
	prev->Next = current->Next;
	free(current);
	
	return 0;
}

void ReinsertPendingScripts(void)
{
	ListNode *prevNode = NULL;
	ListNode *currentNode = NULL;
	PyTaskletObject *tasklet = NULL;
	if(ReinsertPendingPointer != NULL)
	{
		prevNode = ReinsertPendingPointer; 
		currentNode = prevNode->Next; 
		while(currentNode != NULL)
		{
			tasklet = (PyTaskletObject *)currentNode->Data;
			slp_current_insert(tasklet); 
		 	Py_DECREF(tasklet);	

			list_remove(ReinsertPendingPointer, tasklet);
			currentNode->Data = NULL;
			currentNode = prevNode;
			prevNode = currentNode;
			currentNode = currentNode->Next;
		}
	}
	else
	{
		ReinsertPendingPointer = list_create();
	}
}


static PyObject * scheduler_run(PyObject *self, PyObject *args)
{
	int retval = -1;
	PyObject *RetTasklet = NULL;
	PyObject *module_dict=NULL;


	/* Declarations for Stackless Module */
	PyObject *stacklessmod=NULL;
	PyObject *sm_dict=NULL;
	PyObject *sm_runcall=NULL;

	do
	{
		/*----- Calls to get the stackless.run(100) call in the namespace -----*/ 
		stacklessmod = PyImport_AddModule("stackless");
		if(stacklessmod == NULL)
		{
			break;
		}

		sm_dict = PyModule_GetDict(stacklessmod);
		if(sm_dict == NULL)
		{
			break;
		}

		sm_runcall = PyDict_GetItemString(sm_dict, "run");
		if(sm_runcall == NULL)
		{
			break;
		}

		

		while(1)
		{

			ReinsertPendingScripts();

			// run next tasklet for 100

			RetTasklet = PyEval_CallFunction(sm_runcall, "(i)", 100);
			if(RetTasklet == NULL)
			{
				PyErr_Print();
			}
			else if(RetTasklet != Py_None)
			{
				Py_INCREF(RetTasklet);
				list_add(ReinsertPendingPointer, RetTasklet);
			}
		}

		/* This shouldn't happen, but need to handle the case */
		Py_XDECREF(sm_runcall);
		Py_XDECREF(sm_dict);
		Py_XDECREF(stacklessmod);

		
	}while(0);
	
}



static PyMethodDef my_scheduler_methods[] = {
	{"run",scheduler_run,METH_VARARGS
		,"Run my scheduler"},
	{NULL,NULL,0,NULL}
};

PyMODINIT_FUNC
initmy_scheduler(void)
{
	PyObject *m;
	m = Py_InitModule("my_scheduler",my_scheduler_methods);
	if(my_scheduler_error == NULL) {
		my_scheduler_error = PyErr_NewException("my_scheduler.error", NULL, NULL);
		if (my_scheduler_error == NULL)
			return;
	}
	Py_INCREF(my_scheduler_error);
	PyModule_AddObject(m, "error", my_scheduler_error);
}



import stackless
import my_scheduler
def a():
	while 1:
		print 'test a'
def b():
	while 1:
		print 'test b'

stackless.tasklet(a)()
stackless.tasklet(b)()
my_scheduler.run()

import stackless
def test_schedule():
	while 1:
		t=stackless.run(100)
		t.insert()
def a():
	while 1:
		print 'test a'
def b():
	while 1:
		print 'test b'

stackless.tasklet(a)()
stackless.tasklet(b)()
test_schedule()
_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless

Reply via email to