view src/pthread/ThreadManager.cbc @ 13:f06fb0370caf

add pthread code that has not been debuged yet.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 08 Jan 2010 20:00:01 +0900
parents 07fab8c367b2
children 5f65da34f4f3
line wrap: on
line source

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

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


typedef struct _UserManager {
	Scheduler scheduler;
	struct _ThreadManager *threadmanager;
	/*
	 * ユーザ側からは次のように見えるのが望ましい?
	 *  struct UserManager {
	 *  	Scheduler scheduler;
	 *  }
	 */
} UserManager;


void *
threadbase(void *args)
{
	ThreadManager *manager = args;
	UserManager *umanager;

	umanager = malloc(sizeof(Usermanager));
	umanager->scheduler = schedEntry;
	umanager->threadmanager = manager;
	manager->user = umanager;

	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);
	free(manager->user);
	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.
 */
static __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->user, task->task->rbuff, task->task->wbuff);
	} else {
		/* no task we have.  */
		//goto checkNewCode();
		goto threadloop(manager);
	}
}

static __code
schedEntry(UserManager *user, Taskrun nextcode, void *rbuff, void *wbuff)
{
	ThreadManager *manager = user->threadmanager;
	/* 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);
	}
}