void DList_Assign( DList *left, DList *right ) { daoint i; assert( left->type == right->type || (left->type == DAO_DATA_VALUE && right->type == 0) ); if( left == right ) return; if( right->size == 0 ){ DList_Clear( left ); return; } if( left->type ){ DList_Clear( left); for( i=0; i<right->size; i++ ) DList_Append( left, right->items.pVoid[i] ); }else{ DList_Resize( left, right->size, NULL ); if( left->type == DAO_DATA_VALUE ) DaoGC_LockData(); for( i=0; i<right->size; i++ ) left->items.pVoid[i] = right->items.pVoid[i]; if( left->type == DAO_DATA_VALUE ) DaoGC_UnlockData(); } }
static void DaoMT_Functional( DaoProcess *proc, DaoValue *P[], int N, int F ) { DMutex mutex; DCondVar condv; DaoTaskData *tasks; DaoValue *param = P[0]; DaoValue *result = NULL; DaoList *list = NULL; DaoArray *array = NULL; DaoVmCode *sect = NULL; DaoStackFrame *frame = DaoProcess_FindSectionFrame( proc ); int i, entry, threads = P[1]->xInteger.value; daoint index = -1, status = 0, joined = 0; DNode *node = NULL; switch( F ){ case DVM_FUNCT_MAP : if( param->type == DAO_ARRAY ){ array = DaoProcess_PutArray( proc ); result = (DaoValue*) array; }else{ list = DaoProcess_PutList( proc ); result = (DaoValue*) list; } break; case DVM_FUNCT_FIND : DaoProcess_PutValue( proc, dao_none_value ); break; } if( threads <= 0 ) threads = 2; if( frame != proc->topFrame->prev ){ DaoProcess_RaiseError( proc, NULL, "Invalid code section from non-immediate caller" ); return; } sect = DaoProcess_InitCodeSection( proc, 0 ); if( sect == NULL ) return; if( list ){ DList_Clear( list->value ); if( param->type == DAO_LIST ) DList_Resize( list->value, param->xList.value->size, NULL ); if( param->type == DAO_MAP ) DList_Resize( list->value, param->xMap.value->size, NULL ); #ifdef DAO_WITH_NUMARRAY }else if( array && F == DVM_FUNCT_MAP ){ DaoArray_GetSliceShape( (DaoArray*) param, & array->dims, & array->ndim ); DaoArray_ResizeArray( array, array->dims, array->ndim ); #endif } DMutex_Init( & mutex ); DCondVar_Init( & condv ); entry = proc->topFrame->entry; tasks = (DaoTaskData*) dao_calloc( threads, sizeof(DaoTaskData) ); DaoProcess_PopFrame( proc ); for(i=0; i<threads; i++){ DaoTaskData *task = tasks + i; task->param = param; task->result = result; task->proto = proc; task->sect = sect; task->funct = F; task->entry = entry; task->first = i; task->step = threads; task->index = & index; task->node = & node; task->joined = & joined; task->condv = & condv; task->mutex = & mutex; task->clone = DaoVmSpace_AcquireProcess( proc->vmSpace ); if( i ) DaoCallServer_AddTask( DaoMT_RunFunctional, task, task->clone ); } DaoMT_RunFunctional( tasks ); DMutex_Lock( & mutex ); while( joined < threads ) DCondVar_TimedWait( & condv, & mutex, 0.01 ); DMutex_Unlock( & mutex ); for(i=0; i<threads; i++){ DaoTaskData *task = tasks + i; DaoVmSpace_ReleaseProcess( proc->vmSpace, task->clone ); status |= task->status; } if( F == DVM_FUNCT_FIND ){ DaoTuple *tuple = DaoProcess_PutTuple( proc, 2 ); if( param->type == DAO_LIST && index != -1 ){ DaoValue **items = param->xList.value->items.pValue; GC_Assign( & tuple->values[1], items[index] ); tuple->values[0]->xInteger.value = index; }else if( param->type == DAO_MAP && node ){ GC_Assign( & tuple->values[0], node->key.pValue ); GC_Assign( & tuple->values[1], node->value.pValue ); } } if( status ) DaoProcess_RaiseError( proc, NULL, "code section execution failed!" ); DMutex_Destroy( & mutex ); DCondVar_Destroy( & condv ); dao_free( tasks ); }