view src/pthread/ThreadManager.cbc @ 8:07fab8c367b2

made src directory and move all source files into it. support autocont and automake tools.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 08 Jan 2010 14:40:49 +0900
parents
children f06fb0370caf
line wrap: on
line source

#include <stdlib.h>
#include <pthread.h>
// TODO: malloc

#include "Debug.h"
#include "Fifo/SchedTask.h"


typedef struct _ThreadManager {
	pthread_t thread;
	int thread_id;
	int finishFlag;

	// These Queue should be changed to Blocking-Queue.
	// Now, when the thread has no task, he wait by busy loop.
	Queue newtaskQ;
	Queue finishtaskQ;

	List schedTasks;
	SchedTask running;
} ThreadManager;


void *
threadbase(void *args)
{
	ThreadManager *manager = args;
	goto threadloop(manager);
}


__code
threadloop(ThreadManager *manager)
{
	if (manager->finishFlag)
		goto exitThread(manager);
	else
		goto checkNewTask(manager);
}

__code
exitThread(ThreadManager *manager)
{
	__DEBUG("thread whose id is %d finished!", manager->thread_id);
	pthread_exit(0);
}

__code
checkNewTask(ThreadManager *manager)
{
	Task *task;
	task = Qpoll(newtaskQ);
	if (task) {
		SchedTask *stask;
		stask = malloc(sizeof(SchedTask));
		stask->task = task;
		stask->nextcode = tasktypes[task->typeid].code;
		stask->rbuff = task->rbuff;
		stask->wbuff = task->wbuff;

		manager->schedTasks = _listAddFirst(manager->schedTasks, stask);
		goto checkNewTask(manager);
	} else {
		goto selectCode(manager);
	}
}

/*
 *  Scheduler
 *  copied from Fifo/TaskManager.cbc.
 *  it may should be organized to common codes.
 */
__code
selectCode(ThreadManager *manager)
{
	SchedTask *task;
	if (manager->schedTasks) {
		task = (SchedTask*)_listGetLastData(manager->schedTasks);
		manager->running = task;

		/* goto user-defined task.  */
		goto task->nextcode(manager, task->task->rbuff, task->task->wbuff);
	} else {
		/* no task we have.  */
		//goto checkNewCode();
		goto threadloop(manager);
	}
}

__code
schedEntry(ThreadManager *manager, Taskrun nextcode, void *rbuff, void *wbuff)
{
	/* schedulerd  */
	if ( nextcode==NULL ) {
		/* the task finished.  */
		manager->schedTasks =
			_listRemove(manager->schedTasks, manager->running);
		Qoffer(manager->finishtaskQ, manager->running->task);
		//goto selectCode(manager);
		goto threadloop(manager);
	} else {
		/* save the next code segment for the task.  */
		manager->running->nextcode = nextcode;
		manager->running->rbuff = rbuff;
		manager->running->wbuff = wbuff;
		/* move last task to first to be fair.  */
		manager->schedTasks = _listMoveLasttoFirst(manager->schedTasks);
		goto selectCode(manager);
	}
}