Ejemplo n.º 1
0
static void DaoMT_RunArrayFunctional( void *p )
{
	DaoValue **idval;
	DaoValue *elem, *res = NULL;
	DaoValue tidint = {DAO_INTEGER};
	DaoValue com = {DAO_COMPLEX};
	DaoValue *threadid = (DaoValue*)(void*)&tidint;
	DaoTaskData *self = (DaoTaskData*)p;
	DaoProcess *clone = self->clone;
	DaoVmCode *sect = self->sect;
	DaoArray *param = (DaoArray*) self->param;
	DaoArray *result = (DaoArray*) self->result;
	DaoArray *original = param->original;
	DaoArray *array = original ? original : param;
	DArray *slices = param->slices;
	daoint *dims = array->dims;
	daoint i, id, id2, n = DaoArray_SliceSize( param );
	int j, D = array->ndim;
	int isvec = (D == 2 && (dims[0] ==1 || dims[1] == 1));
	int stackBase, vdim = sect->b - 1;

	DaoMT_InitProcess( self->proto, clone );
	tidint.xInteger.value = self->first;

	stackBase = clone->topFrame->active->stackBase;
	idval = clone->activeValues + sect->a + 1;
	for(j=0; j<vdim; j++) idval[j]->xInteger.value = 0;
	for(i=self->first; i<n; i+=self->step){
		idval = clone->stackValues + stackBase + sect->a + 1;
		id = id2 = (original ? DaoArray_IndexFromSlice( original, slices, i ) : i);
		if( isvec ){
			if( vdim >0 ) idval[0]->xInteger.value = id2;
			if( vdim >1 ) idval[1]->xInteger.value = id2;
		}else{
			for( j=D-1; j>=0; j--){
				int k = id2 % dims[j];
				id2 /= dims[j];
				if( j < vdim ) idval[j]->xInteger.value = k;
			}
		}
		elem = clone->stackValues[ stackBase + sect->a ];
		if( elem == NULL || elem->type != array->etype ){
			elem = (DaoValue*)&com;
			elem->type = array->etype;
			elem = DaoProcess_SetValue( clone, sect->a, elem );
		}
		DaoArray_GetValue( array, id, elem );
		if( sect->b > 6 ) DaoProcess_SetValue( clone, sect->a+6, threadid );
		clone->topFrame->entry = self->entry;
		DaoProcess_Execute( clone );
		if( clone->status != DAO_PROCESS_FINISHED ) break;
		res = clone->stackValues[0];
		if( self->funct == DVM_FUNCT_MAP ){
			DaoArray_SetValue( result, i, res );
		}else if( self->funct == DVM_FUNCT_APPLY ){
			DaoArray_SetValue( array, id, res );
		}
	}
}
Ejemplo n.º 2
0
static void DaoMT_Start( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoProcess *clone;
	DaoVmCode *vmc, *end;
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	DaoType *type = DaoProcess_GetReturnType( proc );
	DaoFuture *future = DaoFuture_New( type, 0 );
	int entry, nop = proc->activeCode[1].code == DVM_NOP;

	DaoProcess_PutValue( proc, (DaoValue*) future );
	if( sect == NULL || DaoMT_PushSectionFrame( proc ) == 0 ) return;

	entry = proc->topFrame->entry;
	end = proc->activeRoutine->body->vmCodes->data.codes + proc->activeCode[nop+1].b;
	clone = DaoVmSpace_AcquireProcess( proc->vmSpace );
	DaoProcess_PopFrame( proc );
	DaoProcess_SetActiveFrame( proc, proc->topFrame );
	DaoMT_InitProcess( proc, clone );
	clone->topFrame->entry = entry;
	/*
	// Use the cloned process instead of the parent process, in case that
	// the cloned process will not be joined by the parent process:
	*/
	clone->topFrame->outer = clone;
	future->process = clone;
	GC_IncRC( clone );
	GC_ShiftRC( future, clone->future );
	clone->future = future;
	future->state = DAO_CALL_RUNNING;

	for(vmc=sect; vmc!=end; vmc++){
		int i = -1, code = vmc->code;
		if( code == DVM_GETVH || (code >= DVM_GETVH_I && code <= DVM_GETVH_C) ){
			i = vmc->b;
		}else if( code == DVM_SETVH || (code >= DVM_SETVH_II && code <= DVM_SETVH_CC) ){
			i = vmc->b;
		}
		if( i >= 0 ){
			/* These values should be shared with the parent thread: */
			GC_ShiftRC( proc->activeValues[i], clone->activeValues[i] );
			clone->activeValues[i] = proc->activeValues[i];
		}
	}
	DaoCallServer_AddTask( DaoMT_Start0, clone, p[0]->xEnum.value );
}
Ejemplo n.º 3
0
static void DaoMT_RunMapFunctional( void *p )
{
	DaoValue *res;
	DaoInteger tidint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *threadid = (DaoValue*)(void*)&tidint;
	DaoTaskData *self = (DaoTaskData*)p;
	DaoMap *map = (DaoMap*) self->param;
	DaoList *list2 = (DaoList*) self->result;
	DaoProcess *clone = self->clone;
	DaoVmCode *sect = self->sect;
	DaoType *type = map->ctype;
	DNode *node = NULL;
	daoint i = 0;

	DaoMT_InitProcess( self->proto, clone, 3 );
	tidint.value = self->first;
	type = type && type->nested->size > 1 ? type->nested->items.pType[1] : NULL;
	for(node=DMap_First( map->value ); node; node=DMap_Next(map->value, node) ){
		if( (i++) % self->step != self->first ) continue;
		if( sect->b >0 ) DaoProcess_SetValue( clone, sect->a, node->key.pValue );
		if( sect->b >1 ) DaoProcess_SetValue( clone, sect->a+1, node->value.pValue );
		if( sect->b >2 ) DaoProcess_SetValue( clone, sect->a+2, threadid );
		clone->topFrame->entry = self->entry;
		DaoProcess_Execute( clone );
		if( clone->status != DAO_PROCESS_FINISHED ) break;
		res = clone->stackValues[0];
		if( self->funct == DVM_FUNCT_MAP ){
			self->status |= DaoList_SetItem( list2, res, i-1 );
		}else if( self->funct == DVM_FUNCT_APPLY ){
			self->status |= DaoValue_Move( res, & node->value.pValue, type ) == 0;
		}else if( self->funct == DVM_FUNCT_FIND ){
			DNode **p = self->node;
			/* XXX: 2014-11-11 */
			if( *p && DaoValue_Compare( (*p)->key.pValue, node->key.pValue ) < 0 ) break;
			if( res->xInteger.value ){
				DMutex_Lock( self->mutex );
				if( *p == NULL || DaoValue_Compare( (*p)->key.pValue, node->key.pValue ) >0 ) *p = node;
				DMutex_Unlock( self->mutex );
				break;
			}
		}
	}
}
Ejemplo n.º 4
0
static void DaoMT_RunListFunctional( void *p )
{
	DaoValue *res;
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoInteger tidint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *index = (DaoValue*)(void*)&idint;
	DaoValue *threadid = (DaoValue*)(void*)&tidint;
	DaoTaskData *self = (DaoTaskData*)p;
	DaoList *list = (DaoList*) self->param;
	DaoList *list2 = (DaoList*) self->result;
	DaoProcess *clone = self->clone;
	DaoVmCode *sect = self->sect;
	DaoValue **items = list->items.items.pValue;
	daoint i, n = list->items.size;

	DaoMT_InitProcess( self->proto, clone );
	tidint.value = self->first;
	for(i=self->first; i<n; i+=self->step){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( clone, sect->a, items[i] );
		if( sect->b >1 ) DaoProcess_SetValue( clone, sect->a+1, index );
		if( sect->b >2 ) DaoProcess_SetValue( clone, sect->a+2, threadid );
		clone->topFrame->entry = self->entry;
		DaoProcess_Execute( clone );
		if( clone->status != DAO_PROCESS_FINISHED ) break;
		res = clone->stackValues[0];
		if( self->funct == DVM_FUNCT_MAP ){
			self->status |= DaoList_SetItem( list2, res, i );
		}else if( self->funct == DVM_FUNCT_APPLY ){
			self->status |= DaoList_SetItem( list, res, i );
		}else if( self->funct == DVM_FUNCT_FIND ){
			if( *self->index >= 0 && *self->index < i ) break;
			if( res->xInteger.value ){
				DMutex_Lock( self->mutex );
				if( *self->index < 0 || i < *self->index ) *self->index = i;
				DMutex_Unlock( self->mutex );
				break;
			}
		}
	}
}
Ejemplo n.º 5
0
static void DaoMT_RunIterateFunctional( void *p )
{
	DaoInteger idint = {DAO_INTEGER,0,0,0,0,0};
	DaoInteger tidint = {DAO_INTEGER,0,0,0,0,0};
	DaoValue *index = (DaoValue*)(void*)&idint;
	DaoValue *threadid = (DaoValue*)(void*)&tidint;
	DaoTaskData *self = (DaoTaskData*)p;
	DaoProcess *clone = self->clone;
	DaoVmCode *sect = self->sect;
	daoint i, n = self->param->xInteger.value;

	DaoMT_InitProcess( self->proto, clone );
	tidint.value = self->first;
	for(i=self->first; i<n; i+=self->step){
		idint.value = i;
		if( sect->b >0 ) DaoProcess_SetValue( clone, sect->a, index );
		if( sect->b >1 ) DaoProcess_SetValue( clone, sect->a+1, threadid );
		clone->topFrame->entry = self->entry;
		DaoProcess_Execute( clone );
		if( clone->status != DAO_PROCESS_FINISHED ) break;
	}
}
Ejemplo n.º 6
0
static void DaoMT_Start( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoProcess *clone;
	DaoVmCode *vmc, *end, *sect;
	DaoType *type = DaoProcess_GetReturnType( proc );
	DaoFuture *future = DaoFuture_New( type, 0 );
	int entry, nop = proc->activeCode[1].code == DVM_NOP;

	DaoProcess_PutValue( proc, (DaoValue*) future );
	sect = DaoProcess_InitCodeSection( proc, 0 );
	if( sect == NULL ) return;

	entry = proc->topFrame->entry;
	end = proc->activeRoutine->body->vmCodes->data.codes + proc->activeCode[nop+1].b;
	clone = DaoVmSpace_AcquireProcess( proc->vmSpace );
	DaoProcess_PopFrame( proc );
	DaoMT_InitProcess( proc, clone, 0 );
	clone->topFrame->entry = entry;
	/*
	// Use the cloned process instead of the parent process, in case that
	// the cloned process will not be joined by the parent process:
	*/
	clone->topFrame->outer = clone;
	future->process = clone;
	GC_IncRC( clone );
	GC_Assign( & clone->future, future );
	future->state = DAO_CALL_RUNNING;

	for(vmc=sect; vmc!=end; vmc++){
		int i = -1, code = vmc->code;
		if( code == DVM_GETVH || (code >= DVM_GETVH_I && code <= DVM_GETVH_C) ){
			i = vmc->b;
		}else if( code == DVM_SETVH || (code >= DVM_SETVH_II && code <= DVM_SETVH_CC) ){
			i = vmc->b;
		}
		if( i >= 0 ) DaoValue_Move( proc->activeValues[i], & clone->activeValues[i], NULL );
	}
	DaoCallServer_AddTask( DaoMT_Start0, clone, p[0]->xEnum.value ? clone : NULL );
}