Mark Sibly %!s(int64=7) %!d(string=hai) anos
pai
achega
735b092ccd

+ 2 - 0
.gitignore

@@ -46,6 +46,8 @@ __NEWPAGES__/
 /modules/pyro-scenegraph
 /modules/pyro-tiled
 /modules/box2d
+/modules/box2dxt
+/modules/steamworks
 
 /modules/module-manager/backups
 

+ 26 - 50
modules/monkey/native/bbgc_mx.cpp

@@ -90,9 +90,7 @@ namespace bbGC{
 		if( inited ) return;
 		inited=true;
 		
-		printf( "sizeof( std::atomic_char )=%i\n",sizeof( std::atomic_char ) );
-		printf( "std::atomic_char().is_lock_free()=%i\n",std::atomic_char().is_lock_free() );
-		fflush( stdout );
+		bb_printf( "Initializing threaded GC\n" );
 		
 		markedBit=1;
 		markedList=&markLists[0];
@@ -171,24 +169,18 @@ namespace bbGC{
 	//
 	void suspendThreads(){
 	
-		bbGCThread *thread=threads;
-		
-		for( ;; ){
-		
-			if( thread!=currentThread ){
+		for( bbGCThread *thread=currentThread->succ;thread!=currentThread;thread=thread->succ ){
 
-				int n=(int)SuspendThread( thread->handle );
+			int n=(int)SuspendThread( thread->handle );
 						
-				if( n<0 ){ printf( "SuspendThread failed! n=%i\n",n );fflush( stdout );exit( -1 ); }
-			
-				CONTEXT context={0};//CONTEXT_CONTROL};
+			if( n<0 ){ printf( "SuspendThread failed! n=%i\n",n );fflush( stdout );exit( -1 ); }
+		}
+
+		for( bbGCThread *thread=currentThread->succ;thread!=currentThread;thread=thread->succ ){
+
+			CONTEXT context={0};//CONTEXT_CONTROL};
 						
-				if( !GetThreadContext( thread->handle,&context ) ){ printf( "GetThreadContext failed\n" );fflush( stdout );exit( -1 ); }
-			}
-			
-			thread=thread->succ;
-			
-			if( thread==threads ) break;
+			if( !GetThreadContext( thread->handle,&context ) ){ printf( "GetThreadContext failed\n" );fflush( stdout );exit( -1 ); }
 		}
 	}
 	
@@ -196,31 +188,21 @@ namespace bbGC{
 	//
 	void resumeThreads(){
 	
-		bbGCThread *thread=threads;
-		
-		for( ;; ){
-		
-			if( thread!=currentThread ){
-				
-				ResumeThread( thread->handle );
-			}
+		for( bbGCThread *thread=currentThread->succ;thread!=currentThread;thread=thread->succ ){
 
-			thread=thread->succ;
-			
-			if( thread==threads ) break;
+			ResumeThread( thread->handle );
 		}
 	}
 
 #else
-
-	std::atomic_int resumeCount{0};
-	std::atomic_bool threadSuspended{false};
 	
 	std::mutex suspendMutex;
 	std::condition_variable_any suspendCondvar;
+	std::atomic_int threadsSuspending{0};
 	
 	std::mutex resumeMutex;
 	std::condition_variable_any resumeCondvar;
+	std::atomic_int resumeCount{0};
 	
 	void suspendSigHandler( int sig ){
 	
@@ -228,7 +210,7 @@ namespace bbGC{
 	
 		//signal suspended
 		suspendMutex.lock();
-		threadSuspended=true;
+		threadsSuspending-=1;
 		suspendMutex.unlock();
 		suspendCondvar.notify_one();
 		
@@ -242,26 +224,20 @@ namespace bbGC{
 	//
 	void suspendThreads(){
 	
-		bbGCThread *thread=threads;
+		threadsSuspending=0;
+	
+		for( bbGCThread *thread=currentThread->succ;thread!=currentThread;thread=thread->succ ){
 		
-		suspendMutex.lock();
-		for( ;; ){
+			++threadsSuspending;
+		}
 		
-			if( thread!=currentThread ){
-				
-				threadSuspended=false;
-				suspendMutex.unlock();
-				
-				pthread_kill( (pthread_t)thread->handle,SIGUSR2 );
-
-				suspendMutex.lock();
-				while( !threadSuspended ) suspendCondvar.wait( suspendMutex );
-			}
-			
-			thread=thread->succ;
-			
-			if( thread==threads ) break;
+		for( bbGCThread *thread=currentThread->succ;thread!=currentThread;thread=thread->succ ){
+		
+			pthread_kill( (pthread_t)thread->handle,SIGUSR2 );
 		}
+		
+		suspendMutex.lock();
+		while( threadsSuspending ) suspendCondvar.wait( suspendMutex );
 		suspendMutex.unlock();
 	}
 	

+ 64 - 0
modules/thread/tests/test2.monkey2

@@ -0,0 +1,64 @@
+
+Namespace threadtest2
+
+#Import "<std>"
+#Import "<mojo>"
+#Import "<thread>"
+
+#Import "threads.jpg"
+
+Using std..
+Using mojo..
+
+Class MyWindow Extends Window
+	
+	Field _image:Image
+	
+	Field _progress:Int
+
+	Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )
+
+		Super.New( title,width,height,flags )
+		
+		'Create our loading thread.
+		New Thread( Lambda()
+		
+			For Local i:=0 Until 1000
+				
+				Local image:=Image.Load( "asset::threads.jpg" )
+				
+				'Update progress %
+				_progress=i*100/1000
+			Next
+
+			Local image:=Image.Load( "asset::threads.jpg" )
+			
+			image.Handle=New Vec2f( .5,.5 )
+			
+			_image=image
+			
+		End ).Detach()
+	End
+
+	Method OnRender( canvas:Canvas ) Override
+	
+		App.RequestRender()
+		
+		If Not _image
+			canvas.DrawText( "Loading...progress "+_progress+"%",Width/2,Height/2,.5,.5 )
+			Return
+		Endif
+		
+		canvas.DrawImage( _image,Mouse.Location )
+	End
+	
+End
+
+Function Main()
+
+	New AppInstance
+	
+	New MyWindow
+	
+	App.Run()
+End

+ 84 - 0
modules/thread/tests/test3.monkey2

@@ -0,0 +1,84 @@
+
+#Rem
+
+Little demo showing how to add things to a queue for a thread to process.
+
+#End
+
+Namespace myapp
+
+#Import "<std>"
+#Import "<mojo>"
+#Import "<thread>"
+
+Using std..
+Using mojo..
+
+Class MyWindow Extends Window
+	
+	Field _queue:=New IntDeque
+	Field _mutex:=New Mutex
+	Field _sema:=New Semaphore
+	
+	Field _sent:Int
+	Field _recv:Int
+
+	Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )
+
+		Super.New( title,width,height,flags )
+		
+		'Create background thread and detach it.
+		New Thread( Lambda()
+		
+			Repeat 
+				'Wait for something to be added to queue.
+				_sema.Wait()
+
+				'Remove next item from the queue - the mutex protects against concurrent modification.
+				_mutex.Lock()
+				Local item:=_queue.RemoveFirst()
+				_mutex.Unlock()
+
+				_recv+=item
+			Forever
+		
+		End ).Detach()
+	End
+
+	Method OnRender( canvas:Canvas ) Override
+	
+		App.RequestRender()
+		
+		'Adds a random number of items to the queue.
+		For Local i:=0 Until Int( Rnd(5)+5 )
+
+			'Each item is just a random int.
+			Local item:=Int( Rnd( 5 ) )
+			
+			_sent+=item
+			
+			'Add item to the queue - the mutex protects against concurrent modification.
+			_mutex.Lock()
+			_queue.AddLast( item )
+			_mutex.Unlock()
+			
+			'Signal thread there's something new to be removed.
+			_sema.Signal()
+		Next
+		
+		'Easier to check difference - recv should equal sent but with a lag.
+		Local diff:=_sent-_recv
+		
+		canvas.DrawText( "Sent="+_sent+", Received="+_recv+", Difference="+diff,Width/2,Height/2,.5,.5 )
+	End
+	
+End
+
+Function Main()
+
+	New AppInstance
+	
+	New MyWindow
+	
+	App.Run()
+End

BIN=BIN
modules/thread/tests/threads.jpg


+ 4 - 5
src/mx2cc/mx2cc.monkey2

@@ -24,12 +24,9 @@ Global StartDir:String
 
 Global profileName:String
 
-'Const TestArgs:="mx2cc makemods monkey"
+Const TestArgs:="mx2cc makemods monkey"
 
-'Const TestArgs:="mx2cc makemods"' -clean mojo"
-'Const TestArgs:="mx2cc makedocs std"
- 
-Const TestArgs:="mx2cc makeapp src/mx2cc/test.monkey2"
+'Const TestArgs:="mx2cc makeapp src/mx2cc/test.monkey2"
 
 Function Main()
 	
@@ -541,6 +538,8 @@ Function ParseOpts:String[]( opts:BuildOpts,args:String[] )
 			
 		opts.arch="llvm"
 		
+		opts.threads=False
+		
 	Case "android"
 		
 		opts.arch=GetEnv( "MX2_ANDROID_APP_ABI","armeabi-v7a" )