Exemple #1
0
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();
	}
}
Exemple #2
0
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 );
}