static void DaoMT_Start0( void *p ) { DaoProcess *proc = (DaoProcess*)p; int count = proc->exceptions->size; DaoProcess_Execute( proc ); DaoProcess_ReturnFutureValue( proc, proc->future ); if( proc->exceptions->size > count ) DaoProcess_PrintException( proc, 1 ); if( proc->future->state == DAO_CALL_FINISHED ){ DaoFuture_ActivateEvent( proc->future ); DaoVmSpace_ReleaseProcess( proc->vmSpace, proc ); } }
static void DaoMT_RunFunctional( void *p ) { DaoTaskData *self = (DaoTaskData*)p; DaoProcess *clone = self->clone; switch( self->param->type ){ case DAO_INTEGER : DaoMT_RunIterateFunctional( p ); break; case DAO_LIST : DaoMT_RunListFunctional( p ); break; case DAO_MAP : DaoMT_RunMapFunctional( p ); break; #ifdef DAO_WITH_NUMARRAY case DAO_ARRAY : DaoMT_RunArrayFunctional( p ); break; #endif } self->status |= clone->status != DAO_PROCESS_FINISHED; DMutex_Lock( self->mutex ); *self->joined += 1; if( clone->exceptions->size ) DaoProcess_PrintException( clone, NULL, 1 ); DCondVar_Signal( self->condv ); DMutex_Unlock( self->mutex ); }
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 ); }
static void DaoCallThread_Run( DaoCallThread *self ) { DaoCallServer *server = daoCallServer; double wt = 0.001; daoint i, timeout; self->thdData = DThread_GetSpecific(); if( self->taskFunc ) self->taskFunc( self->taskParam ); while(1){ DaoProcess *process = NULL; DaoFuture *future = NULL; DThreadTask function = NULL; void *parameter = NULL; self->thdData->state = 0; DMutex_Lock( & server->mutex ); server->idle += 1; 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->finishing && server->idle == server->total ){ if( (server->events2->size + server->waitings->size) == 0 ) break; } 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 ); function = (DThreadTask) server->functions->items.pVoid[i]; parameter = param; DArray_Erase( server->functions, i, 1 ); DArray_Erase( server->parameters, i, 1 ); DMap_Erase( server->pending, parameter ); server->idle -= 1; break; } DMutex_Unlock( & server->mutex ); if( function ){ (*function)( parameter ); DMutex_Lock( & server->mutex ); DMap_Erase( server->active, parameter ); DMutex_Unlock( & server->mutex ); continue; } if( server->pending->size == 0 && server->finishing && server->idle == server->total ) break; DMutex_Lock( & server->mutex ); server->idle -= 1; future = DaoCallServer_GetNextFuture(); DMutex_Unlock( & server->mutex ); if( future == NULL ) continue; process = future->process; if( process == NULL ){ GC_DecRC( future ); continue; } if( process->pauseType == DAO_PAUSE_NATIVE_THREAD ){ DMutex_Lock( & server->mutex ); process->pauseType = 0; /* TODO: demo/concurrent/future.dao */ if( process->condv ) DCondVar_Signal( process->condv ); DMutex_Unlock( & server->mutex ); }else{ int count = process->exceptions->size; future->state = DAO_CALL_RUNNING; DaoProcess_InterceptReturnValue( process ); DaoProcess_Execute( process ); if( process->exceptions->size > count ) DaoProcess_PrintException( process, 1 ); } if( future->actor ){ DMutex_Lock( & server->mutex ); DMap_Erase( server->active, future->actor->rootObject ); DMutex_Unlock( & server->mutex ); } DMutex_Lock( & server->mutex ); DMap_Erase( server->active, process ); 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 ); }