using System; using System.Windows.Forms; using System.Drawing; using System.Drawing.Imaging; using System.Data; using MCSharp; using System.Threading; using System.Runtime.Serialization; using System.Runtime.Remoting.Messaging; [Serializable()] class Mandelbrot : ISerializable { //-------------- MC# functions ----------- public Mandelbrot() { _mcs_initiate(); } public Mandelbrot( SerializationInfo info, StreamingContext context ) { MCSharp.Serialization.UnPack( info, context, this ); } public void GetObjectData( SerializationInfo info, StreamingContext context ) { MCSharp.Serialization.Pack( info, context, this ); } private void _mcs_initiate() { Monitor.Enter( CommExec.Objects ); int _mcs_ObjectNumber = CommExec.Objects.Count + 1; CommExec.Objects.Add( _mcs_ObjectNumber, this ); Monitor.Exit( CommExec.Objects ); bc1 = new Channel( this, _mcs_ObjectNumber, "_mcs_Channelbc1" ); bc2 = new Channel( this, _mcs_ObjectNumber, "_mcs_Channelbc2" ); _mcs_QueueGet = new MCSharp.ThreadQ(); } public void Calculate( double x1, double y1, double x2, double y2, int cx, int cy, double deltaY, int numberOfPiece, Channel c, Channel channelToTop ) { MCSharp.TCP.DeliverMovableMethod( this, "_mcs_Calculate", new object[] { x1, y1, x2, y2, cx, cy, deltaY, numberOfPiece, c, channelToTop } ); } public void _mcs_Calculate( double x1, double y1, double x2, double y2, int cx, int cy, double deltaY, int numberOfPiece, Channel c, Channel channelToTop ) { if ( y2 - y1 < deltaY ) c.Send( InternalCalculate( x1 , y1 , x2 , y2 , cx , cy , numberOfPiece , channelToTop ) ) ; else { Calculate( x1 , y1 , x2 , y1 + ( y2 - y1 ) / 2 , cx , cy , deltaY , numberOfPiece * 2 - 1 , bc1 , channelToTop ) ; Calculate( x1 , y1 + ( y2 - y1 ) / 2 , x2 , y2 , cx , cy , deltaY , numberOfPiece * 2 , bc2 , channelToTop ) ; c.Send( Get( ) ) ; } } //-------------Channel declarations----------------- public MCSharp.Channel bc1; public MCSharp.Channel bc2; //-------------Queues------------------------------ [NonSerialized] private MCSharp.ThreadQ _mcs_QueueGet; //-------------Masks-------------------------------- private const int _mcs_mask_Get = 1 << 0; private const int _mcs_mask_bc1 = 1 << 1; private const int _mcs_mask_bc2 = 1 << 2; private const int _mcs_mask_Getbc1bc2 = _mcs_mask_Get | _mcs_mask_bc1 | _mcs_mask_bc2; [NonSerialized] private MCSharp.BitMask _mcs_BitMaskGetbc1bc2 = new MCSharp.BitMask(); private void _mcs_scanGetbc1bc2() { if ( _mcs_BitMaskGetbc1bc2.match( _mcs_mask_Getbc1bc2 ) ) _mcs_QueueGet.wakeup(); } [OneWay] public void _mcs_Channelbc1( Bitmap x ) { lock ( _mcs_QueueGet ) { bc1.Enqueue( new object[] { x } ); if ( !_mcs_BitMaskGetbc1bc2.match( _mcs_mask_bc1 ) ) { _mcs_BitMaskGetbc1bc2.set( _mcs_mask_bc1 ); _mcs_scanGetbc1bc2(); } } } [OneWay] public void _mcs_Channelbc2( Bitmap y ) { lock ( _mcs_QueueGet ) { bc2.Enqueue( new object[] { y } ); if ( !_mcs_BitMaskGetbc1bc2.match( _mcs_mask_bc2 ) ) { _mcs_BitMaskGetbc1bc2.set( _mcs_mask_bc2 ); _mcs_scanGetbc1bc2(); } } } public Bitmap Get ( ) { Monitor.Enter( _mcs_QueueGet ); if ( !_mcs_BitMaskGetbc1bc2.match( _mcs_mask_Get ) ) goto now; later: _mcs_QueueGet.yield( _mcs_QueueGet ); if ( _mcs_QueueGet.empty ) _mcs_BitMaskGetbc1bc2.clear( _mcs_mask_Get ); now: if ( _mcs_BitMaskGetbc1bc2.match( _mcs_mask_bc1 | _mcs_mask_bc2 ) ) { object[] obc1 = (object[]) bc1.Dequeue(); Bitmap x = (Bitmap) obc1 [0]; if ( bc1.Count == 0 ) _mcs_BitMaskGetbc1bc2.clear( _mcs_mask_bc1 ); object[] obc2 = (object[]) bc2.Dequeue(); Bitmap y = (Bitmap) obc2 [0]; if ( bc2.Count == 0 ) _mcs_BitMaskGetbc1bc2.clear( _mcs_mask_bc2 ); _mcs_scanGetbc1bc2(); Monitor.Exit( _mcs_QueueGet ); { Bitmap bmp = new Bitmap( x.Width , x.Height + y.Height ) ; Graphics g = Graphics.FromImage( bmp ) ; g.DrawImage( x , 0 , 0 ) ; g.DrawImage( y , 0 , x.Height ) ; return bmp ; } } else { _mcs_BitMaskGetbc1bc2.set( _mcs_mask_Get ); goto later; } } private Bitmap InternalCalculate ( double x1, double y1, double x2, double y2, int cx, int cy, int numberOfPiece, Channel channelToTop ) { const int m_iLimit = 255 ; double dAddx = ( x2 - x1 ) / ( (double)cx ) ; double dAddy = ( y2 - y1 ) / ( (double)cy ) ; Bitmap outBmp = new Bitmap( cx , cy ) ; for ( int i = 0 ; i < cy ; i++ ) { double dCr = x1 ; for ( int j = 0 ; j < cx ; j++ ) { int c = 0 ; double dZr = 0.0 , dZi = 0.0 , dZiSqr = 0.0 , dZrSqr = 0.0 , dZr1 ; while ( c < m_iLimit && dZiSqr + dZrSqr < 4 ) { dZr1 = dZrSqr - dZiSqr + dCr ; dZi = 2 * dZr * dZi + y1 ; dZr = dZr1 ; dZiSqr = dZi * dZi ; dZrSqr = dZr * dZr ; ++c ; } if ( c >= m_iLimit ) outBmp.SetPixel( j , i , GetColor( 0 ) ) ; else outBmp.SetPixel( j , i , GetColor( c ) ) ; dCr += dAddx ; } y1 += dAddy ; } channelToTop.Send( outBmp , numberOfPiece ) ; return outBmp ; } [ NonSerialized ]Color[] colors = { Color.Black , Color.AntiqueWhite , Color.Aqua , Color.Aquamarine , Color.Azure , Color.Beige , Color.Bisque , Color.Black , Color.BlanchedAlmond , Color.Blue , Color.BlueViolet , Color.Brown , Color.BurlyWood , Color.CadetBlue , Color.Chartreuse , Color.Chocolate , Color.Coral , Color.CornflowerBlue , Color.Cornsilk , Color.Crimson , Color.Cyan , Color.DarkBlue , Color.DarkCyan , Color.DarkGoldenrod , Color.DarkGray , Color.DarkGreen , Color.DarkKhaki , Color.DarkMagenta , Color.DarkOliveGreen , Color.DarkOrange , Color.DarkOrchid , Color.DarkRed , Color.DarkSalmon , Color.DarkSeaGreen , Color.DarkSlateBlue , Color.DarkSlateGray , Color.DarkTurquoise , Color.DarkViolet , Color.DeepPink , Color.DeepSkyBlue , Color.DimGray , Color.DodgerBlue , Color.DodgerBlue , Color.Firebrick , Color.FloralWhite } ; private Color GetColor ( int code ) { return colors[ code % 45 ] ; } } [Serializable()] class ComputeMandelbrotForm:System.Windows.Forms.Form, ISerializable { //-------------- MC# functions ----------- public ComputeMandelbrotForm() { _mcs_initiate(); } public ComputeMandelbrotForm( SerializationInfo info, StreamingContext context ) { MCSharp.Serialization.UnPack( info, context, this ); } public void GetObjectData( SerializationInfo info, StreamingContext context ) { MCSharp.Serialization.Pack( info, context, this ); } private void _mcs_initiate() { Monitor.Enter( CommExec.Objects ); int _mcs_ObjectNumber = CommExec.Objects.Count + 1; CommExec.Objects.Add( _mcs_ObjectNumber, this ); Monitor.Exit( CommExec.Objects ); c = new Channel( this, _mcs_ObjectNumber, "_mcs_Channelc" ); _mcs_QueueGet = new MCSharp.ThreadQ(); c2 = new Channel( this, _mcs_ObjectNumber, "_mcs_Channelc2" ); _mcs_QueueGetBitmapAndFragmentNumber = new MCSharp.ThreadQ(); } Bitmap[] computedBmps ; int[] computedBmpsNumbers ; int currentComputedBitmap ; int totalNumberOfBmps ; Graphics g ; Thread repainterThread ; Thread receiverThread ; Thread receiverThread2 ; public ComputeMandelbrotForm ( string[] args ) { _mcs_initiate(); this.AutoScroll = true ; this.ClientSize = new System.Drawing.Size( 4000 , 4000 ) ; this.DockPadding.All = 4000 ; this.WindowState = System.Windows.Forms.FormWindowState.Maximized ; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show ; this.Name = "Mandelbrot set demo" ; this.Text = "Mandelbrot set demo" ; this.TransparencyKey = System.Drawing.Color.Green ; Label l = new Label( ) ; l.Size = new System.Drawing.Size( 0 , 0 ) ; this.Controls.AddRange( new System.Windows.Forms.Control[ ]{ l } ) ; g = this.CreateGraphics( ) ; double x1 = System.Convert.ToDouble( args[ 0 ] ) ; double y1 = System.Convert.ToDouble( args[ 1 ] ) ; double x2 = System.Convert.ToDouble( args[ 2 ] ) ; double y2 = System.Convert.ToDouble( args[ 3 ] ) ; int cx = System.Convert.ToInt32( args[ 4 ] ) ; int cy = System.Convert.ToInt32( args[ 5 ] ) ; double deltaY = System.Convert.ToDouble( args[ 6 ] ) ; totalNumberOfBmps = (int)( ( y2 - y1 ) / deltaY ) + 30 ; Mandelbrot m = new Mandelbrot( ) ; computedBmps = new Bitmap[ totalNumberOfBmps ] ; computedBmpsNumbers = new int[ totalNumberOfBmps ] ; m.Calculate( x1 , y1 , x2 , y2 , cx , cy , deltaY , 1 , c , c2 ) ; repainterThread = new Thread( new ThreadStart( DynamicRepainter ) ) ; repainterThread.Start( ) ; receiverThread = new Thread( new ThreadStart( Receiver ) ) ; receiverThread.Start( ) ; receiverThread2 = new Thread( new ThreadStart( Receiver2 ) ) ; receiverThread2.Start( ) ; this.ResumeLayout( false ) ; } public static void Usage ( ) { Console.WriteLine( "Usage: ComputeMandelbrotForm.exe x1 y2 x2 y2 cx cy deltaY" ) ; Console.WriteLine( "where" ) ; Console.WriteLine( " (x1, y1) - left bottom corner of fractal" ) ; Console.WriteLine( " (x2, y2) - right top corner of fractal" ) ; Console.WriteLine( " (cx, cy) - width and height of each fragment" ) ; Console.WriteLine( " deltaY - step of fragmentation" ) ; Console.WriteLine( ) ; Console.WriteLine( "For example:" ) ; Console.WriteLine( " ComputeMandelbrotForm.exe " + -1.5 + " " + -1.5 + " " + 1.5 + " " + 1.5 + " 1000 100 " + 0.3 ) ; Console.WriteLine( " ComputeMandelbrotForm.exe " + 0.30 + " " + -0.05 + " " + 0.35 + " " + -0.0005 + " 1000 10 " + 0.000495 ) ; } public static void Main( string[] args ) { if ( !MCSharp.Session.Init( args ) ) return; _mcs_Main_Wrapper( args ); MCSharp.Session.FinalizeIt(); } private static void _mcs_Main_Wrapper( string[] args ) { if ( args.Length >= 7 ) { Application.Run( new ComputeMandelbrotForm( args ) ) ; } else { Usage( ) ; Console.WriteLine( args.Length ) ; } } //-------------Channel declarations----------------- public MCSharp.Channel c; //-------------Queues------------------------------ [NonSerialized] private MCSharp.ThreadQ _mcs_QueueGet; //-------------Masks-------------------------------- private const int _mcs_mask_Get = 1 << 0; private const int _mcs_mask_c = 1 << 1; private const int _mcs_mask_Getc = _mcs_mask_Get | _mcs_mask_c; [NonSerialized] private MCSharp.BitMask _mcs_BitMaskGetc = new MCSharp.BitMask(); private void _mcs_scanGetc() { if ( _mcs_BitMaskGetc.match( _mcs_mask_Getc ) ) _mcs_QueueGet.wakeup(); } [OneWay] public void _mcs_Channelc( Bitmap bmp ) { lock ( _mcs_QueueGet ) { c.Enqueue( new object[] { bmp } ); if ( !_mcs_BitMaskGetc.match( _mcs_mask_c ) ) { _mcs_BitMaskGetc.set( _mcs_mask_c ); _mcs_scanGetc(); } } } public Bitmap Get ( ) { Monitor.Enter( _mcs_QueueGet ); if ( !_mcs_BitMaskGetc.match( _mcs_mask_Get ) ) goto now; later: _mcs_QueueGet.yield( _mcs_QueueGet ); if ( _mcs_QueueGet.empty ) _mcs_BitMaskGetc.clear( _mcs_mask_Get ); now: if ( _mcs_BitMaskGetc.match( _mcs_mask_c ) ) { object[] oc = (object[]) c.Dequeue(); Bitmap bmp = (Bitmap) oc [0]; if ( c.Count == 0 ) _mcs_BitMaskGetc.clear( _mcs_mask_c ); _mcs_scanGetc(); Monitor.Exit( _mcs_QueueGet ); { return bmp ; } } else { _mcs_BitMaskGetc.set( _mcs_mask_Get ); goto later; } } //-------------Channel declarations----------------- public MCSharp.Channel c2; //-------------Queues------------------------------ [NonSerialized] private MCSharp.ThreadQ _mcs_QueueGetBitmapAndFragmentNumber; //-------------Masks-------------------------------- private const int _mcs_mask_GetBitmapAndFragmentNumber = 1 << 0; private const int _mcs_mask_c2 = 1 << 1; private const int _mcs_mask_GetBitmapAndFragmentNumberc2 = _mcs_mask_GetBitmapAndFragmentNumber | _mcs_mask_c2; [NonSerialized] private MCSharp.BitMask _mcs_BitMaskGetBitmapAndFragmentNumberc2 = new MCSharp.BitMask(); private void _mcs_scanGetBitmapAndFragmentNumberc2() { if ( _mcs_BitMaskGetBitmapAndFragmentNumberc2.match( _mcs_mask_GetBitmapAndFragmentNumberc2 ) ) _mcs_QueueGetBitmapAndFragmentNumber.wakeup(); } [OneWay] public void _mcs_Channelc2( Bitmap bmp, int numberOfPiece ) { lock ( _mcs_QueueGetBitmapAndFragmentNumber ) { c2.Enqueue( new object[] { bmp, numberOfPiece } ); if ( !_mcs_BitMaskGetBitmapAndFragmentNumberc2.match( _mcs_mask_c2 ) ) { _mcs_BitMaskGetBitmapAndFragmentNumberc2.set( _mcs_mask_c2 ); _mcs_scanGetBitmapAndFragmentNumberc2(); } } } public void GetBitmapAndFragmentNumber ( ) { Monitor.Enter( _mcs_QueueGetBitmapAndFragmentNumber ); if ( !_mcs_BitMaskGetBitmapAndFragmentNumberc2.match( _mcs_mask_GetBitmapAndFragmentNumber ) ) goto now; later: _mcs_QueueGetBitmapAndFragmentNumber.yield( _mcs_QueueGetBitmapAndFragmentNumber ); if ( _mcs_QueueGetBitmapAndFragmentNumber.empty ) _mcs_BitMaskGetBitmapAndFragmentNumberc2.clear( _mcs_mask_GetBitmapAndFragmentNumber ); now: if ( _mcs_BitMaskGetBitmapAndFragmentNumberc2.match( _mcs_mask_c2 ) ) { object[] oc2 = (object[]) c2.Dequeue(); Bitmap bmp = (Bitmap) oc2 [0]; int numberOfPiece = (int) oc2 [1]; if ( c2.Count == 0 ) _mcs_BitMaskGetBitmapAndFragmentNumberc2.clear( _mcs_mask_c2 ); _mcs_scanGetBitmapAndFragmentNumberc2(); Monitor.Exit( _mcs_QueueGetBitmapAndFragmentNumber ); { computedBmps[ currentComputedBitmap ] = bmp ; computedBmpsNumbers[ currentComputedBitmap ] = numberOfPiece ; currentComputedBitmap++ ; } } else { _mcs_BitMaskGetBitmapAndFragmentNumberc2.set( _mcs_mask_GetBitmapAndFragmentNumber ); goto later; } } public void Receiver ( ) { for ( int i = 0 ; i < totalNumberOfBmps ; i++ ) { GetBitmapAndFragmentNumber( ) ; } } public void Receiver2 ( ) { Get( ).Save( "result.jpeg" , ImageFormat.Jpeg ) ; Console.WriteLine( "Result has been saved to file result.jpeg!" ) ; } private void Repaint ( ) { Monitor.Enter( g ) ; for ( int i = 0 ; i < currentComputedBitmap ; i++ ) { Monitor.Enter( computedBmps[ i ] ) ; g.DrawImage( computedBmps[ i ] , this.AutoScrollPosition.X , ( computedBmpsNumbers[ i ] - 1 ) * computedBmps[ i ].Height + this.AutoScrollPosition.Y ) ; Monitor.Exit( computedBmps[ i ] ) ; } Monitor.Exit( g ) ; } private void DynamicRepainter ( ) { while ( true ) { Repaint( ) ; Thread.Sleep( 100 ) ; } } protected override void OnPaint ( PaintEventArgs e ) { Repaint( ) ; } protected override void OnClosed ( EventArgs e ) { if ( repainterThread != null ) repainterThread.Abort( ) ; if ( receiverThread != null ) receiverThread.Abort( ) ; if ( receiverThread2 != null ) receiverThread2.Abort( ) ; } }