Esempio n. 1
0
        public void ThreadLock_SpeedTest()
        {
            UT_INIT();

            Log.SetVerbosity(new ConsoleLogger(), Verbosity.Verbose, "/");
            Log.MapThreadName("UnitTest");
            Log.SetDomain("TestTLock", Scope.Method);

            ThreadLock aLock = new ThreadLock();

            int repeats  = 100000;
            int rrepeats = 5;

            Ticks stopwatch = new Ticks();

            for (int r = 0; r < rrepeats; r++)
            {
                Log.Info("Run " + rrepeats);

                aLock.SetSafeness(Safeness.Unsafe);
                stopwatch.Set();
                for (int i = 0; i < repeats; i++)
                {
                    aLock.Acquire();
                    aLock.Release();
                }
                long time = stopwatch.Age().InMillis();
                Log.Info("Safe mode, " + repeats + " lock/unlock ops: " + time + " ms");

                aLock.SetSafeness(Safeness.Safe);
                stopwatch.Set();
                for (int i = 0; i < repeats; i++)
                {
                    //aLock.acquire();
                    //aLock.release();

                    // in java, adding the following two loops, results in similar execution speed
                    for (int tt = 0; tt < 70; tt++)
                    {
                        i += tt;
                    }
                    for (int tt = 0; tt < 70; tt++)
                    {
                        i -= tt;
                    }
                }
                time = stopwatch.Age().InMillis();
                Log.Info("Unsafe mode, " + repeats + " lock/unlock ops: " + time + " ms");
            }
        }
        void PerformanceTestRL()
        {
            // create a lox for release logging
            Lox          lox       = new Lox("ReleaseLox");
            TextLogger   relLogger = Lox.CreateConsoleLogger();
            MemoryLogger ml        = new MemoryLogger();


            lox.SetVerbosity(relLogger, Verbosity.Verbose, "/CON");
            lox.SetVerbosity(ml, Verbosity.Verbose, "/MEM");


            lox.Info("/CON", "Logging simple info lines into a memory logger");

            AString msgBuf   = new AString( );
            long    fastest  = long.MaxValue;
            Ticks   timer    = new Ticks();
            int     qtyLines = 1000;
            int     qtyLoops = 2000; //1000

            if (System.Diagnostics.Debugger.IsAttached)
            {
                qtyLines = qtyLoops = 10;
            }

            for (int i = 0; i < qtyLoops; i++)
            {
            #if ALOX_DBG_LOG || ALOX_REL_LOG
                ml.MemoryLog.Clear();
            #endif

                timer.Set();
                for (int ii = 0; ii < qtyLines; ii++)
                {
                    lox.Info("/MEM", "Test Line");
                    if (i == 0 && ii == 0)
                    {
                        Console.WriteLine(ml.MemoryLog.ToString());
                    }
                }
                long t = timer.Age().Raw();

                if (fastest > t)
                {
                    fastest = t;
                    lox.Info("/CON", msgBuf.Clear()._("Pass ")._(i, 3)._(" is new fastest:  ")
                             ._((int)(new Ticks(fastest)).InMicros(), 0)
                             ._(" micros per ")._(qtyLines)._(" logs."));
                }
            }

            double microsPerLog  = ((double)(new Ticks(fastest)).InMicros()) / qtyLines;
            int    logsPerSecond = (int)(1000000.0 / microsPerLog);
            lox.Info("/CON", msgBuf._()._("  ")._(ESC.MAGENTA)._("Fastest Release Logging: ")
                     ._(microsPerLog)._(" micros per log (resp ")
                     ._(logsPerSecond)._(" logs per second) "));

            lox.RemoveLogger(ml);
            lox.RemoveLogger(relLogger);
        }
Esempio n. 3
0
        public void SpeedTest()
        {
            UT_INIT();

            Log.SetVerbosity(new ConsoleLogger(), Verbosity.Verbose, "/");
            Log.MapThreadName("UnitTest");
            Log.SetDomain("TickWatch", Scope.Method);

            Log.Info("\n### TicksSpeedTest ###");
            for (int runs = 0; runs < 5; runs++)
            {
                int   aLotOf    = 100;
                Ticks t         = new Ticks();
                Ticks tkMeasure = new Ticks();
                for (int i = 0; i < aLotOf; i++)
                {
                    t.Set();
                }

                long nanos        = tkMeasure.Age().InNanos();
                long averageNanos = nanos / aLotOf;
                Log.Info("Doing " + aLotOf + " Ticks.Set() calls took " + nanos + " ns. This is an average of " + averageNanos + " nanoseconds per call");
                UT_TRUE(averageNanos < 20000);    // this is much slower on Windows than on mono/linux.
            }
        }
Esempio n. 4
0
        // #############################################################################################
        // Interface
        // #############################################################################################


        /** ********************************************************************************************
         *  Thread which invokes this method gets registered  as the current owner of this object, until the
         *  same thread releases the ownership invoking Release().
         *  In the case that this object is already owned by another thread, the invoking thread is suspended
         *  until ownership can be gained.
         *  Multiple (nested) calls to this method are counted and the object is only released when the same
         *  number of Release() calls have been made.
         *
         * @param cln (Optional) Caller info, compiler generated. Please omit.
         * @param csf (Optional) Caller info, compiler generated. Please omit.
         * @param cmn (Optional) Caller info, compiler generated. Please omit.
         **********************************************************************************************/
        public void Acquire(
            [CallerLineNumber] int cln = 0, [CallerFilePath] String csf = "", [CallerMemberName] String cmn = "")

        {
            // are we in unsafe mode?
            if (mutex == null)
            {
                // we are still increasing the lockCount
                lockCount = lockMode == LockMode.Recursive ? lockCount + 1
                                                       : 1;

                // reached warning limit
                if (lockCount <= 0)
                {
                    ALIB.ERROR("Unsafe mode: Counter invalid (<= 0): This should never happen. Set lock to safe mode!");
                }

                else if (lockCount % RecursionWarningThreshold == 0)
                {
                    ALIB.WARNING("Recursion depth " + lockCount + ". To prevent this, change ThreadSafe.recursionWarningThreshold or fix your code!");
                }

                // end of unsafe version of this method
                return;
            }

            // get current thread
            Thread thisThread = Thread.CurrentThread;

            // synchronize on mutex
            lock ( mutex )
            {
                // we already own the thread
                if (owner == thisThread)
                {
                    // we are still increasing the lockCount
                    lockCount = lockMode == LockMode.Recursive ? lockCount + 1
                                                           : 1;
                    // reached warning limit
                    if (lockCount % RecursionWarningThreshold == 0)
                    {
                        ALIB.WARNING("Recursion depth " + lockCount + ". To prevent this, change ThreadSafe.recursionWarningThreshold or fix your code!");
                    }

                    return;
                }

                // we do not own this thread, wait until lock is free
                bool hasWarned = false;
                while (owner != null)
                {
                    try
                    {
                        // wait unconditional
                        if (waitWarningTimeLimitInMillis <= 0 || hasWarned)
                        {
                            Monitor.Wait(mutex);
                        }

                        // wait with time limit
                        else
                        {
                            waitTime.Set();
                            Monitor.Wait(mutex, waitWarningTimeLimitInMillis);
                            long time = waitTime.Age().InMillis();
                            if (time >= waitWarningTimeLimitInMillis)
                            {
                                hasWarned = true;
                                ALIB.WARNING("Timeout (" + waitWarningTimeLimitInMillis
                                             + " ms). Change your codes critical section length if possible." + CString.NewLineChars
                                             + "This thread: " + thisThread.ManagedThreadId + "/" + thisThread.Name + CString.NewLineChars
                                             + "Owning thread: " + (owner != null ? (owner.ManagedThreadId + "/" + owner.Name) : "null")
                                    #if DEBUG
                                             + CString.NewLineChars
                                             + "Location of acquirement: " + acquirementSourcefile + ":" + acquirementLineNumber + " " + acquirementMethodName + "()"
                                    #endif
                                             );
                            }
                        }
                    }
                    catch (Exception) {} // ignore spurious wakeups
                }

                // take control
                owner = thisThread;
            #if DEBUG
                acquirementLineNumber = cln;
                acquirementSourcefile = csf;
                acquirementMethodName = cmn;
            #endif

                lockCount = 1;
            } // synchronized
        }