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; }
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 ); } }
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." ); }
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 ); }