Пример #1
0
void* coro_fun(void *arg)
{
	//printf("a coro start\n");
	coro_t co = (coro_t)arg;
	LINK_LIST_PUSH_BACK(co->_sche->active_list_2,co);
	co->status = CORO_ACTIVE;
	uthread_switch(co->ut,co->_sche->co->ut,co);
	void *ret = co->fun(co->arg);
	co->status = CORO_DIE;
	uthread_switch(co->ut,co->_sche->co->ut,co);
	return NULL;
}
Пример #2
0
static inline coro_t _sche_next(sche_t s,coro_t co)
{

	coro_t next = NULL;
	coro_t coro_goback = co->_goback;
	if(NULL == coro_goback)
	{
		next = LINK_LIST_POP(coro_t,s->active_list_1);
		if(!next)
			next = LINK_LIST_POP(coro_t,s->active_list_2);
		if(!next)	
			next = s->co;
	}
	else
	{
		next = coro_goback;
		co->_goback = NULL;
	}
	
	if(co->status == CORO_YIELD)
	{
		co->status = CORO_ACTIVE;
		LINK_LIST_PUSH_BACK(s->active_list_2,co);
	}
	assert(co != next);
	set_current_coro(next);
	return (coro_t)uthread_switch(co->ut,next->ut,co);
}
Пример #3
0
/*
 * uthread_yield
 *
 * Causes the currently running thread to yield use of the processor to
 * another thread. 
 */
void
uthread_yield(void)
{
	/* Yield the processor to somebody */
	/* Always succeeds */
	/* When we call this function, the thread is not in CPU anymore */
	int offset = ut_curthr - &uthreads[0];
	/* Make sure it's not hack */
	if (offset >= 0 && 
		offset < UTH_MAX_UTHREADS &&
		ut_curthr->ut_state == UT_ON_CPU)
	{
		ut_curthr->ut_state = UT_RUNNABLE;
		/* Set the priority */
		if (uthread_setprio(ut_curthr->ut_id, ut_curthr->ut_prio) != 0)
		{
			char pbuffer[256] = {0};
			sprintf(pbuffer, "error in setprio\n");  
			int ret = write(STDOUT_FILENO, pbuffer, strlen(pbuffer));
			if (ret < 0) 
			{
				perror("write");
			}
			exit(EXIT_FAILURE);
		}
	}
	/* do switch */
	uthread_switch();
}
Пример #4
0
void* ufun1(void *arg)
{
    uthread_t self = (uthread_t)arg;
    uthread_t u = uthread_create(self,stack2,4096,ufun2);
    char* _arg[2];
    _arg[0] = (char*)u;
    _arg[1] = (char*)self;
    int i = 0;
    uint32_t tick = GetSystemMs();
    for( ; i < 30000000; ++i)
    {
        uthread_switch(self,u,&_arg[0]);
    }
    printf("%d\n",GetSystemMs()-tick);
    uthread_switch(self,u,NULL);
    return arg;
}
Пример #5
0
/*
 * uthread_yield
 *
 * Causes the currently running thread to yield use of the processor to
 * another thread. The thread is still runnable however, so it should
 * be in the UT_RUNNABLE state and schedulable by the scheduler. When this
 * function returns, the thread should be executing again. A bit more clearly,
 * when this function is called, the current thread stops executing for some
 * period of time (allowing another thread to execute). Then, when the time
 * is right (ie when a call to uthread_switch() results in this thread
 * being swapped in), the function returns.
 */
void
uthread_yield(void)
{
	//NOT_YET_IMPLEMENTED("UTHREADS: uthread_yield");
        ut_curthr-> ut_state = UT_RUNNABLE;
        uthread_switch();
        ut_curthr->ut_state = UT_ON_CPU;
        return;
}
Пример #6
0
/*
 * uthread_block
 *
 * Put the current thread to sleep, pending an appropriate call to 
 * uthread_wake().
 */
void
uthread_block(void) 
{
	//NOT_YET_IMPLEMENTED("UTHREADS: uthread_block");
        ut_curthr -> ut_state = UT_WAIT;
        uthread_switch();
        //woken up by others
        ut_curthr->ut_state = UT_ON_CPU;
        return;
}
Пример #7
0
int32_t sche_spawn(sche_t s,void*(*fun)(void*),void*arg)
{
	if(s->coro_size > s->max_coro)
		return -1;
	coro_t co = coro_create(s,s->stack_size,coro_fun);
	co->arg = arg;
	co->fun = fun;
	++s->coro_size;
	double_link_push(&s->coros,&co->dblink);
	uthread_switch(s->co->ut,co->ut,co);
	return 0;
}
Пример #8
0
/*
 * uthread_block
 *
 * Put the current thread to sleep, pending an appropriate call to 
 * uthread_wake().
 */
void
uthread_block(void) 
{
	/* Already waiting? deadlock */
	if (ut_curthr->ut_state == UT_WAIT)
	{
		uthread_switch();
	}
	/* If the current thread is on cpu, then do context switch */
	if (ut_curthr->ut_state == UT_ON_CPU)
	{
		ut_curthr->ut_state = UT_WAIT;
		uthread_switch();
	}
	/* If the current thread is in the queue, remove it from the queue */
	else if (ut_curthr->ut_state == UT_RUNNABLE)
	{
		ut_curthr->ut_state = UT_WAIT;
		utqueue_remove(&runq_table[ut_curthr->ut_prio], ut_curthr);
	}
}
Пример #9
0
void* ufun2(void *arg)
{
    printf("ufun2\n");
    char **tmp = (char**)arg;
    uthread_t self = (uthread_t)tmp[0];
    uthread_t parent = (uthread_t)tmp[1];
    volatile void *ptr = self;
    while(ptr)
    {
        ptr = uthread_switch(self,parent,NULL);
    }
    return NULL;
}
Пример #10
0
int main()
{
    stack1 = (char*)malloc(4096);
    stack2 = (char*)malloc(4096);
    /*
    if use ucontext version
    char dummy_stack[4096];
    uthread_t p = uthread_create(NULL,dummy_stack,0,NULL);
    */
    uthread_t p = uthread_create(NULL,NULL,0,NULL);
    uthread_t u = uthread_create(p,stack1,4096,ufun1);
    uthread_switch(p,u,u);
    printf("main end\n");
    return 0;
};
Пример #11
0
/*
*  next选择方案,如果有goback优先选择goback作为下一个被运行的coro,
*  否则取active_list_1首元素作为下一个被运行的coro,如果active_list_1
*  为空则直接返回.
*/
coro_t _sche_next_1(sche_t s,coro_t co)
{

	coro_t next = NULL;
	coro_t coro_goback = co->_goback;
	if(NULL == coro_goback)
	{	
		coro_t next = LINK_LIST_POP(coro_t,s->active_list_1);
		if(!next)
			return NULL;
	}
	else
	{
		next = coro_goback;
		co->_goback = NULL;
	}
	LINK_LIST_PUSH_BACK(s->active_list_2,co);
	assert(co != next);	
	set_current_coro(next);
	return (coro_t)uthread_switch(co->ut,next->ut,co);	
}
Пример #12
0
void sche_sche_co(coro_t from,coro_t to)
{
	set_current_coro(to);
	uthread_switch(from->ut,to->ut,from);
}