public bool Run()
        {
            // start all threads
            _threads.ForEach(t => t.Start());

            // wait for all threads to get ready
            while (_taskReadyCount != _threads.Count) // atomic read, hence not using Interlocked
            {
                System.Threading.Thread.Sleep(10);
            }

            SmashStopwatch sw = new SmashStopwatch(TotalIterations);

            // fire the event
            _startEvent.Set();

            // Wait for all threads to complete
            _threads.ForEach(t => t.Join());

            sw.Done();

            _result = sw.ToString();

            TotalProcessed = _threadResults.Values.Sum(t => t.SuccessfulIterations);
            SmashAssert.AreEqual(TotalIterations, TotalProcessed);

            return(TotalIterations == TotalProcessed);
        }
        private void DoWork(SmashContext tparam)
        {
            System.Threading.ManualResetEvent startEvent = tparam.StartEvent;
            System.Threading.Interlocked.Increment(ref _taskReadyCount);
            if (!startEvent.WaitOne())
            {
                throw new SmashException(string.Format("Thread #{0} fail to start", tparam.ThreadNo));
            }

            SmashStopwatch swTask = new SmashStopwatch(tparam.NumIterations);

            SmashResult result = new SmashResult();

            result.SuccessfulIterations = 0;
            for (int i = 0; i < tparam.NumIterations; ++i)
            {
                if (tparam.SmashFunc(tparam.ThreadNo, i))
                {
                    result.SuccessfulIterations++;
                }
            }
            swTask.Done();

            SmashAssert.AreEqual(tparam.NumIterations, result.SuccessfulIterations);
            result.TimeTaken  = swTask.Elapsed;
            result.RatePerSec = swTask.RatePerSec;

            tparam.Manager.SubmitResult(tparam.ThreadNo, result);
        }