Beispiel #1
0
//***** ThreadSafe! *****
void bbDelay( int millis ){
	int i,e;
	
	if( millis<0 ) return;

	e=bbMilliSecs()+millis;
	
	for( i=0;;++i ){
		int t=e-bbMilliSecs();
		if( t<=0 ){
			if( !i ) usleep( 0 );	//always sleep at least once.
			break;
		}
		usleep( t*1000 );
	}
}
Beispiel #2
0
static void startup(){
	struct sysinfo info;
	
	_mainThread=pthread_self();

	sysinfo( &info );
	base_time=bbMilliSecs()-info.uptime*1000;
}
Beispiel #3
0
static void startup(){
	struct sysinfo info;
	
	//_mainThread=pthread_self();

	// TODO : appears as "undefined" when linking... need this for millisecs support.
	//sysinfo( &info );
	base_time=bbMilliSecs()-info.uptime*1000;
}
Beispiel #4
0
static void *timerProc( void *data ){
	BBTimer *timer=(BBTimer*)data;
	
	int time=timer->start;
	
	while( timer->status==1 ){
		time+=timer->period;

		bbDelay( time-bbMilliSecs() );

		++timer->puts;
		bbSystemPostSyncOp( timerSyncOp,&bbNullObject,(int)timer );
	}

	bbSystemPostSyncOp( timerSyncOp,&bbNullObject,(int)timer );
}
Beispiel #5
0
BBTimer *bbTimerStart( float hertz,BBObject *bbTimer ){
	BBTimer *timer;
	int start=bbMilliSecs();
	
	timer=(BBTimer*)malloc( sizeof( BBTimer ) );
	
	timer->status=1;
	timer->puts=1;
	timer->gets=0;
	timer->start=start;
	timer->period=1000.0f/hertz;
	timer->bbTimer=bbTimer;
	
	if( pthread_create( &timer->thread,0,(void*(*)(void*))timerProc,timer )<0 ){
		free( timer );
		return 0;
	}
	
	BBRETAIN( timer->bbTimer );
	
	return timer;
}
void collectMem( int dummy ){
	int i;
	void **r;
	
	static int recurs;
	if( recurs ){
//		printf( "RECURSIVE GC!\n" );fflush( stdout );
		return;
	}
	recurs=1;

#ifdef DEBUG_GC
	int ms=bbMilliSecs();
#endif
	
	BBThread *thread;
	BBThread *curThread=bbThreadGetCurrent();
	
	BBThread *lockedThreads=_bbThreadLockThreads();
	
	for( thread=lockedThreads;thread;thread=thread->succ ){
	
		for( i=0;i<32;++i ){
			mark( thread->data[i] );
		}

		if( thread==curThread ){
			void *regs[BBGC_NUM_ROOTREGS];
			void **sp=bbGCRootRegs( regs );
			for( i=0;i<BBGC_NUM_ROOTREGS;++i ){
				mark( regs[i] );
			}
			for( r=sp;r!=thread->stackTop;++r ){
				mark( *r );
			}
		}else{
			for( i=0;i<BB_THREADREGS;++i ){
				mark( (void*)thread->locked_regs[i] );
			}
			for( r=(void**)thread->locked_sp;r!=thread->stackTop;++r ){
				mark( *r );
			}
		}
	}
	
	for( i=0;i<n_global_vars;++i ){
		mark( *global_vars[i] );
	}

#ifdef DEBUG_GC
	int mark_ms=bbMilliSecs();
#endif
	
	GCBlock *t;

	//mark locked blocks
	for( t=usedBlocks;t;t=t->succ ){
		if( t->flags & BBGC_LOCKED ) mark( t->data );
	}

	//resurrect or free finalized blocks
	while( t=finalizedBlocks ){
		finalizedBlocks=t->succ;
		if( t->flags & BBGC_MARKED ){
			//resurrect me!
			t->succ=usedBlocks;
			usedBlocks=t;
			if( t->flags & BBGC_FINALIZE ){
				t->flags&=~BBGC_FINALIZE;
#ifdef DEBUG_GC
				BBObject *q=(BBObject*)t->data;
				printf( "GC resurrected:%s @%p\n",typeName( q ),q );fflush( stdout );
#endif
			}
		}else{
			freeBlock( t );
		}
	}

	GCBlock **p=&usedBlocks;

	int n_finalized=0;
	
	while( t=*p ){
		if( t->flags & BBGC_MARKED ){
			p=&t->succ;
			t->flags&=~BBGC_MARKED;
		}else{
			*p=t->succ;
			if( t->flags & BBGC_FINALIZE ){
				++n_finalized;
				BBObject *q=(BBObject*)t->data;
//				printf( "GC finalizing:%s\n",typeName( q ) );fflush( stdout );
				BBClass *c=q->clas;
				c->free( q );
				q->clas=c;
			}
			t->succ=finalizedBlocks;
			finalizedBlocks=t;
		}
	}
	
	if( !n_finalized ){
		//
		//No finalizers were run, so it's OK to free blocks NOW.
		//
		while( t=finalizedBlocks ){
			finalizedBlocks=t->succ;
			freeBlock( t );
		}
	}
	
	_bbThreadUnlockThreads();
	
#ifdef DEBUG_GC
	int end_ms=bbMilliSecs();
	printf( "gc ms=%i, marked=%i, marked_ms=%i, freed=%i, freed_ms=%i\n",end_ms-ms,n_marked,mark_ms-ms,n_freed,end_ms-mark_ms );fflush( stdout );
#endif

	recurs=0;	
}