Example #1
0
static void SYS_Sleep( DaoProcess *proc, DaoValue *p[], int N )
{
#ifdef DAO_WITH_THREAD
	DMutex    mutex;
	DCondVar  condv;
#endif

	double s = p[0]->xFloat.value;
	if( s < 0 ){
		DaoProcess_RaiseException( proc, DAO_WARNING_VALUE, "expecting positive value" );
		return;
	}
#ifdef DAO_WITH_THREAD
	/* sleep only the current thread: */
	DMutex_Init( & mutex );
	DCondVar_Init( & condv );
	DMutex_Lock( & mutex );
	DCondVar_TimedWait( & condv, & mutex, s );
	DMutex_Unlock( & mutex );
	DMutex_Destroy( & mutex );
	DCondVar_Destroy( & condv );
#elif UNIX
	sleep( (int)s ); /* This may cause the whole process to sleep. */
#else
	Sleep( s * 1000 );
#endif
}
static void DaoCondV_Lib_TimedWait( DaoProcess *proc, DaoValue *par[], int N )
{
	DaoCondVar *self = (DaoCondVar*) par[0];
	DaoMutex *mutex = (DaoMutex*) par[1];
	DaoProcess_PutInteger( proc,
			DCondVar_TimedWait( & self->myCondVar, & mutex->myMutex, par[2]->xFloat.value ) );
}
Example #3
0
void DaoCallServer_AddTimedWait( DaoProcess *wait, DaoTaskEvent *event, double timeout )
{
	DaoCallServer *server;
	if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace );
	server = daoCallServer;

	DMutex_Lock( & server->mutex );
	if( timeout >= 1E-27 ){
		server->timestamp.value.real = timeout + Dao_GetCurrentTime();
		server->timestamp.value.imag += 1;
		event->expiring = server->timestamp.value.real;
		DMap_Insert( server->waitings, & server->timestamp, event );
		DMap_Insert( server->pending, event, NULL );
		DCondVar_Signal( & server->condv2 );
	}else{
		event->expiring = -1.0;
		DaoCallServer_AddEvent( event );
		DCondVar_Signal( & server->condv );
	}
	if( wait->condv ){
		/*
		// Need to suspend the native thread, for suspending inside code sections
		// for functional methods such as std.iterate(), mt.iterate() etc:
		*/
		wait->pauseType = DAO_PAUSE_NATIVE_THREAD;
		if( timeout > 0 ){
			DCondVar_TimedWait( wait->condv, & server->mutex, timeout );
		}else{
			DCondVar_Wait( wait->condv, & server->mutex );
		}
		wait->status = DAO_PROCESS_RUNNING;
	}
	DMutex_Unlock( & server->mutex );
}
Example #4
0
void DaoCallServer_Stop()
{
	DCondVar condv;
	DaoCallThread *calth;
	if( daoCallServer == NULL ) return;
	DCondVar_Init( & condv );
	daoCallServer->finishing = 1;

	calth = DaoCallThread_New( NULL, NULL );
	DMutex_Lock( & daoCallServer->mutex );
	daoCallServer->total += 1;
	DMutex_Unlock( & daoCallServer->mutex );

	DaoCallThread_Run( calth );  /* process tasks in the main thread; */

	DMutex_Lock( & daoCallServer->mutex );
	while( daoCallServer->stopped != daoCallServer->total || daoCallServer->timing ){
		DCondVar_TimedWait( & condv, & daoCallServer->mutex, 0.01 );
	}
	DMutex_Unlock( & daoCallServer->mutex );

	DCondVar_Destroy( & condv );
	DaoCallThread_Delete( calth );
	DaoCallServer_Delete( daoCallServer );
	daoCallServer = NULL;
}
Example #5
0
void DThread_PauseVM( DThread *another )
{
	another->vmpause = 1;
	DMutex_Lock( & another->mutex );
	if( ! another->vmpaused ){
		DCondVar_TimedWait( & another->condv, & another->mutex, 0.01 );
	}
	DMutex_Unlock( & another->mutex );
}
Example #6
0
static void DaoCallServer_Timer( void *p )
{
	DaoCallServer *server = daoCallServer;
	double time = 0.0;
	daoint i, timeout;

	server->timing = 1;
	while( server->finishing == 0 || server->stopped != server->total ){
		DMutex_Lock( & server->mutex );
		while( server->waitings->size == 0 ){
			if( server->idle == server->total && server->events2->size ){
				DaoCallServer_ActivateEvents();
			}
			if( server->finishing && server->stopped == server->total ) break;
			DCondVar_TimedWait( & server->condv2, & server->mutex, 0.01 );
		}
		if( server->waitings->size ){
			DNode *node = DMap_First( server->waitings );
			time = node->key.pValue->xComplex.value.real;
			time -= Dao_GetCurrentTime();
			/* wait the right amount of time for the closest arriving timeout: */
			if( time > 0 ) DCondVar_TimedWait( & server->condv2, & server->mutex, time );
		}
		DMutex_Unlock( & server->mutex );
		if( server->finishing && server->stopped == server->total ) break;

		DMutex_Lock( & server->mutex );
		if( server->waitings->size ){ /* a new wait timed out: */
			DNode *node = DMap_First( server->waitings );
			time = Dao_GetCurrentTime();
			if( node->key.pValue->xComplex.value.real < time ){
				DaoTaskEvent *event = (DaoTaskEvent*) node->value.pVoid;
				event->state = DAO_EVENT_RESUME;
				event->timeout = 1;
				event->expiring = MIN_TIME;
				DArray_Append( server->events, node->value.pVoid );
				DMap_EraseNode( server->waitings, node );
			}
		}
		DCondVar_Signal( & server->condv );
		DMutex_Unlock( & server->mutex );
	}
	server->timing = 0;
}
Example #7
0
void DaoCallServer_Stop()
{
	DCondVar condv;
	if( daoCallServer == NULL ) return;
	DCondVar_Init( & condv );
	daoCallServer->finishing = 1;
	DMutex_Lock( & daoCallServer->mutex );
	while( daoCallServer->pending->size || daoCallServer->idle != daoCallServer->total ){
		/* printf( "finalizing: %3i %3i\n", daoCallServer->idle, daoCallServer->total ); */
		DCondVar_TimedWait( & condv, & daoCallServer->mutex, 0.01 );
	}
	while( daoCallServer->stopped != daoCallServer->total || daoCallServer->timing ){
		DCondVar_TimedWait( & condv, & daoCallServer->mutex, 0.01 );
	}
	DMutex_Unlock( & daoCallServer->mutex );
	DCondVar_Destroy( & condv );
	DaoCallServer_Delete( daoCallServer );
	daoCallServer = NULL;
}
Example #8
0
void DaoCallServer_Join()
{
	DCondVar condv;
	if( daoCallServer == NULL ) return;
	DCondVar_Init( & condv );
	DMutex_Lock( & daoCallServer->mutex );
	while( daoCallServer->pending->size || daoCallServer->vacant != daoCallServer->total ){
		DCondVar_TimedWait( & condv, & daoCallServer->mutex, 0.01 );
	}
	DMutex_Unlock( & daoCallServer->mutex );
	DCondVar_Destroy( & condv );
}
Example #9
0
void DaoVmSpace_JoinTasklets( DaoVmSpace *self )
{
	DaoTaskletServer *server = (DaoTaskletServer*) self->taskletServer;
	DCondVar condv;

	if( server == NULL ) return;

	DCondVar_Init( & condv );
	DMutex_Lock( & server->mutex );
	while( server->pending->size || server->vacant != server->total ){
		DCondVar_TimedWait( & condv, & server->mutex, 0.01 );
	}
	DMutex_Unlock( & server->mutex );
	DCondVar_Destroy( & condv );
}
Example #10
0
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 );
}
Example #11
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 = DaoGetSectionCode( proc->activeCode );
	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_APPLY : DaoProcess_PutValue( proc, param ); break;
	case DVM_FUNCT_FIND : DaoProcess_PutValue( proc, dao_none_value ); break;
	}
	if( threads <= 0 ) threads = 2;
	if( sect == NULL || DaoMT_PushSectionFrame( proc ) == 0 ) return;
	if( list ){
		DArray_Clear( & list->items );
		if( param->type == DAO_LIST ) DArray_Resize( & list->items, param->xList.items.size, NULL );
		if( param->type == DAO_MAP ) DArray_Resize( & list->items, param->xMap.items->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 );
		task->clone->mutex = & mutex;
		if( i ) DaoCallServer_AddTask( DaoMT_RunFunctional, task, 1 );
	}
	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, 0 );
		if( param->type == DAO_LIST && index != -1 ){
			DaoValue **items = param->xList.items.items.pValue;
			GC_ShiftRC( items[index], tuple->items[1] );
			tuple->items[1] = items[index];
			tuple->items[0]->xInteger.value = index;
		}else if( param->type == DAO_MAP && node ){
			GC_ShiftRC( node->key.pValue, tuple->items[0] );
			GC_ShiftRC( node->value.pValue, tuple->items[1] );
			tuple->items[0] = node->key.pValue;
			tuple->items[1] = node->value.pValue;
		}
	}
	if( status ) DaoProcess_RaiseException( proc, DAO_ERROR, "code section execution failed!" );
	DMutex_Destroy( & mutex );
	DCondVar_Destroy( & condv );
	dao_free( tasks );
}
Example #12
0
int  DaoCondVar_TimedWait( DaoCondVar *self, DaoMutex *mutex, double seconds )
{
	return DCondVar_TimedWait( & self->myCondVar, & mutex->myMutex, seconds );
}
Example #13
0
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 );
}