Esempio n. 1
0
        // Top left and top right threads' function (Add an offset):
        // ---------------------------------------------------------
        static uint TopThread(IntPtr ThreadParameters)
        {
            GCHandle     threadParamHandle = GCHandle.FromIntPtr(ThreadParameters);
            THREAD_PARAM TPar = threadParamHandle.Target as THREAD_PARAM;

            while (TPar.Exit == 0)
            {
                // Wait for bottom ready event before proceeding.
                MIL.MthrWait(TPar.ReadyEvent, MIL.M_EVENT_WAIT);

                // For better visual effect, reset SrcImage to the original image regularly.
                if ((TPar.NumberOfIteration % 192) == 0)
                {
                    MIL.MbufCopy(TPar.OrgImage, TPar.SrcImage);
                }

                if ((TPar.LicenseModules & MIL.M_LICENSE_IM) != 0)
                {
                    // Add a constant to the image.
                    MIL.MimArith(TPar.SrcImage, 1L, TPar.DstImage, MIL.M_ADD_CONST + MIL.M_SATURATION);
                }
                else
                {
                    // Under Mil lite draw a variable size rectangle in the image.
                    TPar.Radius = TPar.SlaveThreadParam.Radius = (TPar.NumberOfIteration % DRAW_RADIUS_NUMBER) * DRAW_RADIUS_STEP;
                    MIL.MgraColor(MIL.M_DEFAULT, 0xff);
                    MIL.MgraRectFill(MIL.M_DEFAULT, TPar.DstImage, DRAW_CENTER_POSX - TPar.Radius, DRAW_CENTER_POSY - TPar.Radius, DRAW_CENTER_POSX + TPar.Radius, DRAW_CENTER_POSY + TPar.Radius);
                }

                // Increment iteration count and draw text.
                TPar.NumberOfIteration++;
                MIL.MgraColor(MIL.M_DEFAULT, 0xFF);
                MIL.MgraText(MIL.M_DEFAULT, TPar.DstImage, STRING_POS_X, STRING_POS_Y, String.Format("{0}", TPar.NumberOfIteration));

                // Signal to the bottom thread that the first part of processing is completed.
                MIL.MthrControl(TPar.DoneEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);

                // For a smoother display effect, optional yield to the other threads.
                BalanceThreadScheduling();
            }

            // Require the bottom thread to exit.
            TPar.SlaveThreadParam.Exit = 1;

            // Signal the bottom thread end to wake up.
            MIL.MthrControl(TPar.DoneEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);

            // before exiting the thread, make sure all the commands are executed
            MIL.MthrWait(TPar.System, MIL.M_THREAD_WAIT, MIL.M_NULL);

            return(1);
        }
Esempio n. 2
0
        // Bottom-right thread function (Edge Detect):
        // -------------------------------------------
        static uint BotRightThread(IntPtr ThreadParameters)
        {
            GCHandle     threadParamHandle = GCHandle.FromIntPtr(ThreadParameters);
            THREAD_PARAM TPar = threadParamHandle.Target as THREAD_PARAM;

            while (TPar.Exit == 0)
            {
                // Wait for the event in top-right function to be ready before proceeding.
                MIL.MthrWait(TPar.ReadyEvent, MIL.M_EVENT_WAIT);

                // If processing available, add a constant to the image.
                if ((TPar.LicenseModules & MIL.M_LICENSE_IM) != 0)
                {
                    MIL.MimConvolve(TPar.SrcImage, TPar.DstImage, MIL.M_EDGE_DETECT);
                }
                else // else copy the top image and draw a filled circle.
                {
                    MIL.MbufCopy(TPar.SrcImage, TPar.DstImage);
                    MIL.MgraColor(MIL.M_DEFAULT, 0x40);
                    MIL.MgraArcFill(MIL.M_DEFAULT, TPar.DstImage, DRAW_CENTER_POSX, DRAW_CENTER_POSY, TPar.Radius / 2, TPar.Radius / 2, 0, 360);
                }

                // Increment iteration count and draw text.
                TPar.NumberOfIteration++;
                MIL.MgraColor(MIL.M_DEFAULT, 0xFF);
                MIL.MgraText(MIL.M_DEFAULT, TPar.DstImage, STRING_POS_X, STRING_POS_Y, String.Format("{0}", TPar.NumberOfIteration));

                // Signal to the top thread that the last part of the processing is completed.
                MIL.MthrControl(TPar.DoneEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);

                // For a smoother display effect, optional yield to the other threads.
                BalanceThreadScheduling();
            }

            // before exiting the thread, make sure all the commands are executed
            MIL.MthrWait(TPar.System, MIL.M_THREAD_WAIT, MIL.M_NULL);

            return(1);
        }
Esempio n. 3
0
        // Main function:
        // --------------
        static void Main(string[] args)
        {
            MIL_ID       MilApplication       = MIL.M_NULL;         // Application identifier.
            MIL_ID       MilRemoteApplication = MIL.M_NULL;         // Remote Application identifier if running on a remote computer
            MIL_ID       MilSystem            = MIL.M_NULL;         // System identifier.
            MIL_ID       MilDisplay           = MIL.M_NULL;         // Display identifier.
            MIL_ID       MilImage             = MIL.M_NULL;         // Image buffer identifiers.
            MIL_ID       MilOrgImage          = MIL.M_NULL;
            THREAD_PARAM TParTopLeft          = new THREAD_PARAM(); // Parameters passed to top left thread.
            THREAD_PARAM TParBotLeft          = new THREAD_PARAM(); // Parameters passed to bottom left thread.
            THREAD_PARAM TParTopRight         = new THREAD_PARAM(); // Parameters passed to top right thread.
            THREAD_PARAM TParBotRight         = new THREAD_PARAM(); // Parameters passed to bottom right thread.
            double       Time            = 0.0;                     // Timer variables.
            double       FramesPerSecond = 0.0;
            MIL_INT      LicenseModules  = 0;                       // List of available MIL modules.

            // Allocate defaults.
            MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL);

            // Allocate and display the main image buffer.
            MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilImage);
            MIL.MbufClear(MilImage, 0);
            MIL.MdispSelect(MilDisplay, MilImage);

            // Allocate an image buffer to keep the original.
            MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilOrgImage);

            // Allocate a destination child buffer for each thread.
            MIL.MbufChild2d(MilImage, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParTopLeft.SrcImage);
            MIL.MbufChild2d(MilImage, 0, IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParBotLeft.DstImage);
            MIL.MbufChild2d(MilImage, IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParTopRight.SrcImage);
            MIL.MbufChild2d(MilImage, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParBotRight.DstImage);

            // Allocate synchronization events.
            MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParTopLeft.DoneEvent);
            MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParBotLeft.DoneEvent);
            MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParTopRight.DoneEvent);
            MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParBotRight.DoneEvent);

            // Inquire MIL licenses.
            MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication);
            MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules);

            // Initialize remaining thread parameters.
            TParTopLeft.System            = MilSystem;
            TParTopLeft.OrgImage          = MilOrgImage;
            TParTopLeft.DstImage          = TParTopLeft.SrcImage;
            TParTopLeft.ReadyEvent        = TParBotLeft.DoneEvent;
            TParTopLeft.NumberOfIteration = 0;
            TParTopLeft.Radius            = 0;
            TParTopLeft.Exit             = 0;
            TParTopLeft.LicenseModules   = LicenseModules;
            TParTopLeft.SlaveThreadParam = TParBotLeft;

            TParBotLeft.System            = MilSystem;
            TParBotLeft.OrgImage          = 0;
            TParBotLeft.SrcImage          = TParTopLeft.DstImage;
            TParBotLeft.ReadyEvent        = TParTopLeft.DoneEvent;
            TParBotLeft.NumberOfIteration = 0;
            TParBotLeft.Radius            = 0;
            TParBotLeft.Exit             = 0;
            TParBotLeft.LicenseModules   = LicenseModules;
            TParBotLeft.SlaveThreadParam = null;

            TParTopRight.System            = MilSystem;
            TParTopRight.OrgImage          = MilOrgImage;
            TParTopRight.DstImage          = TParTopRight.SrcImage;
            TParTopRight.ReadyEvent        = TParBotRight.DoneEvent;
            TParTopRight.NumberOfIteration = 0;
            TParTopRight.Radius            = 0;
            TParTopRight.Exit             = 0;
            TParTopRight.LicenseModules   = LicenseModules;
            TParTopRight.SlaveThreadParam = TParBotRight;

            TParBotRight.System            = MilSystem;
            TParBotRight.OrgImage          = 0;
            TParBotRight.SrcImage          = TParTopRight.DstImage;
            TParBotRight.ReadyEvent        = TParTopRight.DoneEvent;
            TParBotRight.NumberOfIteration = 0;
            TParBotRight.Radius            = 0;
            TParBotRight.Exit             = 0;
            TParBotRight.LicenseModules   = LicenseModules;
            TParBotRight.SlaveThreadParam = null;

            // Initialize the original image to process.
            MIL.MbufLoad(IMAGE_FILE, MilOrgImage);

            // Start the 4 threads.
            MIL_THREAD_FUNCTION_PTR TopThreadDelegate      = new MIL_THREAD_FUNCTION_PTR(TopThread);
            MIL_THREAD_FUNCTION_PTR BotLeftThreadDelegate  = new MIL_THREAD_FUNCTION_PTR(BotLeftThread);
            MIL_THREAD_FUNCTION_PTR BotRightThreadDelegate = new MIL_THREAD_FUNCTION_PTR(BotRightThread);

            GCHandle TParTopLeftHandle  = GCHandle.Alloc(TParTopLeft);
            GCHandle TParBotLeftHandle  = GCHandle.Alloc(TParBotLeft);
            GCHandle TParTopRightHandle = GCHandle.Alloc(TParTopRight);
            GCHandle TParBotRightHandle = GCHandle.Alloc(TParBotRight);

            MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, TopThreadDelegate, GCHandle.ToIntPtr(TParTopLeftHandle), ref TParTopLeft.Id);
            MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, BotLeftThreadDelegate, GCHandle.ToIntPtr(TParBotLeftHandle), ref TParBotLeft.Id);
            MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, TopThreadDelegate, GCHandle.ToIntPtr(TParTopRightHandle), ref TParTopRight.Id);
            MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, BotRightThreadDelegate, GCHandle.ToIntPtr(TParBotRightHandle), ref TParBotRight.Id);

            // Start the timer.
            MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL);

            // Set events to start operation of top left and top right threads.
            MIL.MthrControl(TParTopLeft.ReadyEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);
            MIL.MthrControl(TParTopRight.ReadyEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);

            // Report that the threads are started and wait for a key press to stop them.
            Console.Write("\nMULTI-THREADING:\n");
            Console.Write("----------------\n\n");
            Console.Write("4 threads running...\n");
            Console.Write("Press <Enter> to stop.\n\n");
            Console.ReadKey();

            // Signal the threads to exit.
            TParTopLeft.Exit  = 1;
            TParTopRight.Exit = 1;

            // Wait for all threads to terminate.
            MIL.MthrWait(TParTopLeft.Id, MIL.M_THREAD_END_WAIT);
            MIL.MthrWait(TParBotLeft.Id, MIL.M_THREAD_END_WAIT);
            MIL.MthrWait(TParTopRight.Id, MIL.M_THREAD_END_WAIT);
            MIL.MthrWait(TParBotRight.Id, MIL.M_THREAD_END_WAIT);

            // Stop the timer and calculate the number of frames per second processed.
            MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time);
            FramesPerSecond = (TParTopLeft.NumberOfIteration + TParBotLeft.NumberOfIteration + TParTopRight.NumberOfIteration + TParBotRight.NumberOfIteration) / Time;

            // Print statistics.
            Console.Write("Top left iterations done:     {0,4}.\n", TParTopLeft.NumberOfIteration);
            Console.Write("Bottom left iterations done:  {0,4}.\n", TParBotLeft.NumberOfIteration);
            Console.Write("Top right iterations done:    {0,4}.\n", TParTopRight.NumberOfIteration);
            Console.Write("Bottom right iterations done: {0,4}.\n\n", TParBotRight.NumberOfIteration);
            Console.Write("Processing speed for the 4 threads: {0:0.0} Images/Sec.\n\n", FramesPerSecond);
            Console.Write("Press <Enter> to end.\n\n");
            Console.ReadKey();

            // Free threads.
            MIL.MthrFree(TParTopLeft.Id);
            MIL.MthrFree(TParBotLeft.Id);
            MIL.MthrFree(TParTopRight.Id);
            MIL.MthrFree(TParBotRight.Id);

            // Free events.
            MIL.MthrFree(TParTopLeft.DoneEvent);
            MIL.MthrFree(TParBotLeft.DoneEvent);
            MIL.MthrFree(TParTopRight.DoneEvent);
            MIL.MthrFree(TParBotRight.DoneEvent);

            // Free buffers.
            MIL.MbufFree(TParTopLeft.SrcImage);
            MIL.MbufFree(TParTopRight.SrcImage);
            MIL.MbufFree(TParBotLeft.DstImage);
            MIL.MbufFree(TParBotRight.DstImage);
            MIL.MbufFree(MilOrgImage);
            MIL.MbufFree(MilImage);

            // Free the GCHandles
            TParTopLeftHandle.Free();
            TParBotLeftHandle.Free();
            TParTopRightHandle.Free();
            TParBotRightHandle.Free();

            // Free defaults.
            MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL);
        }