Пример #1
0
int DaoProcess_Resume( DaoProcess *self, DaoValue *par[], int N, DaoProcess *ret )
{
	DaoType *tp;
	DaoVmCode *vmc;
	DaoTuple *tuple;
	if( self->status != DAO_PROCESS_SUSPENDED ) return 0;
	if( self->activeCode && self->activeCode->code == DVM_MCALL ){
		tp = self->activeTypes[ self->activeCode->c ];
		if( N == 1 ){
			DaoProcess_PutValue( self, par[0] );
		}else if( N ){ /* TODO */
			tuple = DaoTuple_New( N );
			tuple->ctype = tp;
			GC_IncRC( tuple->ctype );
			DaoProcess_MakeTuple( self, tuple, par, N );
			DaoProcess_PutValue( self, (DaoValue*) tuple );
		}
	}else if( N ){ /* TODO */
		DaoRoutine *rout = self->topFrame->routine;
		self->paramValues = self->stackValues + self->topFrame->stackBase;
		if( rout ) rout = DaoProcess_PassParams( self, rout, NULL, NULL, par, NULL, N, DVM_CALL );
		self->paramValues = self->stackValues + 1;
		if( rout == NULL ){
			DaoProcess_RaiseError( ret, NULL, "invalid parameters." );
			return 0;
		}
	}
	DaoProcess_Start( self );
	DaoProcess_PutValue( ret, self->stackValues[0] );
	return 1;
}
Пример #2
0
static void DaoMT_Start0( void *p )
{
	DaoProcess *proc = (DaoProcess*)p;
	int count = proc->exceptions->size;
	DaoProcess_Start( proc );
	DaoProcess_ReturnFutureValue( proc, proc->future );
	if( proc->exceptions->size > count ) DaoProcess_PrintException( proc, NULL, 1 );
	if( proc->future->state == DAO_CALL_FINISHED ){
		DaoFuture_ActivateEvent( proc->future );
		DaoVmSpace_ReleaseProcess( proc->vmSpace, proc );
	}
}
Пример #3
0
static void COROUT_Start( DaoProcess *proc, DaoValue *par[], int N )
{
	DaoxCoroutine *self = (DaoxCoroutine*) par[0];
	DaoValue *params[DAO_MAX_PARAM];
	DaoValue *val = par[1];
	DaoProcess *vmProc;
	DaoRoutine *rout;
	int i, passed = 0;
	if( val == NULL || val->type != DAO_ROUTINE ){
		DaoProcess_RaiseError( proc, "Type", NULL );
		return;
	}
	params[0] = par[0];
	memcpy( params + 1, par + 2, (N-2)*sizeof(DaoValue*) );
	rout = DaoRoutine_Resolve( (DaoRoutine*)val, NULL, NULL, params, NULL, N-1, DVM_CALL );
	if( rout ) rout = DaoProcess_PassParams( proc, rout, NULL, NULL, params, NULL, N-1, DVM_CALL );
	if( rout == NULL || rout->body == NULL ){
		DaoProcess_RaiseError( proc, "Param", "not matched" );
		return;
	}
	if( self->process == NULL ){
		self->process = DaoProcess_New( proc->vmSpace );
		GC_IncRC( self->process );
	}
	vmProc = self->process;
	DaoProcess_PushRoutine( vmProc, rout, NULL );
	vmProc->activeValues = vmProc->stackValues + vmProc->topFrame->stackBase;
	for(i=0; i<rout->parCount; i++){
		vmProc->activeValues[i] = proc->paramValues[i];
		GC_IncRC( vmProc->activeValues[i] );
	}
	vmProc->status = DAO_PROCESS_SUSPENDED;
	vmProc->pauseType = DAO_PAUSE_COROUTINE_YIELD;
	DaoProcess_Start( vmProc );
	DaoProcess_PutValue( proc, vmProc->stackValues[0] );
	if( vmProc->status == DAO_PROCESS_ABORTED )
		DaoProcess_RaiseError( proc, NULL, "coroutine execution is aborted." );
}
Пример #4
0
static void DaoCallThread_Run( DaoCallThread *self )
{
	DaoCallServer *server = daoCallServer;
	double wt = 0.001;
	daoint i, count, timeout;

	self->thdData = DThread_GetSpecific();
	if( self->taskFunc ){
		self->taskFunc( self->taskParam );
		self->taskOwner = NULL;
	}
	while( server->vmspace->stopit == 0 ){
		DaoProcess *process = NULL;
		DaoFuture *future = NULL;
		DThreadTask function = NULL;
		void *parameter = NULL;

		if( self->thdData != NULL ) self->thdData->state = 0;
		DMutex_Lock( & server->mutex );
		server->idle += 1;
		server->vacant += self->taskOwner == NULL;
		while( server->pending->size == (server->events2->size + server->waitings->size) ){
			//printf( "%p %i %i %i %i\n", self, server->events->size, server->pending->size, server->events2->size, server->waitings->size );
			if( server->vmspace->stopit ) break;
			if( server->finishing && server->vacant == server->total ){
				if( (server->events2->size + server->waitings->size) == 0 ) break;
			}
			wt = 0.01*(server->idle == server->total) + 0.001;
			timeout = DCondVar_TimedWait( & server->condv, & server->mutex, wt );
		}
		for(i=0; i<server->parameters->size; ++i){
			void *param = server->parameters->items.pVoid[i];
			if( DMap_Find( server->active, param ) ) continue;
			DMap_Insert( server->active, param, NULL );
			self->taskOwner = server->owners->items.pVoid[i];
			function = (DThreadTask) server->functions->items.pVoid[i];
			parameter = param;
			DList_Erase( server->functions, i, 1 );
			DList_Erase( server->parameters, i, 1 );
			DList_Erase( server->owners, i, 1 );
			DMap_Erase( server->pending, parameter );
			server->idle -= 1;
			server->vacant -= 1;
			break;
		}
		DMutex_Unlock( & server->mutex );

		if( server->vmspace->stopit ) break;
		if( function ){
			(*function)( parameter );
			self->taskOwner = NULL;
			DMutex_Lock( & server->mutex );
			DMap_Erase( server->active, parameter );
			DMutex_Unlock( & server->mutex );
			continue;
		}

		if( server->pending->size == 0 && server->finishing && server->vacant == server->total ) break;

		DMutex_Lock( & server->mutex );
		server->idle -= 1;
		server->vacant -= self->taskOwner == NULL;
		future = DaoCallServer_GetNextFuture();
		DMutex_Unlock( & server->mutex );

		if( future == NULL ) continue;

		process = future->process;
		if( process == NULL ){
			GC_DecRC( future );
			continue;
		}

		count = process->exceptions->size;
		future->state = DAO_CALL_RUNNING;
		DaoProcess_InterceptReturnValue( process );
		DaoProcess_Start( process );
		if( process->exceptions->size > count ) DaoProcess_PrintException( process, NULL, 1 );
		if( process->status <= DAO_PROCESS_ABORTED ) self->taskOwner = NULL;

		if( future->actor ){
			int erase = 1;
			DMutex_Lock( & server->mutex );
			if( future->actor->rootObject->isAsync ){
				erase = process->status == DAO_PROCESS_FINISHED;
			}
			if( erase ) DMap_Erase( server->active, future->actor->rootObject );
			DMutex_Unlock( & server->mutex );
		}
		DMutex_Lock( & server->mutex );
		DMap_Erase( server->active, process );
		process->active = 0;
		DMutex_Unlock( & server->mutex );

		DaoProcess_ReturnFutureValue( process, future );
		if( future->state == DAO_CALL_FINISHED ) DaoFuture_ActivateEvent( future );
		GC_DecRC( future );
	}
	DMutex_Lock( & server->mutex );
	server->stopped += 1;
	DMutex_Unlock( & server->mutex );
}