├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── Disruptor.PerfTests ├── CMakeLists.txt ├── EventCountingQueueProcessor.cpp ├── EventCountingQueueProcessor.h ├── EventCountingWorkHandler.cpp ├── EventCountingWorkHandler.h ├── ExecutorService.h ├── FizzBuzzEvent.cpp ├── FizzBuzzEvent.h ├── FizzBuzzEventHandler.cpp ├── FizzBuzzEventHandler.h ├── FizzBuzzStep.h ├── FunctionEvent.cpp ├── FunctionEvent.h ├── FunctionEventHandler.cpp ├── FunctionEventHandler.h ├── FunctionStep.h ├── ILatencyTest.h ├── IThroughputTest.h ├── LatencyTestSession.cpp ├── LatencyTestSession.h ├── LatencyTestSessionResult.cpp ├── LatencyTestSessionResult.h ├── LongArrayEventHandler.cpp ├── LongArrayEventHandler.h ├── MultiBufferBatchEventProcessor.h ├── MutableLong.cpp ├── MutableLong.h ├── OneToOneRawBatchThroughputTest.cpp ├── OneToOneRawBatchThroughputTest.h ├── OneToOneRawThroughputTest.cpp ├── OneToOneRawThroughputTest.h ├── OneToOneSequencedBatchThroughputTest.cpp ├── OneToOneSequencedBatchThroughputTest.h ├── OneToOneSequencedLongArrayThroughputTest.cpp ├── OneToOneSequencedLongArrayThroughputTest.h ├── OneToOneSequencedPollerThroughputTest.cpp ├── OneToOneSequencedPollerThroughputTest.h ├── OneToOneSequencedThroughputTest.cpp ├── OneToOneSequencedThroughputTest.h ├── OneToOneTranslatorThroughputTest.cpp ├── OneToOneTranslatorThroughputTest.h ├── OneToThreeDiamondSequencedThroughputTest.cpp ├── OneToThreeDiamondSequencedThroughputTest.h ├── OneToThreePipelineSequencedThroughputTest.cpp ├── OneToThreePipelineSequencedThroughputTest.h ├── OneToThreeReleasingWorkerPoolThroughputTest.cpp ├── OneToThreeReleasingWorkerPoolThroughputTest.h ├── OneToThreeSequencedThroughputTest.cpp ├── OneToThreeSequencedThroughputTest.h ├── OneToThreeWorkerPoolThroughputTest.cpp ├── OneToThreeWorkerPoolThroughputTest.h ├── Operation.cpp ├── Operation.h ├── PaddedLong.h ├── PerfTestUtil.cpp ├── PerfTestUtil.h ├── PingPongSequencedLatencyTest.cpp ├── PingPongSequencedLatencyTest.h ├── TestFactory.h ├── TestRepository.cpp ├── TestRepository.h ├── ThreeToOneSequencedBatchThroughputTest.cpp ├── ThreeToOneSequencedBatchThroughputTest.h ├── ThreeToOneSequencedThroughputTest.cpp ├── ThreeToOneSequencedThroughputTest.h ├── ThreeToThreeSequencedThroughputTest.cpp ├── ThreeToThreeSequencedThroughputTest.h ├── ThroughputTestSession.cpp ├── ThroughputTestSession.h ├── ThroughputTestSessionResult.cpp ├── ThroughputTestSessionResult.h ├── TwoToTwoWorkProcessorThroughputTest.cpp ├── TwoToTwoWorkProcessorThroughputTest.h ├── ValueAdditionEventHandler.cpp ├── ValueAdditionEventHandler.h ├── ValueEvent.cpp ├── ValueEvent.h ├── ValueMutationEventHandler.cpp ├── ValueMutationEventHandler.h ├── main.cpp ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── Disruptor.TestTools ├── CMakeLists.txt ├── CountdownEvent.cpp ├── CountdownEvent.h ├── DurationHumanizer.h ├── DurationUnit.h ├── HumanNumberFacet.h ├── LatencyRecorder.cpp ├── LatencyRecorder.h ├── ManualResetEvent.cpp ├── ManualResetEvent.h ├── ResetEvent.cpp ├── ResetEvent.h ├── ScopeExitFunctor.cpp ├── ScopeExitFunctor.h ├── Stopwatch.cpp ├── Stopwatch.h ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── Disruptor.Tests ├── AggregateEventHandlerTests.cpp ├── AggregateEventHandlerTestsFixture.cpp ├── AggregateEventHandlerTestsFixture.h ├── AtomicReference.h ├── BatchEventProcessorTests.cpp ├── BatchEventProcessorTestsFixture.cpp ├── BatchEventProcessorTestsFixture.h ├── BatchHandlerMock.h ├── BatchingTests.cpp ├── BusySpinWaitStrategyTests.cpp ├── CMakeLists.txt ├── ConsumerRepositoryTests.cpp ├── ConsumerRepositoryTestsFixture.cpp ├── ConsumerRepositoryTestsFixture.h ├── DataProviderMock.h ├── DelayedEventHandler.cpp ├── DelayedEventHandler.h ├── DisruptorFixture.cpp ├── DisruptorFixture.h ├── DisruptorStressTest.cpp ├── DisruptorTests.cpp ├── DummySequenceBarrier.cpp ├── DummySequenceBarrier.h ├── EventHandlerStub.h ├── EventPollerTests.cpp ├── EventProcessorMock.h ├── EventPublisherTests.cpp ├── ExceptionHandlerMock.h ├── ExceptionThrowingEventHandler.cpp ├── ExceptionThrowingEventHandler.h ├── FatalExceptionHandlerTests.cpp ├── FixedSequenceGroupTest.cpp ├── IgnoreExceptionHandlerTests.cpp ├── LifecycleAwareEventHandlerMock.h ├── LifecycleAwareTests.cpp ├── LongEvent.h ├── MultiProducerSequencerTests.cpp ├── RingBufferTests.cpp ├── RingBufferTestsFixture.cpp ├── RingBufferTestsFixture.h ├── RingBufferWithMocksTest.cpp ├── SequenceBarrierMock.h ├── SequenceBarrierTests.cpp ├── SequenceBarrierTestsFixture.cpp ├── SequenceBarrierTestsFixture.h ├── SequenceReportingCallbackTests.cpp ├── SequenceUpdater.cpp ├── SequenceUpdater.h ├── SequencerFixture.h ├── SequencerMock.h ├── SequencerTests.cpp ├── SleepingEventHandler.cpp ├── SleepingEventHandler.h ├── SleepingWaitStrategyTests.cpp ├── SpinWaitWaitStrategyTests.cpp ├── StubEvent.cpp ├── StubEvent.h ├── StubExceptionHandler.h ├── StubExecutor.cpp ├── StubExecutor.h ├── StubPublisher.cpp ├── StubPublisher.h ├── TestEvent.h ├── TestWaiter.cpp ├── TestWaiter.h ├── TestWorkHandler.cpp ├── TestWorkHandler.h ├── TimeoutBlockingWaitStrategyTests.cpp ├── UtilTests.cpp ├── WaitStrategyMock.h ├── WaitStrategyTestUtil.cpp ├── WaitStrategyTestUtil.h ├── WorkerPoolTests.cpp ├── YieldingWaitStrategyTests.cpp ├── main.cpp ├── postbuild.bat ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── Disruptor.cmake ├── Disruptor ├── AggregateEventHandler.h ├── AlertException.h ├── ArgumentException.h ├── ArgumentNullException.h ├── ArgumentOutOfRangeException.h ├── BasicExecutor.cpp ├── BasicExecutor.h ├── BatchEventProcessor.h ├── BlockingQueue.h ├── BlockingWaitStrategy.cpp ├── BlockingWaitStrategy.h ├── BuildConfig.h ├── BusySpinWaitStrategy.cpp ├── BusySpinWaitStrategy.h ├── CMakeLists.txt ├── ClockConfig.h ├── ConsumerRepository.h ├── Disruptor.h ├── EventHandlerGroup.h ├── EventPoller.h ├── EventProcessorInfo.h ├── ExceptionBase.h ├── ExceptionHandlerSetting.h ├── ExceptionHandlerWrapper.h ├── FatalException.h ├── FatalExceptionHandler.h ├── FixedSequenceGroup.cpp ├── FixedSequenceGroup.h ├── IConsumerInfo.h ├── ICursored.h ├── IDataProvider.h ├── IEventHandler.h ├── IEventProcessor.h ├── IEventProcessorFactory.h ├── IEventProcessorSequenceAware.h ├── IEventReleaseAware.h ├── IEventReleaser.h ├── IEventSequencer.h ├── IEventTranslator.h ├── IEventTranslatorVararg.h ├── IExceptionHandler.h ├── IExecutor.h ├── IHighestPublishedSequenceProvider.h ├── ILifecycleAware.h ├── ISequence.h ├── ISequenceBarrier.h ├── ISequenceReportingEventHandler.h ├── ISequenced.h ├── ISequencer.h ├── ITaskScheduler.h ├── ITimeoutHandler.h ├── IWaitStrategy.h ├── IWorkHandler.h ├── IgnoreExceptionHandler.h ├── InsufficientCapacityException.h ├── InvalidOperationException.h ├── MultiProducerSequencer.h ├── NoOpEventProcessor.h ├── NotSupportedException.h ├── Pragmas.h ├── ProcessingSequenceBarrier.cpp ├── ProcessingSequenceBarrier.h ├── ProducerType.cpp ├── ProducerType.h ├── RingBuffer.h ├── RoundRobinThreadAffinedTaskScheduler.cpp ├── RoundRobinThreadAffinedTaskScheduler.h ├── Sequence.cpp ├── Sequence.h ├── SequenceGroups.cpp ├── SequenceGroups.h ├── Sequencer.h ├── SingleProducerSequencer.h ├── SleepingWaitStrategy.cpp ├── SleepingWaitStrategy.h ├── SpinWait.cpp ├── SpinWait.h ├── SpinWaitWaitStrategy.cpp ├── SpinWaitWaitStrategy.h ├── ThreadHelper.h ├── ThreadHelper_Linux.cpp ├── ThreadHelper_Windows.cpp ├── ThreadHelper_macOS.cpp ├── ThreadPerTaskScheduler.cpp ├── ThreadPerTaskScheduler.h ├── TimeoutBlockingWaitStrategy.cpp ├── TimeoutBlockingWaitStrategy.h ├── TimeoutException.h ├── TypeInfo.cpp ├── TypeInfo.h ├── Util.cpp ├── Util.h ├── WorkProcessor.h ├── WorkerPool.h ├── WorkerPoolInfo.h ├── YieldingWaitStrategy.cpp ├── YieldingWaitStrategy.h ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── LICENCE.txt ├── README.md ├── appveyor.yml ├── cmake_uninstall.cmake.in ├── googletest-release-1.8.0 ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── README.md ├── appveyor.yml ├── googlemock │ ├── CHANGES │ ├── CMakeLists.txt │ ├── CONTRIBUTORS │ ├── LICENSE │ ├── Makefile.am │ ├── README.md │ ├── build-aux │ │ └── .keep │ ├── configure.ac │ ├── docs │ │ ├── CheatSheet.md │ │ ├── CookBook.md │ │ ├── DesignDoc.md │ │ ├── DevGuide.md │ │ ├── Documentation.md │ │ ├── ForDummies.md │ │ ├── FrequentlyAskedQuestions.md │ │ ├── KnownIssues.md │ │ ├── v1_5 │ │ │ ├── CheatSheet.md │ │ │ ├── CookBook.md │ │ │ ├── Documentation.md │ │ │ ├── ForDummies.md │ │ │ └── FrequentlyAskedQuestions.md │ │ ├── v1_6 │ │ │ ├── CheatSheet.md │ │ │ ├── CookBook.md │ │ │ ├── Documentation.md │ │ │ ├── ForDummies.md │ │ │ └── FrequentlyAskedQuestions.md │ │ └── v1_7 │ │ │ ├── CheatSheet.md │ │ │ ├── CookBook.md │ │ │ ├── Documentation.md │ │ │ ├── ForDummies.md │ │ │ └── FrequentlyAskedQuestions.md │ ├── include │ │ └── gmock │ │ │ ├── gmock-actions.h │ │ │ ├── gmock-cardinalities.h │ │ │ ├── gmock-generated-actions.h │ │ │ ├── gmock-generated-actions.h.pump │ │ │ ├── gmock-generated-function-mockers.h │ │ │ ├── gmock-generated-function-mockers.h.pump │ │ │ ├── gmock-generated-matchers.h │ │ │ ├── gmock-generated-matchers.h.pump │ │ │ ├── gmock-generated-nice-strict.h │ │ │ ├── gmock-generated-nice-strict.h.pump │ │ │ ├── gmock-matchers.h │ │ │ ├── gmock-more-actions.h │ │ │ ├── gmock-more-matchers.h │ │ │ ├── gmock-spec-builders.h │ │ │ ├── gmock.h │ │ │ └── internal │ │ │ ├── custom │ │ │ ├── gmock-generated-actions.h │ │ │ ├── gmock-generated-actions.h.pump │ │ │ ├── gmock-matchers.h │ │ │ └── gmock-port.h │ │ │ ├── gmock-generated-internal-utils.h │ │ │ ├── gmock-generated-internal-utils.h.pump │ │ │ ├── gmock-internal-utils.h │ │ │ └── gmock-port.h │ ├── make │ │ └── Makefile │ ├── msvc │ │ ├── 2005 │ │ │ ├── gmock.sln │ │ │ ├── gmock.vcproj │ │ │ ├── gmock_config.vsprops │ │ │ ├── gmock_main.vcproj │ │ │ └── gmock_test.vcproj │ │ ├── 2010 │ │ │ ├── gmock.sln │ │ │ ├── gmock.vcxproj │ │ │ ├── gmock_config.props │ │ │ ├── gmock_main.vcxproj │ │ │ └── gmock_test.vcxproj │ │ ├── 2015 │ │ │ ├── gmock.sln │ │ │ ├── gmock.vcxproj │ │ │ ├── gmock.vcxproj.user │ │ │ ├── gmock_config.props │ │ │ ├── gmock_main.vcxproj │ │ │ └── gmock_test.vcxproj │ │ ├── 2017 │ │ │ ├── gmock.sln │ │ │ ├── gmock.vcxproj │ │ │ ├── gmock.vcxproj.user │ │ │ ├── gmock_config.props │ │ │ ├── gmock_main.vcxproj │ │ │ └── gmock_test.vcxproj │ │ └── 2019 │ │ │ ├── gmock.vcxproj │ │ │ ├── gmock.vcxproj.user │ │ │ └── gmock_config.props │ ├── scripts │ │ ├── fuse_gmock_files.py │ │ ├── generator │ │ │ ├── LICENSE │ │ │ ├── README │ │ │ ├── README.cppclean │ │ │ ├── cpp │ │ │ │ ├── __init__.py │ │ │ │ ├── ast.py │ │ │ │ ├── gmock_class.py │ │ │ │ ├── gmock_class_test.py │ │ │ │ ├── keywords.py │ │ │ │ ├── tokenize.py │ │ │ │ └── utils.py │ │ │ └── gmock_gen.py │ │ ├── gmock-config.in │ │ ├── gmock_doctor.py │ │ ├── upload.py │ │ └── upload_gmock.py │ ├── src │ │ ├── gmock-all.cc │ │ ├── gmock-cardinalities.cc │ │ ├── gmock-internal-utils.cc │ │ ├── gmock-matchers.cc │ │ ├── gmock-spec-builders.cc │ │ ├── gmock.cc │ │ └── gmock_main.cc │ └── test │ │ ├── gmock-actions_test.cc │ │ ├── gmock-cardinalities_test.cc │ │ ├── gmock-generated-actions_test.cc │ │ ├── gmock-generated-function-mockers_test.cc │ │ ├── gmock-generated-internal-utils_test.cc │ │ ├── gmock-generated-matchers_test.cc │ │ ├── gmock-internal-utils_test.cc │ │ ├── gmock-matchers_test.cc │ │ ├── gmock-more-actions_test.cc │ │ ├── gmock-nice-strict_test.cc │ │ ├── gmock-port_test.cc │ │ ├── gmock-spec-builders_test.cc │ │ ├── gmock_all_test.cc │ │ ├── gmock_ex_test.cc │ │ ├── gmock_leak_test.py │ │ ├── gmock_leak_test_.cc │ │ ├── gmock_link2_test.cc │ │ ├── gmock_link_test.cc │ │ ├── gmock_link_test.h │ │ ├── gmock_output_test.py │ │ ├── gmock_output_test_.cc │ │ ├── gmock_output_test_golden.txt │ │ ├── gmock_stress_test.cc │ │ ├── gmock_test.cc │ │ └── gmock_test_utils.py ├── googletest │ ├── .gitignore │ ├── CHANGES │ ├── CMakeLists.txt │ ├── CONTRIBUTORS │ ├── LICENSE │ ├── Makefile.am │ ├── README.md │ ├── build-aux │ │ └── .keep │ ├── cmake │ │ └── internal_utils.cmake │ ├── codegear │ │ ├── gtest.cbproj │ │ ├── gtest.groupproj │ │ ├── gtest_all.cc │ │ ├── gtest_link.cc │ │ ├── gtest_main.cbproj │ │ └── gtest_unittest.cbproj │ ├── configure.ac │ ├── docs │ │ ├── AdvancedGuide.md │ │ ├── DevGuide.md │ │ ├── Documentation.md │ │ ├── FAQ.md │ │ ├── Primer.md │ │ ├── PumpManual.md │ │ ├── Samples.md │ │ ├── V1_5_AdvancedGuide.md │ │ ├── V1_5_Documentation.md │ │ ├── V1_5_FAQ.md │ │ ├── V1_5_Primer.md │ │ ├── V1_5_PumpManual.md │ │ ├── V1_5_XcodeGuide.md │ │ ├── V1_6_AdvancedGuide.md │ │ ├── V1_6_Documentation.md │ │ ├── V1_6_FAQ.md │ │ ├── V1_6_Primer.md │ │ ├── V1_6_PumpManual.md │ │ ├── V1_6_Samples.md │ │ ├── V1_6_XcodeGuide.md │ │ ├── V1_7_AdvancedGuide.md │ │ ├── V1_7_Documentation.md │ │ ├── V1_7_FAQ.md │ │ ├── V1_7_Primer.md │ │ ├── V1_7_PumpManual.md │ │ ├── V1_7_Samples.md │ │ ├── V1_7_XcodeGuide.md │ │ └── XcodeGuide.md │ ├── include │ │ └── gtest │ │ │ ├── gtest-death-test.h │ │ │ ├── gtest-message.h │ │ │ ├── gtest-param-test.h │ │ │ ├── gtest-param-test.h.pump │ │ │ ├── gtest-printers.h │ │ │ ├── gtest-spi.h │ │ │ ├── gtest-test-part.h │ │ │ ├── gtest-typed-test.h │ │ │ ├── gtest.h │ │ │ ├── gtest_pred_impl.h │ │ │ ├── gtest_prod.h │ │ │ └── internal │ │ │ ├── custom │ │ │ ├── gtest-port.h │ │ │ ├── gtest-printers.h │ │ │ └── gtest.h │ │ │ ├── gtest-death-test-internal.h │ │ │ ├── gtest-filepath.h │ │ │ ├── gtest-internal.h │ │ │ ├── gtest-linked_ptr.h │ │ │ ├── gtest-param-util-generated.h │ │ │ ├── gtest-param-util-generated.h.pump │ │ │ ├── gtest-param-util.h │ │ │ ├── gtest-port-arch.h │ │ │ ├── gtest-port.h │ │ │ ├── gtest-string.h │ │ │ ├── gtest-tuple.h │ │ │ ├── gtest-tuple.h.pump │ │ │ ├── gtest-type-util.h │ │ │ └── gtest-type-util.h.pump │ ├── m4 │ │ ├── acx_pthread.m4 │ │ └── gtest.m4 │ ├── make │ │ └── Makefile │ ├── msvc │ │ ├── gtest-md.sln │ │ ├── gtest-md.vcproj │ │ ├── gtest.sln │ │ ├── gtest.vcproj │ │ ├── gtest_main-md.vcproj │ │ ├── gtest_main.vcproj │ │ ├── gtest_prod_test-md.vcproj │ │ ├── gtest_prod_test.vcproj │ │ ├── gtest_unittest-md.vcproj │ │ └── gtest_unittest.vcproj │ ├── samples │ │ ├── prime_tables.h │ │ ├── sample1.cc │ │ ├── sample1.h │ │ ├── sample10_unittest.cc │ │ ├── sample1_unittest.cc │ │ ├── sample2.cc │ │ ├── sample2.h │ │ ├── sample2_unittest.cc │ │ ├── sample3-inl.h │ │ ├── sample3_unittest.cc │ │ ├── sample4.cc │ │ ├── sample4.h │ │ ├── sample4_unittest.cc │ │ ├── sample5_unittest.cc │ │ ├── sample6_unittest.cc │ │ ├── sample7_unittest.cc │ │ ├── sample8_unittest.cc │ │ └── sample9_unittest.cc │ ├── scripts │ │ ├── common.py │ │ ├── fuse_gtest_files.py │ │ ├── gen_gtest_pred_impl.py │ │ ├── gtest-config.in │ │ ├── pump.py │ │ ├── release_docs.py │ │ ├── test │ │ │ └── Makefile │ │ ├── upload.py │ │ └── upload_gtest.py │ ├── src │ │ ├── gtest-all.cc │ │ ├── gtest-death-test.cc │ │ ├── gtest-filepath.cc │ │ ├── gtest-internal-inl.h │ │ ├── gtest-port.cc │ │ ├── gtest-printers.cc │ │ ├── gtest-test-part.cc │ │ ├── gtest-typed-test.cc │ │ ├── gtest.cc │ │ └── gtest_main.cc │ ├── test │ │ ├── gtest-death-test_ex_test.cc │ │ ├── gtest-death-test_test.cc │ │ ├── gtest-filepath_test.cc │ │ ├── gtest-linked_ptr_test.cc │ │ ├── gtest-listener_test.cc │ │ ├── gtest-message_test.cc │ │ ├── gtest-options_test.cc │ │ ├── gtest-param-test2_test.cc │ │ ├── gtest-param-test_test.cc │ │ ├── gtest-param-test_test.h │ │ ├── gtest-port_test.cc │ │ ├── gtest-printers_test.cc │ │ ├── gtest-test-part_test.cc │ │ ├── gtest-tuple_test.cc │ │ ├── gtest-typed-test2_test.cc │ │ ├── gtest-typed-test_test.cc │ │ ├── gtest-typed-test_test.h │ │ ├── gtest-unittest-api_test.cc │ │ ├── gtest_all_test.cc │ │ ├── gtest_break_on_failure_unittest.py │ │ ├── gtest_break_on_failure_unittest_.cc │ │ ├── gtest_catch_exceptions_test.py │ │ ├── gtest_catch_exceptions_test_.cc │ │ ├── gtest_color_test.py │ │ ├── gtest_color_test_.cc │ │ ├── gtest_env_var_test.py │ │ ├── gtest_env_var_test_.cc │ │ ├── gtest_environment_test.cc │ │ ├── gtest_filter_unittest.py │ │ ├── gtest_filter_unittest_.cc │ │ ├── gtest_help_test.py │ │ ├── gtest_help_test_.cc │ │ ├── gtest_list_tests_unittest.py │ │ ├── gtest_list_tests_unittest_.cc │ │ ├── gtest_main_unittest.cc │ │ ├── gtest_no_test_unittest.cc │ │ ├── gtest_output_test.py │ │ ├── gtest_output_test_.cc │ │ ├── gtest_output_test_golden_lin.txt │ │ ├── gtest_pred_impl_unittest.cc │ │ ├── gtest_premature_exit_test.cc │ │ ├── gtest_prod_test.cc │ │ ├── gtest_repeat_test.cc │ │ ├── gtest_shuffle_test.py │ │ ├── gtest_shuffle_test_.cc │ │ ├── gtest_sole_header_test.cc │ │ ├── gtest_stress_test.cc │ │ ├── gtest_test_utils.py │ │ ├── gtest_throw_on_failure_ex_test.cc │ │ ├── gtest_throw_on_failure_test.py │ │ ├── gtest_throw_on_failure_test_.cc │ │ ├── gtest_uninitialized_test.py │ │ ├── gtest_uninitialized_test_.cc │ │ ├── gtest_unittest.cc │ │ ├── gtest_xml_outfile1_test_.cc │ │ ├── gtest_xml_outfile2_test_.cc │ │ ├── gtest_xml_outfiles_test.py │ │ ├── gtest_xml_output_unittest.py │ │ ├── gtest_xml_output_unittest_.cc │ │ ├── gtest_xml_test_utils.py │ │ ├── production.cc │ │ └── production.h │ └── xcode │ │ ├── Config │ │ ├── DebugProject.xcconfig │ │ ├── FrameworkTarget.xcconfig │ │ ├── General.xcconfig │ │ ├── ReleaseProject.xcconfig │ │ ├── StaticLibraryTarget.xcconfig │ │ └── TestTarget.xcconfig │ │ ├── Resources │ │ └── Info.plist │ │ ├── Samples │ │ └── FrameworkSample │ │ │ ├── Info.plist │ │ │ ├── WidgetFramework.xcodeproj │ │ │ └── project.pbxproj │ │ │ ├── runtests.sh │ │ │ ├── widget.cc │ │ │ ├── widget.h │ │ │ └── widget_test.cc │ │ ├── Scripts │ │ ├── runtests.sh │ │ └── versiongenerate.py │ │ └── gtest.xcodeproj │ │ └── project.pbxproj └── travis.sh └── msvc ├── 2015 ├── Disruptor-all.sln ├── Disruptor-lib.sln ├── Disruptor.PerfTests.vcxproj ├── Disruptor.PerfTests.vcxproj.filters ├── Disruptor.TestTools.vcxproj ├── Disruptor.TestTools.vcxproj.filters ├── Disruptor.Tests.vcxproj ├── Disruptor.Tests.vcxproj.filters ├── Disruptor.vcxproj └── Disruptor.vcxproj.filters ├── 2017 ├── Disruptor-all.sln ├── Disruptor-lib.sln ├── Disruptor.PerfTests.vcxproj ├── Disruptor.PerfTests.vcxproj.filters ├── Disruptor.TestTools.vcxproj ├── Disruptor.TestTools.vcxproj.filters ├── Disruptor.Tests.vcxproj ├── Disruptor.Tests.vcxproj.filters ├── Disruptor.vcxproj └── Disruptor.vcxproj.filters ├── 2019 ├── Disruptor-all.sln ├── Disruptor-all.sln.DotSettings.user ├── Disruptor-lib.sln ├── Disruptor.PerfTests.vcxproj ├── Disruptor.PerfTests.vcxproj.filters ├── Disruptor.PerfTests.vcxproj.user ├── Disruptor.TestTools.vcxproj ├── Disruptor.TestTools.vcxproj.filters ├── Disruptor.TestTools.vcxproj.user ├── Disruptor.Tests.vcxproj ├── Disruptor.Tests.vcxproj.filters ├── Disruptor.Tests.vcxproj.user ├── Disruptor.vcxproj ├── Disruptor.vcxproj.filters └── Disruptor.vcxproj.user ├── boost.props └── disruptor.props /.gitignore: -------------------------------------------------------------------------------- 1 | obj/ 2 | bin/ 3 | lib/ 4 | build/ 5 | .vs/ 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: required 3 | dist: trusty 4 | addons: 5 | apt: 6 | sources: 7 | # add PPAs with more up-to-date toolchains 8 | packages: 9 | matrix: 10 | include: 11 | - compiler: gcc 12 | addons: 13 | apt: 14 | sources: 15 | - ubuntu-toolchain-r-test 16 | - boost-latest 17 | packages: 18 | - g++-5 19 | env: COMPILER=g++-5 20 | - compiler: clang 21 | addons: 22 | apt: 23 | sources: 24 | - ubuntu-toolchain-r-test 25 | - llvm-toolchain-precise-3.8 26 | packages: 27 | - g++-5 # need at least gcc 5 because clang uses gcc stl 28 | - clang-3.8 29 | env: COMPILER=clang++-3.8 30 | 31 | before_install: 32 | - if [ "$TRAVIS_OS_NAME" == "linux" ]; then 33 | sudo apt-get install libboost-all-dev; 34 | fi 35 | 36 | script: mkdir build && cd build && cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DDISRUPTOR_BUILD_TESTS=true .. && make VERBOSE=1 && make test 37 | branches: 38 | only: 39 | - master 40 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/EventCountingQueueProcessor.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "EventCountingQueueProcessor.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | EventCountingQueueProcessor::EventCountingQueueProcessor(const std::shared_ptr< BlockingQueue< std::int64_t > >& blockingQueue, 11 | const std::vector< std::shared_ptr< PaddedLong > >& counters, 12 | std::int32_t index) 13 | : m_running(false) 14 | , m_blockingQueue(blockingQueue) 15 | , m_counters(counters) 16 | , m_index(index) 17 | { 18 | } 19 | 20 | void EventCountingQueueProcessor::halt() 21 | { 22 | m_running = false; 23 | } 24 | 25 | void EventCountingQueueProcessor::run() 26 | { 27 | m_running = true; 28 | while (m_running) 29 | { 30 | std::int64_t item; 31 | if (!m_blockingQueue->timedWaitAndPop(item, std::chrono::microseconds(100))) 32 | continue; 33 | 34 | m_counters[m_index]->value = m_counters[m_index]->value + 1L; 35 | } 36 | } 37 | 38 | } // namespace PerfTests 39 | } // namespace Disruptor 40 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/EventCountingQueueProcessor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "Disruptor/BlockingQueue.h" 9 | 10 | #include "Disruptor.PerfTests/PaddedLong.h" 11 | 12 | 13 | namespace Disruptor 14 | { 15 | namespace PerfTests 16 | { 17 | 18 | class EventCountingQueueProcessor 19 | { 20 | public: 21 | EventCountingQueueProcessor(const std::shared_ptr< BlockingQueue< std::int64_t > >& blockingQueue, 22 | const std::vector< std::shared_ptr< PaddedLong > >& counters, 23 | std::int32_t index); 24 | 25 | void halt(); 26 | 27 | void run(); 28 | 29 | private: 30 | std::atomic< bool > m_running; 31 | std::shared_ptr< BlockingQueue< std::int64_t > > m_blockingQueue; 32 | std::vector< std::shared_ptr< PaddedLong > > m_counters; 33 | std::int32_t m_index; 34 | }; 35 | 36 | } // namespace PerfTests 37 | } // namespace Disruptor 38 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/EventCountingWorkHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "EventCountingWorkHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | EventCountingWorkHandler::EventCountingWorkHandler(const std::vector< std::shared_ptr< PaddedLong > >& counters, std::int32_t index) 11 | : m_counters(counters) 12 | , m_index(index) 13 | { 14 | } 15 | 16 | void EventCountingWorkHandler::onEvent(ValueEvent& /*evt*/) 17 | { 18 | m_counters[m_index]->value = m_counters[m_index]->value + 1L; 19 | } 20 | 21 | } // namespace PerfTests 22 | } // namespace Disruptor 23 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/EventCountingWorkHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "Disruptor/IWorkHandler.h" 8 | 9 | #include "Disruptor.PerfTests/PaddedLong.h" 10 | #include "Disruptor.PerfTests/ValueEvent.h" 11 | 12 | 13 | namespace Disruptor 14 | { 15 | namespace PerfTests 16 | { 17 | 18 | class EventCountingWorkHandler : public IWorkHandler< ValueEvent > 19 | { 20 | public: 21 | EventCountingWorkHandler(const std::vector< std::shared_ptr< PaddedLong > >& counters, std::int32_t index); 22 | 23 | void onEvent(ValueEvent& evt) override; 24 | 25 | private: 26 | std::vector< std::shared_ptr< PaddedLong > > m_counters; 27 | std::int32_t m_index; 28 | }; 29 | 30 | } // namespace PerfTests 31 | } // namespace Disruptor 32 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ExecutorService.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/BatchEventProcessor.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | namespace PerfTests 12 | { 13 | 14 | template 15 | class ExecutorService 16 | { 17 | public: 18 | std::future< void > submit(const std::shared_ptr< BatchEventProcessor< T > >& eventProcessor) 19 | { 20 | return std::async(std::launch::async, [eventProcessor] { eventProcessor->run(); }); 21 | } 22 | }; 23 | 24 | } // namespace PerfTests 25 | } // namespace Disruptor 26 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FizzBuzzEvent.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FizzBuzzEvent.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | void FizzBuzzEvent::reset() 11 | { 12 | value = 0; 13 | fizz = false; 14 | buzz = false; 15 | } 16 | 17 | const std::function< FizzBuzzEvent() >& FizzBuzzEvent::eventFactory() 18 | { 19 | static std::function< FizzBuzzEvent() > result([] { return FizzBuzzEvent(); }); 20 | return result; 21 | } 22 | 23 | } // namespace PerfTests 24 | } // namespace Disruptor 25 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FizzBuzzEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | namespace Disruptor 9 | { 10 | namespace PerfTests 11 | { 12 | 13 | class FizzBuzzEvent 14 | { 15 | public: 16 | void reset(); 17 | 18 | static const std::function< FizzBuzzEvent() >& eventFactory(); 19 | 20 | std::int64_t value = 0; 21 | bool fizz = false; 22 | bool buzz = false; 23 | }; 24 | 25 | } // namespace PerfTests 26 | } // namespace Disruptor 27 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FizzBuzzEventHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FizzBuzzEventHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | FizzBuzzEventHandler::FizzBuzzEventHandler(FizzBuzzStep fizzBuzzStep) 11 | : m_fizzBuzzStep(fizzBuzzStep) 12 | { 13 | } 14 | 15 | std::int64_t FizzBuzzEventHandler::fizzBuzzCounter() const 16 | { 17 | return m_fizzBuzzCounter.value; 18 | } 19 | 20 | void FizzBuzzEventHandler::reset(const std::shared_ptr< Tests::ManualResetEvent >& latch, std::int64_t iterations) 21 | { 22 | m_fizzBuzzCounter.value = 0; 23 | m_iterations = iterations; 24 | m_latch = latch; 25 | } 26 | 27 | void FizzBuzzEventHandler::onEvent(FizzBuzzEvent& data, std::int64_t sequence, bool) 28 | { 29 | switch (m_fizzBuzzStep) 30 | { 31 | case FizzBuzzStep::Fizz: 32 | data.fizz = data.value % 3 == 0; 33 | break; 34 | 35 | case FizzBuzzStep::Buzz: 36 | data.buzz = data.value % 5 == 0; 37 | break; 38 | 39 | case FizzBuzzStep::FizzBuzz: 40 | if (data.fizz && data.buzz) 41 | { 42 | m_fizzBuzzCounter.value = m_fizzBuzzCounter.value + 1; 43 | } 44 | break; 45 | } 46 | 47 | if (sequence == m_iterations - 1) 48 | { 49 | m_latch->set(); 50 | } 51 | } 52 | 53 | } // namespace PerfTests 54 | } // namespace Disruptor 55 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FizzBuzzEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/IEventHandler.h" 4 | 5 | #include "Disruptor.TestTools/ManualResetEvent.h" 6 | 7 | #include "Disruptor.PerfTests/FizzBuzzEvent.h" 8 | #include "Disruptor.PerfTests/FizzBuzzStep.h" 9 | #include "Disruptor.PerfTests/PaddedLong.h" 10 | 11 | 12 | namespace Disruptor 13 | { 14 | namespace PerfTests 15 | { 16 | 17 | class FizzBuzzEventHandler : public IEventHandler< FizzBuzzEvent > 18 | { 19 | public: 20 | explicit FizzBuzzEventHandler(FizzBuzzStep fizzBuzzStep); 21 | 22 | std::int64_t fizzBuzzCounter() const; 23 | 24 | void reset(const std::shared_ptr< Tests::ManualResetEvent >& latch, std::int64_t iterations); 25 | 26 | void onEvent(FizzBuzzEvent& data, std::int64_t sequence, bool /*endOfBatch*/) override; 27 | 28 | private: 29 | FizzBuzzStep m_fizzBuzzStep; 30 | std::int64_t m_iterations = 0; 31 | std::shared_ptr< Tests::ManualResetEvent > m_latch; 32 | PaddedLong m_fizzBuzzCounter; 33 | }; 34 | 35 | } // namespace PerfTests 36 | } // namespace Disruptor 37 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FizzBuzzStep.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Disruptor 5 | { 6 | namespace PerfTests 7 | { 8 | 9 | enum class FizzBuzzStep 10 | { 11 | Fizz, 12 | Buzz, 13 | FizzBuzz, 14 | }; 15 | 16 | } // namespace PerfTests 17 | } // namespace Disruptor 18 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FunctionEvent.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FunctionEvent.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | const std::function< FunctionEvent() >& FunctionEvent::eventFactory() 11 | { 12 | static std::function< FunctionEvent() > result([] { return FunctionEvent(); }); 13 | return result; 14 | } 15 | 16 | } // namespace PerfTests 17 | } // namespace Disruptor 18 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FunctionEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | namespace PerfTests 10 | { 11 | 12 | class FunctionEvent 13 | { 14 | public: 15 | static const std::function< FunctionEvent() >& eventFactory(); 16 | 17 | std::int64_t operandOne = 0; 18 | std::int64_t operandTwo = 0; 19 | std::int64_t stepOneResult = 0; 20 | std::int64_t stepTwoResult = 0; 21 | }; 22 | 23 | } // namespace PerfTests 24 | } // namespace Disruptor 25 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FunctionEventHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FunctionEventHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | FunctionEventHandler::FunctionEventHandler(FunctionStep functionStep) 11 | : m_functionStep(functionStep) 12 | { 13 | } 14 | 15 | std::int64_t FunctionEventHandler::stepThreeCounter() const 16 | { 17 | return m_counter.value; 18 | } 19 | 20 | void FunctionEventHandler::reset(const std::shared_ptr< Tests::ManualResetEvent >& latch, std::int64_t iterations) 21 | { 22 | m_counter.value = 0; 23 | m_iterations = iterations; 24 | m_latch = latch; 25 | } 26 | 27 | void FunctionEventHandler::onEvent(FunctionEvent& data, std::int64_t sequence, bool /*endOfBatch*/) 28 | { 29 | switch (m_functionStep) 30 | { 31 | case FunctionStep::One: 32 | data.stepOneResult = data.operandOne + data.operandTwo; 33 | break; 34 | 35 | case FunctionStep::Two: 36 | data.stepTwoResult = data.stepOneResult + 3L; 37 | break; 38 | 39 | case FunctionStep::Three: 40 | if ((data.stepTwoResult & 4L) == 4L) 41 | { 42 | m_counter.value = m_counter.value + 1; 43 | } 44 | break; 45 | } 46 | 47 | if (sequence == m_iterations - 1) 48 | { 49 | m_latch->set(); 50 | } 51 | } 52 | 53 | } // namespace PerfTests 54 | } // namespace Disruptor 55 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FunctionEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IEventHandler.h" 6 | 7 | #include "Disruptor.TestTools/ManualResetEvent.h" 8 | 9 | #include "Disruptor.PerfTests/FunctionEvent.h" 10 | #include "Disruptor.PerfTests/FunctionStep.h" 11 | #include "Disruptor.PerfTests/PaddedLong.h" 12 | 13 | 14 | namespace Disruptor 15 | { 16 | namespace PerfTests 17 | { 18 | 19 | class FunctionEventHandler : public IEventHandler< FunctionEvent > 20 | { 21 | public: 22 | explicit FunctionEventHandler(FunctionStep functionStep); 23 | 24 | std::int64_t stepThreeCounter() const; 25 | 26 | void reset(const std::shared_ptr< Tests::ManualResetEvent >& latch, std::int64_t iterations); 27 | 28 | void onEvent(FunctionEvent& data, std::int64_t sequence, bool endOfBatch); 29 | 30 | private: 31 | FunctionStep m_functionStep; 32 | PaddedLong m_counter; 33 | std::int64_t m_iterations{0}; 34 | std::shared_ptr< Tests::ManualResetEvent > m_latch; 35 | }; 36 | 37 | } // namespace PerfTests 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/FunctionStep.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Disruptor 5 | { 6 | namespace PerfTests 7 | { 8 | 9 | enum class FunctionStep 10 | { 11 | One, 12 | Two, 13 | Three, 14 | }; 15 | 16 | } // namespace PerfTests 17 | } // namespace Disruptor 18 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ILatencyTest.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor.TestTools/LatencyRecorder.h" 6 | #include "Disruptor.TestTools/Stopwatch.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | namespace PerfTests 12 | { 13 | 14 | class ILatencyTest 15 | { 16 | public: 17 | virtual ~ILatencyTest() = default; 18 | 19 | virtual void run(Stopwatch& stopwatch, const std::shared_ptr< Tests::LatencyRecorder >& latencyRecorder) = 0; 20 | 21 | virtual std::int32_t requiredProcessorCount() const = 0; 22 | }; 23 | 24 | } // namespace PerfTests 25 | } // namespace Disruptor 26 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/IThroughputTest.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor.TestTools/Stopwatch.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | namespace PerfTests 11 | { 12 | 13 | class IThroughputTest 14 | { 15 | public: 16 | virtual ~IThroughputTest() = default; 17 | 18 | virtual std::int64_t run(Stopwatch& stopwatch) = 0; 19 | 20 | virtual std::int32_t requiredProcessorCount() const = 0; 21 | }; 22 | 23 | } // namespace PerfTests 24 | } // namespace Disruptor 25 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/LatencyTestSession.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor.PerfTests/TestFactory.h" 7 | #include "LatencyTestSessionResult.h" 8 | 9 | 10 | namespace Disruptor 11 | { 12 | namespace PerfTests 13 | { 14 | 15 | class ILatencyTest; 16 | 17 | 18 | class LatencyTestSession 19 | { 20 | public: 21 | explicit LatencyTestSession(const LatencyTestInfo& testInfo); 22 | 23 | void run(); 24 | 25 | static std::int64_t convertStopwatchTicksToNano(double durationInTicks); 26 | static double convertNanoToStopwatchTicks(std::int64_t pauseDurationInNanos); 27 | 28 | private: 29 | static void checkProcessorsRequirements(const std::shared_ptr< ILatencyTest >& test); 30 | 31 | const std::int32_t m_runs = 3; 32 | 33 | LatencyTestInfo m_testInfo; 34 | std::vector< LatencyTestSessionResult > m_results; 35 | }; 36 | 37 | } // namespace PerfTests 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/LatencyTestSessionResult.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "LatencyTestSessionResult.h" 3 | 4 | #include 5 | #include 6 | 7 | #include "Disruptor.TestTools/DurationHumanizer.h" 8 | #include "Disruptor.TestTools/HumanNumberFacet.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace PerfTests 14 | { 15 | 16 | LatencyTestSessionResult::LatencyTestSessionResult(const std::shared_ptr< Tests::LatencyRecorder >& latencyRecorder, const ClockConfig::Duration& duration) 17 | : m_latencyRecorder(latencyRecorder) 18 | , m_duration(duration) 19 | { 20 | } 21 | 22 | LatencyTestSessionResult::LatencyTestSessionResult(const std::exception& exception) 23 | : m_exception(exception) 24 | { 25 | } 26 | 27 | std::string LatencyTestSessionResult::toString() 28 | { 29 | std::ostringstream result; 30 | result.imbue(std::locale(result.getloc(), new Tests::HumanNumberFacet())); 31 | 32 | if (m_exception) 33 | result << "Run: FAILED: " << m_exception.get().what(); 34 | else 35 | { 36 | auto humanDuration = Tests::DurationHumanizer::deduceHumanDuration(duration()); 37 | 38 | result << "Run: " 39 | << "Duration (" << humanDuration.shortUnitName << "): " << std::setprecision(3) << humanDuration.value 40 | << ", Latency: "; 41 | m_latencyRecorder->writeReport(result); 42 | } 43 | 44 | return result.str(); 45 | } 46 | 47 | ClockConfig::Duration LatencyTestSessionResult::duration() const 48 | { 49 | return m_duration; 50 | } 51 | 52 | } // namespace PerfTests 53 | } // namespace Disruptor 54 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/LatencyTestSessionResult.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "Disruptor/ClockConfig.h" 10 | #include "Disruptor.TestTools/LatencyRecorder.h" 11 | 12 | 13 | namespace Disruptor 14 | { 15 | namespace PerfTests 16 | { 17 | 18 | class LatencyTestSessionResult 19 | { 20 | public: 21 | LatencyTestSessionResult(const std::shared_ptr< Tests::LatencyRecorder >& latencyRecorder, const ClockConfig::Duration& duration); 22 | 23 | explicit LatencyTestSessionResult(const std::exception& exception); 24 | 25 | std::string toString(); 26 | 27 | ClockConfig::Duration duration() const; 28 | 29 | private: 30 | std::shared_ptr< Tests::LatencyRecorder > m_latencyRecorder; 31 | ClockConfig::Duration m_duration; 32 | boost::optional< std::exception > m_exception; 33 | }; 34 | 35 | } // namespace PerfTests 36 | } // namespace Disruptor 37 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/LongArrayEventHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "LongArrayEventHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | std::int64_t LongArrayEventHandler::count() const 11 | { 12 | return m_count; 13 | } 14 | 15 | const std::shared_ptr< Tests::ManualResetEvent >& LongArrayEventHandler::signal() const 16 | { 17 | return m_signal; 18 | } 19 | 20 | std::int64_t LongArrayEventHandler::value() const 21 | { 22 | return m_value->value; 23 | } 24 | 25 | void LongArrayEventHandler::reset(const std::shared_ptr< Tests::ManualResetEvent >& signal, std::int64_t expectedCount) 26 | { 27 | m_value->value = 0L; 28 | m_signal = signal; 29 | m_count = expectedCount; 30 | } 31 | 32 | void LongArrayEventHandler::onEvent(std::vector< std::int64_t >& data, std::int64_t /*sequence*/, bool /*endOfBatch*/) 33 | { 34 | for (auto i = 0u; i < data.size(); ++i) 35 | { 36 | m_value->value = m_value->value + data[i]; 37 | } 38 | 39 | if (--m_count == 0) 40 | { 41 | if (m_signal != nullptr) 42 | m_signal->set(); 43 | } 44 | } 45 | 46 | } // namespace PerfTests 47 | } // namespace Disruptor 48 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/LongArrayEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/IEventHandler.h" 7 | 8 | #include "Disruptor.TestTools/ManualResetEvent.h" 9 | 10 | #include "Disruptor.PerfTests/PaddedLong.h" 11 | 12 | 13 | namespace Disruptor 14 | { 15 | namespace PerfTests 16 | { 17 | 18 | class LongArrayEventHandler : public IEventHandler< std::vector< std::int64_t > > 19 | { 20 | public: 21 | std::int64_t count() const; 22 | 23 | const std::shared_ptr< Tests::ManualResetEvent >& signal() const; 24 | 25 | std::int64_t value() const; 26 | 27 | void reset(const std::shared_ptr< Tests::ManualResetEvent >& signal, std::int64_t expectedCount); 28 | 29 | void onEvent(std::vector< std::int64_t >& data, std::int64_t sequence, bool endOfBatch) override; 30 | 31 | private: 32 | std::shared_ptr< PaddedLong > m_value = std::make_shared< PaddedLong >(); 33 | std::int64_t m_count = 0; 34 | std::shared_ptr< Tests::ManualResetEvent > m_signal; 35 | }; 36 | 37 | } // namespace PerfTests 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/MutableLong.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "MutableLong.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | MutableLong::MutableLong(std::int64_t value) 11 | : value(value) 12 | { 13 | } 14 | 15 | } // namespace PerfTests 16 | } // namespace Disruptor 17 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/MutableLong.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace PerfTests 9 | { 10 | 11 | class MutableLong 12 | { 13 | public: 14 | explicit MutableLong(std::int64_t value); 15 | 16 | std::int64_t value; 17 | }; 18 | 19 | } // namespace PerfTests 20 | } // namespace Disruptor 21 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/Operation.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Operation.h" 3 | 4 | #include "Disruptor/ArgumentOutOfRangeException.h" 5 | 6 | 7 | namespace Disruptor 8 | { 9 | namespace PerfTests 10 | { 11 | namespace OperationExtensions 12 | { 13 | 14 | std::int64_t Op(Operation operation, std::int64_t lhs, std::int64_t rhs) 15 | { 16 | switch (operation) 17 | { 18 | case Operation::Addition: 19 | return lhs + rhs; 20 | case Operation::Subtraction: 21 | return lhs - rhs; 22 | case Operation::And: 23 | return lhs & rhs; 24 | default: 25 | DISRUPTOR_THROW_ARGUMENT_OUT_OF_RANGE_EXCEPTION("The variable 'operation' (" << static_cast< int >(operation) << ") is out of range"); 26 | } 27 | } 28 | 29 | } // namespace OperationExtensions 30 | } // namespace PerfTests 31 | } // namespace Disruptor 32 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/Operation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace PerfTests 9 | { 10 | 11 | enum class Operation 12 | { 13 | Addition, 14 | Subtraction, 15 | And 16 | }; 17 | 18 | namespace OperationExtensions 19 | { 20 | 21 | std::int64_t Op(Operation operation, std::int64_t lhs, std::int64_t rhs); 22 | 23 | } // namespace OperationExtensions 24 | } // namespace PerfTests 25 | } // namespace Disruptor 26 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/PaddedLong.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace PerfTests 9 | { 10 | 11 | struct PaddedLong 12 | { 13 | std::int64_t value = 0; 14 | char _padding[54]; 15 | }; 16 | 17 | } // namespace PerfTests 18 | } // namespace Disruptor 19 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/PerfTestUtil.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "PerfTestUtil.h" 3 | 4 | #include 5 | 6 | #include "Disruptor/IEventProcessor.h" 7 | #include "Disruptor/ISequence.h" 8 | 9 | 10 | namespace Disruptor 11 | { 12 | namespace PerfTests 13 | { 14 | namespace PerfTestUtil 15 | { 16 | 17 | std::int64_t accumulatedAddition(std::int64_t iterations) 18 | { 19 | std::int64_t temp = 0L; 20 | for (std::int64_t i = 0L; i < iterations; i++) 21 | { 22 | temp += i; 23 | } 24 | 25 | return temp; 26 | } 27 | 28 | void failIf(std::int64_t a, std::int64_t b, const std::string& message) 29 | { 30 | if (a == b) 31 | { 32 | throw std::runtime_error(message.empty() ? "Test failed " + std::to_string(a) + " == " + std::to_string(b) : message); 33 | } 34 | } 35 | 36 | void failIfNot(std::int64_t a, std::int64_t b, const std::string& message) 37 | { 38 | if (a != b) 39 | { 40 | throw std::runtime_error(message.empty() ? "Test failed " + std::to_string(a) + " != " + std::to_string(b) : message); 41 | } 42 | } 43 | 44 | void waitForEventProcessorSequence(std::int64_t expectedCount, const std::shared_ptr< IEventProcessor >& batchEventProcessor) 45 | { 46 | while (batchEventProcessor->sequence()->value() != expectedCount) 47 | { 48 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); 49 | } 50 | } 51 | 52 | std::string utcDateToString() 53 | { 54 | auto t(boost::posix_time::second_clock::universal_time()); 55 | return to_simple_string(t); 56 | } 57 | 58 | } // namespace PerfTestUtil 59 | } // namespace PerfTests 60 | } // namespace Disruptor 61 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/PerfTestUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | class IEventProcessor; 11 | 12 | namespace PerfTests 13 | { 14 | namespace PerfTestUtil 15 | { 16 | 17 | std::int64_t accumulatedAddition(std::int64_t iterations); 18 | 19 | void failIf(std::int64_t a, std::int64_t b, const std::string& message = std::string()); 20 | 21 | void failIfNot(std::int64_t a, std::int64_t b, const std::string& message = std::string()); 22 | 23 | void waitForEventProcessorSequence(std::int64_t expectedCount, const std::shared_ptr< IEventProcessor >& batchEventProcessor); 24 | 25 | std::string utcDateToString(); 26 | 27 | } // namespace PerfTestUtil 28 | } // namespace PerfTests 29 | } // namespace Disruptor 30 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/TestFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor.PerfTests/ILatencyTest.h" 6 | #include "Disruptor.PerfTests/IThroughputTest.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | namespace PerfTests 12 | { 13 | 14 | template 15 | struct TestFactory 16 | { 17 | std::string name; 18 | std::function()> factory; 19 | }; 20 | 21 | 22 | using ThroughputTestInfo = TestFactory< IThroughputTest >; 23 | using LatencyTestInfo = TestFactory< ILatencyTest >; 24 | 25 | } // namespace PerfTests 26 | } // namespace Disruptor 27 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ThroughputTestSession.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor.PerfTests/TestFactory.h" 4 | #include "Disruptor.PerfTests/ThroughputTestSessionResult.h" 5 | 6 | 7 | namespace Disruptor 8 | { 9 | namespace PerfTests 10 | { 11 | 12 | class IThroughputTest; 13 | 14 | 15 | class ThroughputTestSession 16 | { 17 | public: 18 | explicit ThroughputTestSession(const ThroughputTestInfo& testInfo); 19 | 20 | void run(); 21 | 22 | private: 23 | static void checkProcessorsRequirements(const std::shared_ptr& test); 24 | std::int64_t getAverageThroughput(); 25 | 26 | #ifdef _DEBUG 27 | const std::int32_t m_runs = 3; 28 | #else 29 | const std::int32_t m_runs = 7; 30 | #endif 31 | 32 | std::vector< ThroughputTestSessionResult > m_results; 33 | ThroughputTestInfo m_testInfo; 34 | }; 35 | 36 | } // namespace PerfTests 37 | } // namespace Disruptor 38 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ThroughputTestSessionResult.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "Disruptor/ClockConfig.h" 10 | 11 | 12 | namespace Disruptor 13 | { 14 | namespace PerfTests 15 | { 16 | 17 | class ThroughputTestSessionResult 18 | { 19 | public: 20 | ThroughputTestSessionResult(std::int64_t totalOperationsInRun, ClockConfig::Duration duration); 21 | 22 | explicit ThroughputTestSessionResult(const std::exception& exception); 23 | 24 | void appendDetailedHtmlReport(std::int32_t runId, std::ostringstream& stringBuilder); 25 | std::string toString(); 26 | 27 | std::int64_t totalOperationsInRun() const; 28 | ClockConfig::Duration duration() const; 29 | 30 | std::int64_t ops() const; 31 | std::int64_t durationInMilliseconds() const; 32 | 33 | private: 34 | std::int64_t m_totalOperationsInRun = 0; 35 | ClockConfig::Duration m_duration; 36 | boost::optional< std::exception > m_exception; 37 | }; 38 | 39 | } // namespace PerfTests 40 | } // namespace Disruptor 41 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ValueAdditionEventHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ValueAdditionEventHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | void ValueAdditionEventHandler::reset(const std::shared_ptr< Tests::ManualResetEvent >& latch, std::int64_t expectedCount) 11 | { 12 | m_value.value = 0; 13 | m_latch = latch; 14 | m_count = expectedCount; 15 | } 16 | 17 | void ValueAdditionEventHandler::onEvent(ValueEvent& value, std::int64_t sequence, bool) 18 | { 19 | m_value.value = m_value.value + value.value; 20 | 21 | if (count() == sequence) 22 | { 23 | if (m_latch != nullptr) 24 | m_latch->set(); 25 | } 26 | } 27 | 28 | std::int64_t ValueAdditionEventHandler::count() const 29 | { 30 | return m_count; 31 | } 32 | 33 | std::int64_t ValueAdditionEventHandler::value() const 34 | { 35 | return m_value.value; 36 | } 37 | 38 | } // namespace PerfTests 39 | } // namespace Disruptor 40 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ValueAdditionEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IEventHandler.h" 6 | 7 | #include "Disruptor.TestTools/ManualResetEvent.h" 8 | 9 | #include "Disruptor.PerfTests/PaddedLong.h" 10 | #include "Disruptor.PerfTests/ValueEvent.h" 11 | 12 | 13 | namespace Disruptor 14 | { 15 | namespace PerfTests 16 | { 17 | 18 | class ValueAdditionEventHandler : public IEventHandler< ValueEvent > 19 | { 20 | public: 21 | void reset(const std::shared_ptr< Tests::ManualResetEvent >& latch, std::int64_t expectedCount); 22 | 23 | void onEvent(ValueEvent& value, std::int64_t sequence, bool /*endOfBatch*/) override; 24 | 25 | std::int64_t count() const; 26 | 27 | std::int64_t value() const; 28 | 29 | private: 30 | PaddedLong m_value; 31 | std::int64_t m_count = 0; 32 | std::shared_ptr< Tests::ManualResetEvent > m_latch; 33 | }; 34 | 35 | } // namespace PerfTests 36 | } // namespace Disruptor 37 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ValueEvent.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ValueEvent.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | const std::function< ValueEvent() >& ValueEvent::eventFactory() 11 | { 12 | static std::function< ValueEvent() > result([] { return ValueEvent(); }); 13 | return result; 14 | } 15 | 16 | } // namespace PerfTests 17 | } // namespace Disruptor 18 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ValueEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Disruptor 7 | { 8 | namespace PerfTests 9 | { 10 | 11 | class ValueEvent 12 | { 13 | public: 14 | static const std::function< ValueEvent() >& eventFactory(); 15 | 16 | std::int64_t value; 17 | }; 18 | 19 | } // namespace PerfTests 20 | } // namespace Disruptor 21 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ValueMutationEventHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ValueMutationEventHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | ValueMutationEventHandler::ValueMutationEventHandler(Operation operation) 11 | : m_operation(operation) 12 | { 13 | } 14 | 15 | std::int64_t ValueMutationEventHandler::value() const 16 | { 17 | return m_value.value; 18 | } 19 | 20 | void ValueMutationEventHandler::reset(const std::shared_ptr< boost::barrier >& latch, std::int64_t expectedCount) 21 | { 22 | m_value.value = 0L; 23 | m_latch = latch; 24 | m_iterations = expectedCount; 25 | } 26 | 27 | void ValueMutationEventHandler::onEvent(ValueEvent& data, std::int64_t sequence, bool /*endOfBatch*/) 28 | { 29 | m_value.value = OperationExtensions::Op(m_operation, m_value.value, data.value); 30 | 31 | if (sequence == m_iterations) 32 | { 33 | m_latch->wait(); 34 | } 35 | } 36 | 37 | } // namespace PerfTests 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/ValueMutationEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IEventHandler.h" 6 | 7 | #include "Disruptor.PerfTests/Operation.h" 8 | #include "Disruptor.PerfTests/PaddedLong.h" 9 | #include "Disruptor.PerfTests/ValueEvent.h" 10 | 11 | 12 | namespace Disruptor 13 | { 14 | namespace PerfTests 15 | { 16 | 17 | class ValueMutationEventHandler : public IEventHandler< ValueEvent > 18 | { 19 | public: 20 | explicit ValueMutationEventHandler(Operation operation); 21 | 22 | std::int64_t value() const; 23 | 24 | void reset(const std::shared_ptr< boost::barrier >& latch, std::int64_t expectedCount); 25 | 26 | void onEvent(ValueEvent& data, std::int64_t sequence, bool endOfBatch); 27 | 28 | private: 29 | Operation m_operation; 30 | PaddedLong m_value; 31 | std::int64_t m_iterations = 0; 32 | std::shared_ptr< boost::barrier > m_latch; 33 | }; 34 | 35 | } // namespace PerfTests 36 | } // namespace Disruptor 37 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // disruptorLibTests.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /Disruptor.PerfTests/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #if _MSC_VER // only on Windows 11 | 12 | # ifndef WIN32_LEAN_AND_MEAN 13 | # define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 14 | # endif 15 | 16 | # pragma warning(disable: 4512) // Assignment operator could not be generated 17 | 18 | # include "targetver.h" 19 | # include 20 | # include 21 | # include 22 | #endif 23 | 24 | // STL includes 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include -------------------------------------------------------------------------------- /Disruptor.PerfTests/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /Disruptor.TestTools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(Disruptor.TestTools) 2 | cmake_minimum_required(VERSION 2.6) 3 | 4 | 5 | find_package(Boost COMPONENTS system) 6 | if(Boost_FOUND) 7 | include_directories(${Boost_INCLUDE_DIRS}) 8 | link_directories(${Boost_LIBRARY_DIRS}) 9 | endif() 10 | 11 | include_directories("..") 12 | 13 | 14 | set(DisruptorTestTools_sources 15 | 16 | CountdownEvent.cpp 17 | ManualResetEvent.cpp 18 | ResetEvent.cpp 19 | ScopeExitFunctor.cpp 20 | Stopwatch.cpp 21 | LatencyRecorder.cpp 22 | ) 23 | 24 | add_library(Disruptor.TestTools STATIC ${DisruptorTestTools_sources}) 25 | -------------------------------------------------------------------------------- /Disruptor.TestTools/CountdownEvent.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CountdownEvent.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | CountdownEvent::CountdownEvent(std::uint32_t initialCount) 11 | : ResetEvent(initialCount == 0) 12 | , m_initialCount(initialCount) 13 | , m_currentCount(initialCount) 14 | {} 15 | 16 | std::uint32_t CountdownEvent::initialCount() const 17 | { 18 | return m_initialCount; 19 | } 20 | 21 | std::uint32_t CountdownEvent::currentCount() const 22 | { 23 | return m_currentCount; 24 | } 25 | 26 | void CountdownEvent::reset() 27 | { 28 | m_currentCount = initialCount(); 29 | ResetEvent::reset(); 30 | } 31 | 32 | void CountdownEvent::reset(std::uint32_t initialCount) 33 | { 34 | m_initialCount = initialCount; 35 | reset(); 36 | } 37 | 38 | bool CountdownEvent::wait(ClockConfig::Duration timeDuration) 39 | { 40 | while (currentCount() != 0) 41 | { 42 | ResetEvent::reset(); 43 | ResetEvent::wait(timeDuration); 44 | } 45 | 46 | return true; 47 | } 48 | 49 | void CountdownEvent::signal() 50 | { 51 | --m_currentCount; 52 | if (currentCount() == 0) 53 | set(); 54 | } 55 | 56 | } // namespace Tests 57 | } // namespace Disruptor 58 | -------------------------------------------------------------------------------- /Disruptor.TestTools/CountdownEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/ClockConfig.h" 6 | #include "Disruptor.TestTools/ResetEvent.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | namespace Tests 12 | { 13 | 14 | class CountdownEvent : public ResetEvent 15 | { 16 | public: 17 | explicit CountdownEvent(std::uint32_t initialCount); 18 | 19 | std::uint32_t initialCount() const; 20 | std::uint32_t currentCount() const; 21 | 22 | void signal(); 23 | 24 | void reset() override; 25 | void reset(std::uint32_t initialCount); 26 | 27 | bool wait(ClockConfig::Duration timeDuration = ClockConfig::Duration()) override; 28 | 29 | private: 30 | mutable std::atomic< std::uint32_t > m_initialCount; 31 | mutable std::atomic< std::uint32_t > m_currentCount; 32 | }; 33 | 34 | } // namespace Tests 35 | } // namespace Disruptor 36 | -------------------------------------------------------------------------------- /Disruptor.TestTools/HumanNumberFacet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace Tests 9 | { 10 | 11 | struct HumanNumberFacet : std::numpunct< char > 12 | { 13 | char do_thousands_sep() const override 14 | { 15 | return ' '; 16 | } 17 | 18 | std::string do_grouping() const override 19 | { 20 | return "\3"; 21 | } 22 | }; 23 | 24 | } // namespace Tests 25 | } // namespace Disruptor 26 | -------------------------------------------------------------------------------- /Disruptor.TestTools/LatencyRecorder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/Pragmas.h" 6 | 7 | DISRUPTOR_PRAGMA_PUSH 8 | DISRUPTOR_PRAGMA_IGNORE_ALL 9 | DISRUPTOR_PRAGMA_IGNORE_UNREACHABLE_CODE 10 | DISRUPTOR_PRAGMA_IGNORE_DEPRECATED_DECLARATIONS 11 | #include 12 | #include 13 | DISRUPTOR_PRAGMA_POP 14 | 15 | 16 | namespace Disruptor 17 | { 18 | namespace Tests 19 | { 20 | 21 | class LatencyRecorder 22 | { 23 | using Accumulator = boost::accumulators::accumulator_set 24 | < 25 | double, 26 | boost::accumulators::stats 27 | < 28 | boost::accumulators::tag::mean, 29 | boost::accumulators::tag::max, 30 | boost::accumulators::tag::min, 31 | boost::accumulators::tag::variance, 32 | boost::accumulators::tag::tail_quantile< boost::accumulators::right > 33 | > 34 | >; 35 | 36 | public: 37 | explicit LatencyRecorder(std::int64_t sampleSize); 38 | 39 | void record(std::int64_t value); 40 | 41 | void writeReport(std::ostream& stream) const; 42 | 43 | private: 44 | Accumulator m_accumulator; 45 | }; 46 | 47 | } // namespace Tests 48 | } // namespace Disruptor 49 | -------------------------------------------------------------------------------- /Disruptor.TestTools/ManualResetEvent.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ManualResetEvent.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | ManualResetEvent::ManualResetEvent(bool signaled) 11 | : ResetEvent(signaled) 12 | { 13 | } 14 | 15 | void ManualResetEvent::set(bool ensureWaitIsTriggered) 16 | { 17 | ResetEvent::set(ensureWaitIsTriggered); 18 | } 19 | 20 | void ManualResetEvent::reset() 21 | { 22 | ResetEvent::reset(); 23 | } 24 | 25 | bool ManualResetEvent::isSet() const 26 | { 27 | return ResetEvent::isSet(); 28 | } 29 | 30 | bool ManualResetEvent::waitOne() 31 | { 32 | return wait(std::chrono::hours()); 33 | } 34 | 35 | bool ManualResetEvent::wait(ClockConfig::Duration timeDuration) 36 | { 37 | return ResetEvent::wait(timeDuration); 38 | } 39 | 40 | } // namespace Tests 41 | } // namespace Disruptor 42 | -------------------------------------------------------------------------------- /Disruptor.TestTools/ManualResetEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ClockConfig.h" 4 | 5 | #include "Disruptor.TestTools/ResetEvent.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | namespace Tests 11 | { 12 | 13 | class ManualResetEvent : public ResetEvent 14 | { 15 | public: 16 | explicit ManualResetEvent(bool signaled = false); 17 | 18 | bool isSet() const override; 19 | 20 | void set(bool ensureWaitIsTriggered = false) override; 21 | void reset() override; 22 | 23 | bool waitOne(); 24 | bool wait(ClockConfig::Duration timeDuration) override; 25 | }; 26 | 27 | } // namespace Tests 28 | } // namespace Disruptor 29 | -------------------------------------------------------------------------------- /Disruptor.TestTools/ResetEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/ClockConfig.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | namespace Tests 12 | { 13 | 14 | class ResetEvent 15 | { 16 | public: 17 | explicit ResetEvent(bool signaled = false); 18 | virtual ~ResetEvent() = default; 19 | 20 | ResetEvent(const ResetEvent&) = delete; 21 | 22 | protected: 23 | virtual bool isSet() const; 24 | 25 | virtual void set(bool ensureWaitIsTriggered = false); 26 | virtual void reset(); 27 | 28 | virtual bool wait(ClockConfig::Duration timeDuration); 29 | 30 | private: 31 | bool internalWait(ClockConfig::Duration timeDuration); 32 | 33 | bool m_signaled; 34 | mutable std::mutex m_mutex; 35 | std::condition_variable m_conditionVariable; 36 | int m_waitCount; 37 | }; 38 | 39 | } // namespace Tests 40 | } // namespace Disruptor 41 | -------------------------------------------------------------------------------- /Disruptor.TestTools/ScopeExitFunctor.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ScopeExitFunctor.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace TestTools 8 | { 9 | 10 | ScopeExitFunctor::ScopeExitFunctor(const std::function< void() >& func) 11 | : m_func(func) 12 | { 13 | } 14 | 15 | ScopeExitFunctor::~ScopeExitFunctor() 16 | { 17 | if (m_func) 18 | m_func(); 19 | } 20 | 21 | } // namespace TestTools 22 | } // namespace Disruptor 23 | -------------------------------------------------------------------------------- /Disruptor.TestTools/ScopeExitFunctor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace TestTools 9 | { 10 | 11 | class ScopeExitFunctor 12 | { 13 | public: 14 | explicit ScopeExitFunctor(const std::function< void() >& func); 15 | 16 | ~ScopeExitFunctor(); 17 | 18 | private: 19 | std::function< void() > m_func; 20 | }; 21 | 22 | } // namespace TestTools 23 | } // namespace Disruptor 24 | -------------------------------------------------------------------------------- /Disruptor.TestTools/Stopwatch.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Stopwatch.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace PerfTests 8 | { 9 | 10 | Stopwatch::Stopwatch() 11 | : m_isRunning(false) 12 | { 13 | m_begin = m_end = ClockConfig::Clock::now(); 14 | } 15 | 16 | ClockConfig::Duration Stopwatch::elapsed() const 17 | { 18 | if (isRunning()) 19 | m_end = ClockConfig::Clock::now(); 20 | 21 | return m_end - m_begin; 22 | } 23 | 24 | bool Stopwatch::isRunning() const 25 | { 26 | return !!m_isRunning && m_isRunning.get(); 27 | } 28 | 29 | void Stopwatch::reset() 30 | { 31 | stop(); 32 | m_begin = m_end; 33 | m_isRunning.reset(); 34 | } 35 | 36 | ClockConfig::TimePoint Stopwatch::restart() 37 | { 38 | reset(); 39 | start(); 40 | 41 | return m_begin; 42 | } 43 | 44 | void Stopwatch::start() 45 | { 46 | // Should we resume or start the StopWatch? 47 | if (!m_isRunning) 48 | { 49 | m_isRunning = true; 50 | m_begin = ClockConfig::Clock::now(); 51 | } 52 | else 53 | m_isRunning = true; 54 | } 55 | 56 | Stopwatch Stopwatch::startNew() 57 | { 58 | Stopwatch stopwatch; 59 | stopwatch.start(); 60 | 61 | return stopwatch; 62 | } 63 | 64 | std::int64_t Stopwatch::getTimestamp() 65 | { 66 | return static_cast< std::int64_t >(ClockConfig::Clock::now().time_since_epoch().count()); 67 | } 68 | 69 | void Stopwatch::stop() 70 | { 71 | m_end = ClockConfig::Clock::now(); 72 | m_isRunning = false; 73 | } 74 | 75 | } // namespace PerfTests 76 | } // namespace Disruptor 77 | -------------------------------------------------------------------------------- /Disruptor.TestTools/Stopwatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/ClockConfig.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | namespace PerfTests 12 | { 13 | 14 | class Stopwatch 15 | { 16 | public: 17 | Stopwatch(); 18 | 19 | ClockConfig::Duration elapsed() const; 20 | 21 | bool isRunning() const; 22 | 23 | static Stopwatch startNew(); 24 | 25 | static std::int64_t getTimestamp(); 26 | 27 | void start(); 28 | void stop(); 29 | 30 | void reset(); 31 | 32 | ClockConfig::TimePoint restart(); 33 | 34 | private: 35 | boost::optional< bool > m_isRunning; 36 | ClockConfig::TimePoint m_begin; 37 | mutable ClockConfig::TimePoint m_end; 38 | }; 39 | 40 | } // namespace PerfTests 41 | } // namespace Disruptor 42 | -------------------------------------------------------------------------------- /Disruptor.TestTools/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // disruptorLib.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /Disruptor.TestTools/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #if _MSC_VER // only on Windows 11 | 12 | # ifndef WIN32_LEAN_AND_MEAN 13 | # define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 14 | # endif 15 | 16 | # pragma warning(disable: 4512) // Assignment operator could not be generated 17 | 18 | # include "targetver.h" 19 | # include 20 | # include 21 | # include 22 | #endif 23 | 24 | // STL includes 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include -------------------------------------------------------------------------------- /Disruptor.TestTools/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /Disruptor.Tests/AggregateEventHandlerTestsFixture.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "AggregateEventHandlerTestsFixture.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | AggregateEventHandlerTestsFixture::AggregateEventHandlerTestsFixture() 11 | { 12 | m_eventHandlerMock1 = std::make_shared< testing::NiceMock< LifecycleAwareEventHandlerMock< std::int32_t > > >(); 13 | m_eventHandlerMock2 = std::make_shared< testing::NiceMock< LifecycleAwareEventHandlerMock< std::int32_t > > >(); 14 | m_eventHandlerMock3 = std::make_shared< testing::NiceMock< LifecycleAwareEventHandlerMock< std::int32_t > > >(); 15 | 16 | std::vector< std::shared_ptr< IEventHandler< std::int32_t > > > v = {m_eventHandlerMock1, m_eventHandlerMock2, m_eventHandlerMock3}; 17 | m_aggregateEventHandler = std::make_shared< AggregateEventHandler< std::int32_t > >(v); 18 | } 19 | 20 | } // namespace Tests 21 | } // namespace Disruptor 22 | -------------------------------------------------------------------------------- /Disruptor.Tests/AggregateEventHandlerTestsFixture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/AggregateEventHandler.h" 7 | 8 | #include "Disruptor.Tests/LifecycleAwareEventHandlerMock.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace Tests 14 | { 15 | 16 | struct AggregateEventHandlerTestsFixture 17 | { 18 | AggregateEventHandlerTestsFixture(); 19 | 20 | std::shared_ptr< LifecycleAwareEventHandlerMock< std::int32_t > > m_eventHandlerMock1; 21 | std::shared_ptr< LifecycleAwareEventHandlerMock< std::int32_t > > m_eventHandlerMock2; 22 | std::shared_ptr< LifecycleAwareEventHandlerMock< std::int32_t > > m_eventHandlerMock3; 23 | 24 | std::shared_ptr< AggregateEventHandler< std::int32_t > > m_aggregateEventHandler; 25 | }; 26 | 27 | } // namespace Tests 28 | } // namespace Disruptor 29 | -------------------------------------------------------------------------------- /Disruptor.Tests/AtomicReference.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace Tests 9 | { 10 | 11 | template 12 | class AtomicReference 13 | { 14 | public: 15 | explicit AtomicReference(const boost::optional< T >& value = boost::none) 16 | : m_value(value) 17 | { 18 | } 19 | 20 | boost::optional< T > read() 21 | { 22 | return m_value; 23 | } 24 | 25 | void write(const boost::optional< T >& value) 26 | { 27 | m_value = value; 28 | } 29 | 30 | private: 31 | boost::optional< T > m_value; 32 | }; 33 | 34 | } // namespace Tests 35 | } // namespace Disruptor 36 | -------------------------------------------------------------------------------- /Disruptor.Tests/BatchEventProcessorTestsFixture.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "BatchEventProcessorTestsFixture.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | BatchEventProcessorTestsFixture::BatchEventProcessorTestsFixture() 11 | : m_countDownEvent(1) 12 | { 13 | auto eventFactory = []() { return StubEvent(-1); }; 14 | 15 | m_ringBuffer = std::make_shared< RingBuffer< StubEvent > >(eventFactory, 16); 16 | m_sequenceBarrier = m_ringBuffer->newBarrier(); 17 | 18 | m_batchHandlerMock = std::make_shared< testing::NiceMock< BatchHandlerMock< StubEvent > > >(); 19 | m_excpetionHandlerMock = std::make_shared< testing::NiceMock< ExceptionHandlerMock< StubEvent > > >(); 20 | m_batchEventProcessor = std::make_shared< BatchEventProcessor< StubEvent > >(m_ringBuffer, m_sequenceBarrier, m_batchHandlerMock); 21 | } 22 | 23 | } // namespace Tests 24 | } // namespace Disruptor 25 | -------------------------------------------------------------------------------- /Disruptor.Tests/BatchEventProcessorTestsFixture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/BatchEventProcessor.h" 4 | #include "Disruptor/ISequenceBarrier.h" 5 | #include "Disruptor/RingBuffer.h" 6 | 7 | #include "Disruptor.TestTools/CountdownEvent.h" 8 | 9 | #include "Disruptor.Tests/BatchHandlerMock.h" 10 | #include "Disruptor.Tests/ExceptionHandlerMock.h" 11 | #include "Disruptor.Tests/StubEvent.h" 12 | 13 | 14 | namespace Disruptor 15 | { 16 | namespace Tests 17 | { 18 | 19 | struct BatchEventProcessorTestsFixture 20 | { 21 | BatchEventProcessorTestsFixture(); 22 | 23 | std::shared_ptr< RingBuffer< StubEvent > > m_ringBuffer; 24 | std::shared_ptr< ISequenceBarrier > m_sequenceBarrier; 25 | std::shared_ptr< BatchHandlerMock< StubEvent > > m_batchHandlerMock; 26 | std::shared_ptr< ExceptionHandlerMock< StubEvent > > m_excpetionHandlerMock; 27 | std::shared_ptr< BatchEventProcessor< StubEvent > > m_batchEventProcessor; 28 | CountdownEvent m_countDownEvent; 29 | }; 30 | 31 | } // namespace Tests 32 | } // namespace Disruptor 33 | -------------------------------------------------------------------------------- /Disruptor.Tests/BatchHandlerMock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "Disruptor/IEventHandler.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace Tests 14 | { 15 | 16 | template 17 | class BatchHandlerMock : public IEventHandler< T > 18 | { 19 | public: 20 | MOCK_METHOD3_T(onEvent, void(T& data, std::int64_t sequence, bool endOfBatch)); 21 | }; 22 | 23 | } // namespace Tests 24 | } // namespace Disruptor 25 | -------------------------------------------------------------------------------- /Disruptor.Tests/BusySpinWaitStrategyTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/BusySpinWaitStrategy.h" 4 | #include "WaitStrategyTestUtil.h" 5 | 6 | 7 | using namespace Disruptor; 8 | using namespace Disruptor::Tests; 9 | 10 | 11 | BOOST_AUTO_TEST_SUITE(BusySpinWaitStrategyTests) 12 | 13 | BOOST_AUTO_TEST_CASE(ShouldWaitForValue) 14 | { 15 | assertWaitForWithDelayOf(50, std::make_shared< BusySpinWaitStrategy >()); 16 | } 17 | 18 | BOOST_AUTO_TEST_SUITE_END() 19 | -------------------------------------------------------------------------------- /Disruptor.Tests/ConsumerRepositoryTestsFixture.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ConsumerRepositoryTestsFixture.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | ConsumerRepositoryTestsFixture::ConsumerRepositoryTestsFixture() 11 | : m_eventProcessor1(std::make_shared< testing::NiceMock< EventProcessorMock > >()) 12 | , m_eventProcessor2(std::make_shared< testing::NiceMock< EventProcessorMock > >()) 13 | , m_handler1(std::make_shared< SleepingEventHandler >()) 14 | , m_handler2(std::make_shared< SleepingEventHandler >()) 15 | , m_barrier1(std::make_shared< testing::NiceMock< SequenceBarrierMock > >()) 16 | , m_barrier2(std::make_shared< testing::NiceMock< SequenceBarrierMock > >()) 17 | { 18 | auto sequence1 = std::make_shared< Sequence >(); 19 | auto sequence2 = std::make_shared< Sequence >(); 20 | 21 | ON_CALL(*m_eventProcessor1, sequence()).WillByDefault(testing::Return(sequence1)); 22 | ON_CALL(*m_eventProcessor1, isRunning()).WillByDefault(testing::Return(true)); 23 | ON_CALL(*m_eventProcessor2, sequence()).WillByDefault(testing::Return(sequence1)); 24 | ON_CALL(*m_eventProcessor2, isRunning()).WillByDefault(testing::Return(true)); 25 | } 26 | 27 | } // namespace Tests 28 | } // namespace Disruptor 29 | -------------------------------------------------------------------------------- /Disruptor.Tests/ConsumerRepositoryTestsFixture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/ConsumerRepository.h" 6 | #include "Disruptor/Sequence.h" 7 | 8 | #include "Disruptor.Tests/EventProcessorMock.h" 9 | #include "Disruptor.Tests/SequenceBarrierMock.h" 10 | #include "Disruptor.Tests/SleepingEventHandler.h" 11 | 12 | 13 | namespace Disruptor 14 | { 15 | namespace Tests 16 | { 17 | 18 | struct ConsumerRepositoryTestsFixture 19 | { 20 | ConsumerRepositoryTestsFixture(); 21 | 22 | std::shared_ptr< EventProcessorMock > m_eventProcessor1; 23 | std::shared_ptr< EventProcessorMock > m_eventProcessor2; 24 | std::shared_ptr< SleepingEventHandler > m_handler1; 25 | std::shared_ptr< SleepingEventHandler > m_handler2; 26 | std::shared_ptr< SequenceBarrierMock > m_barrier1; 27 | std::shared_ptr< SequenceBarrierMock > m_barrier2; 28 | ConsumerRepository< TestEvent > m_consumerRepository; 29 | }; 30 | 31 | } // namespace Tests 32 | } // namespace Disruptor 33 | -------------------------------------------------------------------------------- /Disruptor.Tests/DataProviderMock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "Disruptor/IDataProvider.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace Tests 14 | { 15 | 16 | template 17 | class DataProviderMock : public IDataProvider< T > 18 | { 19 | public: 20 | MOCK_CONST_METHOD1_T(indexer, T&(std::int64_t sequence)); 21 | 22 | T& operator[](std::int64_t sequence) const override 23 | { 24 | return this->indexer(sequence); 25 | } 26 | }; 27 | 28 | } // namespace Tests 29 | } // namespace Disruptor 30 | -------------------------------------------------------------------------------- /Disruptor.Tests/DelayedEventHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "DelayedEventHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | DelayedEventHandler::DelayedEventHandler() 11 | : DelayedEventHandler(std::make_shared< boost::barrier >(2)) 12 | {} 13 | 14 | void DelayedEventHandler::onEvent(TestEvent& /*data*/, std::int64_t /*sequence*/, bool /*endOfBatch*/) 15 | { 16 | waitForAndSetFlag(0); 17 | } 18 | 19 | void DelayedEventHandler::processEvent() 20 | { 21 | waitForAndSetFlag(1); 22 | } 23 | 24 | void DelayedEventHandler::stopWaiting() 25 | { 26 | m_stopped = true; 27 | } 28 | 29 | void DelayedEventHandler::onStart() 30 | { 31 | try 32 | { 33 | m_barrier->wait(); 34 | } 35 | catch (std::exception& ex) 36 | { 37 | throw std::runtime_error(ex.what()); 38 | } 39 | } 40 | 41 | void DelayedEventHandler::onShutdown() 42 | { 43 | } 44 | 45 | void DelayedEventHandler::awaitStart() 46 | { 47 | m_barrier->wait(); 48 | } 49 | 50 | DelayedEventHandler::DelayedEventHandler(const std::shared_ptr< boost::barrier >& barrier) 51 | : m_readyToProcessEvent(0) 52 | , m_stopped(false) 53 | , m_barrier(barrier) 54 | { 55 | } 56 | 57 | void DelayedEventHandler::waitForAndSetFlag(std::int32_t newValue) 58 | { 59 | while (!m_stopped && std::atomic_exchange(&m_readyToProcessEvent, newValue) == newValue) 60 | { 61 | std::this_thread::yield(); 62 | } 63 | } 64 | 65 | } // namespace Tests 66 | } // namespace Disruptor 67 | 68 | -------------------------------------------------------------------------------- /Disruptor.Tests/DelayedEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "Disruptor/IEventHandler.h" 10 | #include "Disruptor/ILifecycleAware.h" 11 | 12 | #include "Disruptor.Tests/TestEvent.h" 13 | 14 | 15 | namespace Disruptor 16 | { 17 | namespace Tests 18 | { 19 | 20 | class DelayedEventHandler : public IEventHandler< TestEvent >, public ILifecycleAware 21 | { 22 | public: 23 | DelayedEventHandler(); 24 | 25 | void onEvent(TestEvent& data, std::int64_t sequence, bool endOfBatch) override; 26 | 27 | void processEvent(); 28 | 29 | void stopWaiting(); 30 | 31 | void onStart() override; 32 | 33 | void onShutdown() override; 34 | 35 | void awaitStart(); 36 | 37 | private: 38 | explicit DelayedEventHandler(const std::shared_ptr< boost::barrier >& barrier); 39 | 40 | void waitForAndSetFlag(std::int32_t newValue); 41 | 42 | std::atomic< std::int32_t > m_readyToProcessEvent; 43 | std::atomic< bool > m_stopped; 44 | std::shared_ptr< boost::barrier > m_barrier; 45 | }; 46 | 47 | } // namespace Tests 48 | } // namespace Disruptor 49 | -------------------------------------------------------------------------------- /Disruptor.Tests/DummySequenceBarrier.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "DummySequenceBarrier.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | std::int64_t DummySequenceBarrier::waitFor(std::int64_t) 11 | { 12 | return 0; 13 | } 14 | 15 | std::int64_t DummySequenceBarrier::cursor() 16 | { 17 | return 0; 18 | } 19 | 20 | bool DummySequenceBarrier::isAlerted() 21 | { 22 | return false; 23 | } 24 | 25 | void DummySequenceBarrier::alert() 26 | { 27 | } 28 | 29 | void DummySequenceBarrier::clearAlert() 30 | { 31 | } 32 | 33 | void DummySequenceBarrier::checkAlert() 34 | { 35 | } 36 | 37 | } // namespace Tests 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor.Tests/DummySequenceBarrier.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ISequenceBarrier.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace Tests 9 | { 10 | 11 | class DummySequenceBarrier : public ISequenceBarrier 12 | { 13 | public: 14 | std::int64_t waitFor(std::int64_t sequence) override; 15 | 16 | std::int64_t cursor() override; 17 | 18 | bool isAlerted() override; 19 | void alert() override; 20 | 21 | void clearAlert() override; 22 | void checkAlert() override; 23 | }; 24 | 25 | } // namespace Tests 26 | } // namespace Disruptor 27 | -------------------------------------------------------------------------------- /Disruptor.Tests/EventHandlerStub.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IEventHandler.h" 6 | 7 | #include "Disruptor.TestTools/CountdownEvent.h" 8 | 9 | 10 | namespace Disruptor 11 | { 12 | namespace Tests 13 | { 14 | 15 | template 16 | class EventHandlerStub : public IEventHandler< T > 17 | { 18 | public: 19 | explicit EventHandlerStub(const std::shared_ptr< CountdownEvent >& countDownLatch) 20 | : m_countDownLatch(countDownLatch) 21 | { 22 | } 23 | 24 | void onEvent(T& /*data*/, std::int64_t /*sequence*/, bool /*endOfBatch*/) override 25 | { 26 | m_countDownLatch->signal(); 27 | } 28 | 29 | private: 30 | std::shared_ptr< CountdownEvent > m_countDownLatch; 31 | }; 32 | 33 | } // namespace Tests 34 | } // namespace Disruptor 35 | -------------------------------------------------------------------------------- /Disruptor.Tests/EventProcessorMock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IEventProcessor.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | namespace Tests 11 | { 12 | 13 | class EventProcessorMock : public IEventProcessor 14 | { 15 | public: 16 | MOCK_CONST_METHOD0(sequence, std::shared_ptr< ISequence >()); 17 | 18 | MOCK_METHOD0(halt, void()); 19 | MOCK_METHOD0(run, void()); 20 | 21 | MOCK_CONST_METHOD0(isRunning, bool()); 22 | }; 23 | 24 | } // namespace Tests 25 | } // namespace Disruptor 26 | -------------------------------------------------------------------------------- /Disruptor.Tests/ExceptionHandlerMock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "Disruptor/IExceptionHandler.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace Tests 14 | { 15 | 16 | template 17 | class ExceptionHandlerMock : public IExceptionHandler< T > 18 | { 19 | public: 20 | MOCK_METHOD3_T(handleEventException, void(const std::exception&, std::int64_t, T&)); 21 | MOCK_METHOD1(handleOnStartException, void(const std::exception&)); 22 | MOCK_METHOD1(handleOnShutdownException, void(const std::exception&)); 23 | MOCK_METHOD2_T(handleOnTimeoutException, void (const std::exception&, std::int64_t)); 24 | }; 25 | 26 | } // namespace Tests 27 | } // namespace Disruptor 28 | -------------------------------------------------------------------------------- /Disruptor.Tests/ExceptionThrowingEventHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ExceptionThrowingEventHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | ExceptionThrowingEventHandler::ExceptionThrowingEventHandler(const std::exception& applicationException) 11 | : m_applicationException(applicationException) 12 | { 13 | } 14 | 15 | void ExceptionThrowingEventHandler::onEvent(TestEvent& /*data*/, std::int64_t /*sequence*/, bool /*endOfBatch*/) 16 | { 17 | throw m_applicationException; 18 | } 19 | 20 | } // namespace Tests 21 | } // namespace Disruptor 22 | -------------------------------------------------------------------------------- /Disruptor.Tests/ExceptionThrowingEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IEventHandler.h" 6 | 7 | #include "Disruptor.Tests/TestEvent.h" 8 | 9 | 10 | namespace Disruptor 11 | { 12 | namespace Tests 13 | { 14 | 15 | class ExceptionThrowingEventHandler : public IEventHandler< TestEvent > 16 | { 17 | public: 18 | explicit ExceptionThrowingEventHandler(const std::exception& applicationException); 19 | 20 | void onEvent(TestEvent& data, std::int64_t sequence, bool endOfBatch) override; 21 | 22 | private: 23 | std::exception m_applicationException; 24 | }; 25 | 26 | } // namespace Tests 27 | } // namespace Disruptor 28 | -------------------------------------------------------------------------------- /Disruptor.Tests/FatalExceptionHandlerTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/ArgumentException.h" 4 | #include "Disruptor/FatalExceptionHandler.h" 5 | #include "StubEvent.h" 6 | 7 | 8 | using namespace Disruptor; 9 | 10 | 11 | BOOST_AUTO_TEST_SUITE(FatalExceptionHandlerTests) 12 | 13 | BOOST_AUTO_TEST_CASE(ShouldHandleFatalException) 14 | { 15 | auto causeException = ArgumentException("FatalExceptionHandlerTests.ShouldHandleFatalException"); 16 | auto evt = Tests::StubEvent(0); 17 | 18 | auto exceptionHandler = std::make_shared< FatalExceptionHandler< Tests::StubEvent> >(); 19 | 20 | try 21 | { 22 | exceptionHandler->handleEventException(causeException, 0L, evt); 23 | } 24 | catch (FatalException& ex) 25 | { 26 | BOOST_CHECK_EQUAL(causeException.what(), ex.innerException().what()); 27 | } 28 | } 29 | 30 | BOOST_AUTO_TEST_SUITE_END() -------------------------------------------------------------------------------- /Disruptor.Tests/FixedSequenceGroupTest.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/FixedSequenceGroup.h" 4 | #include "Disruptor/Sequence.h" 5 | 6 | 7 | using namespace Disruptor; 8 | 9 | 10 | BOOST_AUTO_TEST_SUITE(FixedSequenceGroupTest) 11 | 12 | BOOST_AUTO_TEST_CASE(ShouldReturnMinimumOf2Sequences) 13 | { 14 | auto sequence1 = std::make_shared< Sequence >(34); 15 | auto sequence2 = std::make_shared< Sequence >(47); 16 | FixedSequenceGroup group({ sequence1, sequence2 }); 17 | 18 | BOOST_CHECK_EQUAL(group.value(), 34L); 19 | sequence1->setValue(35); 20 | BOOST_CHECK_EQUAL(group.value(), 35L); 21 | sequence1->setValue(48); 22 | BOOST_CHECK_EQUAL(group.value(), 47L); 23 | } 24 | 25 | BOOST_AUTO_TEST_SUITE_END() 26 | -------------------------------------------------------------------------------- /Disruptor.Tests/IgnoreExceptionHandlerTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/ArgumentException.h" 4 | #include "Disruptor/IgnoreExceptionHandler.h" 5 | #include "StubEvent.h" 6 | 7 | 8 | using namespace Disruptor; 9 | 10 | 11 | BOOST_AUTO_TEST_SUITE(IgnoreExceptionHandlerTests) 12 | 13 | BOOST_AUTO_TEST_CASE(ShouldIgnoreException) 14 | { 15 | auto causeException = ArgumentException("IgnoreExceptionHandler.ShouldIgnoreException"); 16 | auto evt = Tests::StubEvent(0); 17 | 18 | auto exceptionHandler = std::make_shared< IgnoreExceptionHandler< Tests::StubEvent> >(); 19 | 20 | BOOST_CHECK_NO_THROW(exceptionHandler->handleEventException(causeException, 0L, evt)); 21 | } 22 | 23 | BOOST_AUTO_TEST_SUITE_END() 24 | -------------------------------------------------------------------------------- /Disruptor.Tests/LifecycleAwareEventHandlerMock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "Disruptor/IEventHandler.h" 9 | #include "Disruptor/ILifecycleAware.h" 10 | 11 | 12 | namespace Disruptor 13 | { 14 | namespace Tests 15 | { 16 | 17 | template 18 | class LifecycleAwareEventHandlerMock : public IEventHandler< T >, public ILifecycleAware 19 | { 20 | public: 21 | MOCK_METHOD3_T(onEvent, void(T& data, std::int64_t sequence, bool endOfBatch)); 22 | MOCK_METHOD0(onStart, void()); 23 | MOCK_METHOD0(onShutdown, void()); 24 | }; 25 | 26 | } // namespace Tests 27 | } // namespace Disruptor 28 | -------------------------------------------------------------------------------- /Disruptor.Tests/LongEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace Tests 9 | { 10 | 11 | class LongEvent 12 | { 13 | public: 14 | std::int64_t value = 0; 15 | }; 16 | 17 | } // namespace Tests 18 | } // namespace Disruptor 19 | -------------------------------------------------------------------------------- /Disruptor.Tests/MultiProducerSequencerTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/BlockingWaitStrategy.h" 4 | #include "Disruptor/MultiProducerSequencer.h" 5 | 6 | 7 | using namespace Disruptor; 8 | 9 | 10 | BOOST_AUTO_TEST_SUITE(MultiProducerSequencerTests) 11 | 12 | BOOST_AUTO_TEST_CASE(ShouldOnlyAllowMessagesToBeAvailableIfSpecificallyPublished) 13 | { 14 | auto waitingStrategy = std::make_shared< BlockingWaitStrategy >(); 15 | auto publisher = std::make_shared< MultiProducerSequencer< int > >(1024, waitingStrategy); 16 | 17 | publisher->publish(3); 18 | publisher->publish(5); 19 | 20 | BOOST_CHECK_EQUAL(publisher->isAvailable(0), false); 21 | BOOST_CHECK_EQUAL(publisher->isAvailable(1), false); 22 | BOOST_CHECK_EQUAL(publisher->isAvailable(2), false); 23 | BOOST_CHECK_EQUAL(publisher->isAvailable(3), true ); 24 | BOOST_CHECK_EQUAL(publisher->isAvailable(4), false); 25 | BOOST_CHECK_EQUAL(publisher->isAvailable(5), true ); 26 | BOOST_CHECK_EQUAL(publisher->isAvailable(6), false); 27 | } 28 | 29 | BOOST_AUTO_TEST_SUITE_END() 30 | -------------------------------------------------------------------------------- /Disruptor.Tests/SequenceBarrierMock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/ISequenceBarrier.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | namespace Tests 11 | { 12 | 13 | class SequenceBarrierMock : public ISequenceBarrier 14 | { 15 | public: 16 | MOCK_METHOD1(waitFor, std::int64_t(std::int64_t sequence)); 17 | 18 | MOCK_METHOD0(cursor, std::int64_t()); 19 | 20 | MOCK_METHOD0(isAlerted, bool()); 21 | MOCK_METHOD0(alert, void()); 22 | 23 | MOCK_METHOD0(clearAlert, void()); 24 | MOCK_METHOD0(checkAlert, void()); 25 | }; 26 | 27 | } // namespace Tests 28 | } // namespace Disruptor 29 | -------------------------------------------------------------------------------- /Disruptor.Tests/SequenceUpdater.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SequenceUpdater.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | SequenceUpdater::SequenceUpdater(std::int64_t sleepTime, const std::shared_ptr< IWaitStrategy >& waitStrategy) 11 | : m_barrier(2) 12 | , m_sleepTime(static_cast< std::int32_t >(sleepTime)) 13 | , m_waitStrategy(waitStrategy) 14 | { 15 | } 16 | 17 | void SequenceUpdater::run() 18 | { 19 | try 20 | { 21 | m_barrier.signal(); 22 | m_barrier.wait(); 23 | if (0 != m_sleepTime) 24 | { 25 | std::this_thread::sleep_for(std::chrono::milliseconds(m_sleepTime)); 26 | } 27 | sequence->incrementAndGet(); 28 | m_waitStrategy->signalAllWhenBlocking(); 29 | } 30 | catch (std::exception& ex) 31 | { 32 | std::cout << ex.what() << std::endl; 33 | } 34 | } 35 | 36 | void SequenceUpdater::waitForStartup() 37 | { 38 | m_barrier.signal(); 39 | m_barrier.wait(); 40 | } 41 | 42 | } // namespace Tests 43 | } // namespace Disruptor 44 | -------------------------------------------------------------------------------- /Disruptor.Tests/SequenceUpdater.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IWaitStrategy.h" 6 | #include "Disruptor/Sequence.h" 7 | 8 | #include "Disruptor.TestTools/CountdownEvent.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace Tests 14 | { 15 | 16 | class SequenceUpdater 17 | { 18 | public: 19 | SequenceUpdater(std::int64_t sleepTime, const std::shared_ptr< IWaitStrategy >& waitStrategy); 20 | 21 | void run(); 22 | 23 | void waitForStartup(); 24 | 25 | std::shared_ptr< Sequence > sequence = std::make_shared< Sequence >(); 26 | 27 | private: 28 | CountdownEvent m_barrier; 29 | std::int32_t m_sleepTime = 0; 30 | std::shared_ptr< IWaitStrategy > m_waitStrategy; 31 | }; 32 | 33 | } // namespace Tests 34 | } // namespace Disruptor 35 | -------------------------------------------------------------------------------- /Disruptor.Tests/SequencerFixture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/BlockingWaitStrategy.h" 4 | #include "Disruptor/MultiProducerSequencer.h" 5 | #include "Disruptor/Sequence.h" 6 | #include "Disruptor/SingleProducerSequencer.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | namespace Tests 12 | { 13 | 14 | template 15 | struct SequencerTestFixture 16 | { 17 | SequencerTestFixture() 18 | : m_waitStrategy(std::make_shared< BlockingWaitStrategy >()) 19 | , m_sequencer(std::make_shared< T >(m_bufferSize, m_waitStrategy)) 20 | , m_gatingSequence(std::make_shared< Sequence >()) 21 | {} 22 | 23 | const std::int32_t m_bufferSize = 16; 24 | std::shared_ptr< IWaitStrategy > m_waitStrategy; 25 | std::shared_ptr< T > m_sequencer; 26 | std::shared_ptr< Sequence > m_gatingSequence; 27 | }; 28 | 29 | } // namespace Tests 30 | } // namespace Disruptor 31 | -------------------------------------------------------------------------------- /Disruptor.Tests/SleepingEventHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SleepingEventHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | void SleepingEventHandler::onEvent(TestEvent& /*data*/, std::int64_t /*sequence*/, bool /*endOfBatch*/) 11 | { 12 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 13 | } 14 | 15 | } // namespace Tests 16 | } // namespace Disruptor 17 | -------------------------------------------------------------------------------- /Disruptor.Tests/SleepingEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/IEventHandler.h" 4 | 5 | #include "Disruptor.Tests/TestEvent.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | namespace Tests 11 | { 12 | 13 | class SleepingEventHandler : public IEventHandler< TestEvent > 14 | { 15 | public: 16 | void onEvent(TestEvent& data, std::int64_t sequence, bool endOfBatch) override; 17 | }; 18 | 19 | } // namespace Tests 20 | } // namespace Disruptor 21 | -------------------------------------------------------------------------------- /Disruptor.Tests/SleepingWaitStrategyTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/SleepingWaitStrategy.h" 4 | #include "WaitStrategyTestUtil.h" 5 | 6 | 7 | using namespace Disruptor; 8 | using namespace Disruptor::Tests; 9 | 10 | 11 | BOOST_AUTO_TEST_SUITE(SleepingWaitStrategyTests) 12 | 13 | BOOST_AUTO_TEST_CASE(ShouldWaitForValue) 14 | { 15 | assertWaitForWithDelayOf(50, std::make_shared< SleepingWaitStrategy >()); 16 | } 17 | 18 | BOOST_AUTO_TEST_SUITE_END() 19 | -------------------------------------------------------------------------------- /Disruptor.Tests/SpinWaitWaitStrategyTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/SpinWaitWaitStrategy.h" 4 | #include "WaitStrategyTestUtil.h" 5 | 6 | 7 | using namespace Disruptor; 8 | using namespace Disruptor::Tests; 9 | 10 | 11 | BOOST_AUTO_TEST_SUITE(SpinWaitWaitStrategyTests) 12 | 13 | BOOST_AUTO_TEST_CASE(ShouldWaitForValue) 14 | { 15 | assertWaitForWithDelayOf(50, std::make_shared< SpinWaitWaitStrategy >()); 16 | } 17 | 18 | BOOST_AUTO_TEST_SUITE_END() 19 | -------------------------------------------------------------------------------- /Disruptor.Tests/StubEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/IEventTranslatorVararg.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | namespace Tests 12 | { 13 | 14 | class StubEvent 15 | { 16 | typedef IEventTranslatorVararg< StubEvent, std::int32_t, std::string > EventTranslatorType; 17 | 18 | class TwoTranslator : public EventTranslatorType 19 | { 20 | public: 21 | void translateTo(StubEvent& event, std::int64_t sequence, const std::int32_t& arg0, const std::string& arg1) override; 22 | }; 23 | 24 | public: 25 | StubEvent() 26 | : m_value(0) 27 | , m_testString() 28 | {} 29 | 30 | explicit StubEvent(int i); 31 | 32 | void operator=(const StubEvent& other) 33 | { 34 | m_value = other.m_value; 35 | m_testString = other.m_testString; 36 | } 37 | 38 | int value() const; 39 | void value(int i); 40 | 41 | std::string testString() const; 42 | void testString(std::string x); 43 | 44 | void copy(const StubEvent& evt); 45 | 46 | bool operator==(const StubEvent& rhs) const; 47 | 48 | static const std::shared_ptr< TwoTranslator >& translator(); 49 | 50 | static const std::function< StubEvent() >& eventFactory(); 51 | 52 | private: 53 | int m_value; 54 | std::string m_testString; 55 | }; 56 | 57 | } // namespace Tests 58 | } // namespace Disruptor 59 | 60 | 61 | #include 62 | 63 | 64 | namespace std 65 | { 66 | 67 | ostream& operator<<(ostream& stream, const Disruptor::Tests::StubEvent& event); 68 | 69 | } // namespace std 70 | -------------------------------------------------------------------------------- /Disruptor.Tests/StubExceptionHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/IExceptionHandler.h" 4 | 5 | #include "Disruptor.Tests/AtomicReference.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | namespace Tests 11 | { 12 | 13 | template 14 | class StubExceptionHandler : public IExceptionHandler< T > 15 | { 16 | public: 17 | explicit StubExceptionHandler(const std::shared_ptr< AtomicReference< std::exception > >& exceptionHandled) 18 | : m_exceptionHandled(exceptionHandled) 19 | { 20 | } 21 | 22 | void handleEventException(const std::exception& ex, std::int64_t /*sequence*/, T& /*evt*/) override 23 | { 24 | m_exceptionHandled->write(ex); 25 | } 26 | 27 | void handleOnStartException(const std::exception& ex) override 28 | { 29 | m_exceptionHandled->write(ex); 30 | } 31 | 32 | void handleOnShutdownException(const std::exception& ex) override 33 | { 34 | m_exceptionHandled->write(ex); 35 | } 36 | 37 | void handleOnTimeoutException(const std::exception& ex, std::int64_t /*sequence*/) override 38 | { 39 | m_exceptionHandled->write(ex); 40 | } 41 | 42 | private: 43 | std::shared_ptr< AtomicReference< std::exception > > m_exceptionHandled; 44 | }; 45 | 46 | } // namespace Tests 47 | } // namespace Disruptor 48 | -------------------------------------------------------------------------------- /Disruptor.Tests/StubExecutor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "Disruptor/IExecutor.h" 10 | 11 | 12 | namespace Disruptor 13 | { 14 | namespace Tests 15 | { 16 | 17 | class StubExecutor : public IExecutor 18 | { 19 | public: 20 | StubExecutor() 21 | : m_ignoreExecutions(false) 22 | , m_executionCount(0) 23 | {} 24 | 25 | std::future< void > execute(const std::function< void() >& command) override; 26 | 27 | void joinAllThreads(); 28 | 29 | void ignoreExecutions(); 30 | 31 | std::int32_t getExecutionCount() const; 32 | 33 | private: 34 | std::recursive_mutex m_mutex; 35 | std::deque< boost::thread > m_threads; 36 | std::atomic< bool > m_ignoreExecutions; 37 | std::atomic< std::int32_t > m_executionCount; 38 | }; 39 | 40 | } // namespace Tests 41 | } // namespace Disruptor 42 | 43 | -------------------------------------------------------------------------------- /Disruptor.Tests/StubPublisher.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "stdafx.h" 3 | #include "StubPublisher.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | namespace Tests 9 | { 10 | 11 | StubPublisher::StubPublisher(const std::shared_ptr< RingBuffer< TestEvent > >& ringBuffer) 12 | : m_running(true) 13 | , m_publicationCount(0) 14 | { 15 | m_ringBuffer = ringBuffer; 16 | } 17 | 18 | void StubPublisher::run() 19 | { 20 | while (m_running) 21 | { 22 | auto sequence = m_ringBuffer->next(); 23 | m_ringBuffer->publish(sequence); 24 | ++m_publicationCount; 25 | } 26 | } 27 | 28 | std::int32_t StubPublisher::getPublicationCount() const 29 | { 30 | return m_publicationCount; 31 | } 32 | 33 | void StubPublisher::halt() 34 | { 35 | m_running = false; 36 | } 37 | 38 | } // namespace Tests 39 | } // namespace Disruptor 40 | 41 | -------------------------------------------------------------------------------- /Disruptor.Tests/StubPublisher.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "Disruptor/RingBuffer.h" 8 | 9 | #include "Disruptor.Tests/TestEvent.h" 10 | 11 | 12 | namespace Disruptor 13 | { 14 | namespace Tests 15 | { 16 | 17 | class StubPublisher 18 | { 19 | public: 20 | explicit StubPublisher(const std::shared_ptr< RingBuffer< TestEvent > >& ringBuffer); 21 | 22 | void run(); 23 | 24 | std::int32_t getPublicationCount() const; 25 | 26 | void halt(); 27 | 28 | private: 29 | std::atomic< bool > m_running; 30 | std::atomic< std::int32_t > m_publicationCount; 31 | 32 | std::shared_ptr< RingBuffer< TestEvent > > m_ringBuffer; 33 | }; 34 | 35 | } // namespace Tests 36 | } // namespace Disruptor 37 | -------------------------------------------------------------------------------- /Disruptor.Tests/TestEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Disruptor 5 | { 6 | namespace Tests 7 | { 8 | 9 | class TestEvent 10 | { 11 | }; 12 | 13 | } // namespace Tests 14 | } // namespace Disruptor 15 | -------------------------------------------------------------------------------- /Disruptor.Tests/TestWaiter.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "TestWaiter.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | TestWaiter::TestWaiter(const std::shared_ptr< boost::barrier >& barrier, 11 | const std::shared_ptr< ISequenceBarrier >& sequenceBarrier, 12 | const std::shared_ptr< RingBuffer< StubEvent > >& ringBuffer, 13 | std::int64_t initialSequence, 14 | std::int64_t toWaitForSequence) 15 | : m_barrier(barrier) 16 | , m_sequenceBarrier(sequenceBarrier) 17 | , m_ringBuffer(ringBuffer) 18 | , m_initialSequence(initialSequence) 19 | , m_toWaitForSequence(toWaitForSequence) 20 | { 21 | } 22 | 23 | std::vector< StubEvent > TestWaiter::call() const 24 | { 25 | m_barrier->wait(); 26 | m_sequenceBarrier->waitFor(m_toWaitForSequence); 27 | 28 | std::vector< StubEvent > events; 29 | for (auto l = m_initialSequence; l <= m_toWaitForSequence; ++l) 30 | { 31 | events.push_back((*m_ringBuffer)[l]); 32 | } 33 | 34 | return events; 35 | } 36 | 37 | } // namespace Tests 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor.Tests/TestWaiter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/ISequenceBarrier.h" 7 | #include "Disruptor/RingBuffer.h" 8 | 9 | #include "Disruptor.Tests/StubEvent.h" 10 | 11 | 12 | namespace Disruptor 13 | { 14 | namespace Tests 15 | { 16 | 17 | class TestWaiter 18 | { 19 | public: 20 | TestWaiter(const std::shared_ptr< boost::barrier >& barrier, 21 | const std::shared_ptr< ISequenceBarrier >& sequenceBarrier, 22 | const std::shared_ptr< RingBuffer< StubEvent > >& ringBuffer, 23 | std::int64_t initialSequence, 24 | std::int64_t toWaitForSequence); 25 | 26 | std::vector< StubEvent > call() const; 27 | 28 | private: 29 | std::shared_ptr< boost::barrier > m_barrier; 30 | std::shared_ptr< ISequenceBarrier > m_sequenceBarrier; 31 | std::shared_ptr< RingBuffer< StubEvent > > m_ringBuffer; 32 | std::int64_t m_initialSequence; 33 | std::int64_t m_toWaitForSequence; 34 | }; 35 | 36 | } // namespace Tests 37 | } // namespace Disruptor 38 | -------------------------------------------------------------------------------- /Disruptor.Tests/TestWorkHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "TestWorkHandler.h" 3 | 4 | 5 | namespace Disruptor 6 | { 7 | namespace Tests 8 | { 9 | 10 | void TestWorkHandler::onEvent(TestEvent& /*evt*/) 11 | { 12 | waitForAndSetFlag(0); 13 | } 14 | 15 | void TestWorkHandler::processEvent() 16 | { 17 | waitForAndSetFlag(1); 18 | } 19 | 20 | void TestWorkHandler::stopWaiting() 21 | { 22 | m_stopped = true; 23 | } 24 | 25 | void TestWorkHandler::waitForAndSetFlag(std::int32_t newValue) 26 | { 27 | while (!m_stopped && std::atomic_exchange(&m_readyToProcessEvent, newValue) == newValue) 28 | { 29 | std::this_thread::yield(); 30 | } 31 | } 32 | 33 | } // namespace Tests 34 | } // namespace Disruptor 35 | -------------------------------------------------------------------------------- /Disruptor.Tests/TestWorkHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/IWorkHandler.h" 7 | 8 | #include "Disruptor.Tests/TestEvent.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace Tests 14 | { 15 | 16 | class TestWorkHandler : public IWorkHandler< TestEvent > 17 | { 18 | public: 19 | TestWorkHandler() 20 | : m_readyToProcessEvent(0) 21 | , m_stopped(false) 22 | {} 23 | 24 | void onEvent(TestEvent& evt) override; 25 | 26 | void processEvent(); 27 | 28 | void stopWaiting(); 29 | 30 | private: 31 | void waitForAndSetFlag(std::int32_t newValue); 32 | 33 | std::atomic< std::int32_t > m_readyToProcessEvent; 34 | std::atomic< bool > m_stopped; 35 | }; 36 | 37 | } // namespace Tests 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor.Tests/TimeoutBlockingWaitStrategyTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/Sequence.h" 4 | #include "Disruptor/TimeoutBlockingWaitStrategy.h" 5 | #include "Disruptor/TimeoutException.h" 6 | 7 | #include "SequenceBarrierMock.h" 8 | 9 | 10 | using namespace Disruptor; 11 | 12 | 13 | BOOST_AUTO_TEST_SUITE(TimeoutBlockingWaitStrategyTest) 14 | 15 | BOOST_AUTO_TEST_CASE(ShouldTimeoutWaitFor) 16 | { 17 | auto sequenceBarrierMock = std::make_shared< testing::NiceMock< Tests::SequenceBarrierMock > >(); 18 | 19 | auto theTimeout = std::chrono::milliseconds(500); 20 | auto waitStrategy = std::make_shared< TimeoutBlockingWaitStrategy >(theTimeout); 21 | auto cursor = std::make_shared< Sequence >(5); 22 | const auto& dependent = cursor; 23 | 24 | EXPECT_CALL(*sequenceBarrierMock, checkAlert()).Times(testing::AtLeast(1)); 25 | 26 | auto t0 = ClockConfig::Clock::now(); 27 | 28 | try 29 | { 30 | waitStrategy->waitFor(6, *cursor, *dependent, *sequenceBarrierMock); 31 | throw std::runtime_error("TimeoutException should have been thrown"); 32 | } 33 | catch (TimeoutException&) 34 | { 35 | } 36 | 37 | auto t1 = ClockConfig::Clock::now(); 38 | 39 | auto timeWaiting = t1 - t0; 40 | 41 | BOOST_CHECK(timeWaiting >= theTimeout); 42 | } 43 | 44 | BOOST_AUTO_TEST_SUITE_END() 45 | -------------------------------------------------------------------------------- /Disruptor.Tests/UtilTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/Sequence.h" 4 | #include "Disruptor/Util.h" 5 | 6 | 7 | using namespace Disruptor; 8 | 9 | 10 | BOOST_AUTO_TEST_SUITE(UtilTests) 11 | 12 | BOOST_AUTO_TEST_CASE(ShouldReturnNextPowerOfTwo) 13 | { 14 | auto powerOfTwo = Util::ceilingNextPowerOfTwo(1000); 15 | 16 | BOOST_CHECK_EQUAL(1024, powerOfTwo); 17 | } 18 | 19 | BOOST_AUTO_TEST_CASE(ShouldReturnExactPowerOfTwo) 20 | { 21 | auto powerOfTwo = Util::ceilingNextPowerOfTwo(1024); 22 | 23 | BOOST_CHECK_EQUAL(1024, powerOfTwo); 24 | } 25 | 26 | BOOST_AUTO_TEST_CASE(ShouldReturnMinimumSequence) 27 | { 28 | BOOST_CHECK_EQUAL(4L, Util::getMinimumSequence({ std::make_shared< Sequence >(11), std::make_shared< Sequence >(4), std::make_shared< Sequence >(13) })); 29 | } 30 | 31 | BOOST_AUTO_TEST_CASE(ShouldReturnLongMaxWhenNoEventProcessors) 32 | { 33 | BOOST_CHECK_EQUAL(std::numeric_limits< std::int64_t >::max(), Util::getMinimumSequence({ })); 34 | } 35 | 36 | BOOST_AUTO_TEST_SUITE_END() 37 | -------------------------------------------------------------------------------- /Disruptor.Tests/WaitStrategyMock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "Disruptor/IWaitStrategy.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace Tests 14 | { 15 | 16 | class WaitStrategyMock : public IWaitStrategy 17 | { 18 | public: 19 | MOCK_METHOD4(waitFor, std::int64_t(std::int64_t sequence, Sequence& cursor, ISequence& dependentSequence, ISequenceBarrier& barrier)); 20 | 21 | MOCK_METHOD0(signalAllWhenBlocking, void()); 22 | 23 | MOCK_CONST_METHOD1(writeDescriptionTo, void(std::ostream& stream)); 24 | }; 25 | 26 | } // namespace Tests 27 | } // namespace Disruptor 28 | -------------------------------------------------------------------------------- /Disruptor.Tests/WaitStrategyTestUtil.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "WaitStrategyTestUtil.h" 3 | 4 | #include "Disruptor/IWaitStrategy.h" 5 | #include "Disruptor/Sequence.h" 6 | 7 | #include "DummySequenceBarrier.h" 8 | #include "SequenceUpdater.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | namespace Tests 14 | { 15 | 16 | void assertWaitForWithDelayOf(std::int64_t sleepTimeMillis, const std::shared_ptr< IWaitStrategy >& waitStrategy) 17 | { 18 | auto sequencerUpdater = std::make_shared< SequenceUpdater >(sleepTimeMillis, waitStrategy); 19 | std::thread([=] { sequencerUpdater->run(); }).detach(); 20 | sequencerUpdater->waitForStartup(); 21 | auto cursor = std::make_shared< Sequence >(0); 22 | auto barrier = std::make_shared< DummySequenceBarrier >(); 23 | auto sequence = waitStrategy->waitFor(0, *cursor, *sequencerUpdater->sequence, *barrier); 24 | 25 | BOOST_CHECK_EQUAL(sequence, 0L); 26 | } 27 | 28 | } // namespace Tests 29 | } // namespace Disruptor 30 | -------------------------------------------------------------------------------- /Disruptor.Tests/WaitStrategyTestUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | class IWaitStrategy; 11 | 12 | 13 | namespace Tests 14 | { 15 | 16 | void assertWaitForWithDelayOf(std::int64_t sleepTimeMillis, const std::shared_ptr< IWaitStrategy >& waitStrategy); 17 | 18 | } // namespace Tests 19 | } // namespace Disruptor 20 | -------------------------------------------------------------------------------- /Disruptor.Tests/YieldingWaitStrategyTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "Disruptor/YieldingWaitStrategy.h" 4 | #include "WaitStrategyTestUtil.h" 5 | 6 | 7 | using namespace Disruptor; 8 | using namespace Disruptor::Tests; 9 | 10 | 11 | BOOST_AUTO_TEST_SUITE(YieldingWaitStrategyTests) 12 | 13 | BOOST_AUTO_TEST_CASE(ShouldWaitForValue) 14 | { 15 | assertWaitForWithDelayOf(50, std::make_shared< YieldingWaitStrategy >()); 16 | } 17 | 18 | BOOST_AUTO_TEST_SUITE_END() 19 | -------------------------------------------------------------------------------- /Disruptor.Tests/main.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE Disruptor.Tests 2 | 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #if _MSC_VER 10 | # pragma warning (disable: 4231) // nonstandard extension used : 'extern' before template explicit instantiation 11 | #endif 12 | 13 | struct GlobalFixture 14 | { 15 | GlobalFixture() 16 | { 17 | // all passed test names are printed to the output 18 | boost::unit_test::unit_test_log.set_threshold_level(boost::unit_test::log_test_units); 19 | // a very small report is printed to the output (passed tests count / total tests count) 20 | boost::unit_test::results_reporter::set_level(boost::unit_test::SHORT_REPORT); 21 | 22 | testing::GTEST_FLAG(throw_on_failure) = true; 23 | testing::InitGoogleMock(&boost::unit_test::framework::master_test_suite().argc, boost::unit_test::framework::master_test_suite().argv); 24 | } 25 | 26 | ~GlobalFixture() 27 | { 28 | } 29 | }; 30 | 31 | BOOST_GLOBAL_FIXTURE(GlobalFixture); 32 | 33 | -------------------------------------------------------------------------------- /Disruptor.Tests/postbuild.bat: -------------------------------------------------------------------------------- 1 | @setlocal 2 | @echo off 3 | 4 | rem VS post build step command line sample: 5 | rem call postbuild.bat $(OutDir) $(Configuration) $(Platform) $(PlatformToolsetVersion) 6 | 7 | set outdir=%1 8 | 9 | if not "%TEAMCITY_PROJECT_NAME%" == "" ( 10 | echo Running unit tests... 11 | call "%outdir%\disruptor.Tests.exe" --detect_memory_leaks=0 --result_code=no 12 | ) 13 | 14 | @endlocal 15 | -------------------------------------------------------------------------------- /Disruptor.Tests/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // disruptorLibTests.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /Disruptor.Tests/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | // STL 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // Boost.Test 25 | 26 | #include "Disruptor/Pragmas.h" 27 | 28 | DISRUPTOR_PRAGMA_PUSH 29 | DISRUPTOR_PRAGMA_IGNORE_ALL 30 | DISRUPTOR_PRAGMA_IGNORE_UNUSED_VARIABLES 31 | 32 | #include 33 | #include 34 | 35 | DISRUPTOR_PRAGMA_POP 36 | 37 | // Google Mock 38 | #include 39 | -------------------------------------------------------------------------------- /Disruptor.Tests/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /Disruptor.cmake: -------------------------------------------------------------------------------- 1 | add_library(Disruptor STATIC IMPORTED) 2 | set_target_properties(Disruptor PROPERTIES IMPORTED_LOCATION ${REPO_BUILT_LIB_DIR}/libdisruptor.a) 3 | 4 | include_directories(${CMAKE_CURRENT_LIST_DIR}) 5 | 6 | set(DISRUPTOR_LIBRARIES Disruptor) 7 | -------------------------------------------------------------------------------- /Disruptor/AlertException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | DISRUPTOR_DECLARE_EXCEPTION(AlertException); 10 | 11 | } // namespace Disruptor 12 | 13 | 14 | #define DISRUPTOR_THROW_ALERT_EXCEPTION() DISRUPTOR_THROW(::Disruptor::AlertException, "") 15 | -------------------------------------------------------------------------------- /Disruptor/ArgumentException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | DISRUPTOR_DECLARE_EXCEPTION(ArgumentException); 10 | 11 | } // namespace Disruptor 12 | 13 | 14 | #define DISRUPTOR_THROW_ARGUMENT_EXCEPTION(message) DISRUPTOR_THROW(::Disruptor::ArgumentException, message) 15 | -------------------------------------------------------------------------------- /Disruptor/ArgumentNullException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | namespace Disruptor 6 | { 7 | 8 | DISRUPTOR_DECLARE_EXCEPTION(ArgumentNullException); 9 | 10 | } // namespace Disruptor 11 | 12 | 13 | #define DISRUPTOR_THROW_ARGUMENT_NULL_EXCEPTION(variable) \ 14 | DISRUPTOR_PRAGMA_PUSH \ 15 | DISRUPTOR_PRAGMA_IGNORE_CONDITIONAL_EXPRESSION_IS_CONSTANT \ 16 | DISRUPTOR_PRAGMA_IGNORE_UNREACHABLE_CODE \ 17 | do \ 18 | { \ 19 | DISRUPTOR_THROW(::Disruptor::ArgumentNullException, "The variable '" << #variable << "' is null"); \ 20 | } while (0); \ 21 | DISRUPTOR_PRAGMA_POP 22 | -------------------------------------------------------------------------------- /Disruptor/ArgumentOutOfRangeException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | DISRUPTOR_DECLARE_EXCEPTION(ArgumentOutOfRangeException); 10 | 11 | } // namespace Disruptor 12 | 13 | 14 | #define DISRUPTOR_THROW_ARGUMENT_OUT_OF_RANGE_EXCEPTION(variable) \ 15 | DISRUPTOR_PRAGMA_PUSH \ 16 | DISRUPTOR_PRAGMA_IGNORE_CONDITIONAL_EXPRESSION_IS_CONSTANT \ 17 | DISRUPTOR_PRAGMA_IGNORE_UNREACHABLE_CODE \ 18 | do \ 19 | { \ 20 | DISRUPTOR_THROW(::Disruptor::ArgumentOutOfRangeException, "The variable '" << #variable << "' (" << variable << ") is out of range"); \ 21 | } while (0); \ 22 | DISRUPTOR_PRAGMA_POP 23 | 24 | 25 | #define DISRUPTOR_THROW_ARGUMENT_OUT_OF_RANGE_WITH_MESSAGE_EXCEPTION(message) DISRUPTOR_THROW(::Disruptor::ArgumentOutOfRangeException, message) 26 | -------------------------------------------------------------------------------- /Disruptor/BasicExecutor.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "BasicExecutor.h" 3 | 4 | #include "ITaskScheduler.h" 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | BasicExecutor::BasicExecutor(const std::shared_ptr< ITaskScheduler >& taskScheduler) 11 | : m_taskScheduler(taskScheduler) 12 | { 13 | } 14 | 15 | std::future< void > BasicExecutor::execute(const std::function< void() >& command) 16 | { 17 | return m_taskScheduler->scheduleAndStart(std::packaged_task< void() >([this, command] { executeCommand(command); })); 18 | } 19 | 20 | void BasicExecutor::executeCommand(const std::function< void() >& command) 21 | { 22 | try 23 | { 24 | command(); 25 | } 26 | catch (...) 27 | { } 28 | } 29 | 30 | } // namespace Disruptor 31 | -------------------------------------------------------------------------------- /Disruptor/BasicExecutor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IExecutor.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | 11 | class ITaskScheduler; 12 | 13 | 14 | /** 15 | * TaskScheduler implementation for IExecutor 16 | */ 17 | class BasicExecutor : public IExecutor 18 | { 19 | public: 20 | /** 21 | * Create a new BasicExecutor with a given TaskScheduler that will handle low-level queuing of commands execution. 22 | */ 23 | explicit BasicExecutor(const std::shared_ptr< ITaskScheduler >& taskScheduler); 24 | 25 | /** 26 | * Start a new task executiong the given command in the current taskscheduler 27 | * \param command 28 | */ 29 | std::future< void > execute(const std::function< void() >& command) override; 30 | 31 | private: 32 | void executeCommand(const std::function< void() >& command); 33 | 34 | private: 35 | std::shared_ptr< ITaskScheduler > m_taskScheduler; 36 | }; 37 | 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor/BlockingQueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | template 11 | < 12 | class T, 13 | class TQueue = std::deque< T > 14 | > 15 | class BlockingQueue 16 | { 17 | public: 18 | typedef std::mutex Mutex; 19 | typedef std::lock_guard< Mutex > ScopedLock; 20 | typedef std::unique_lock< Mutex > UniqueLock; 21 | 22 | void push(const T& value) 23 | { 24 | { 25 | ScopedLock lock(m_mutex); 26 | m_queue.push_back(value); 27 | } 28 | m_conditionVariable.notify_one(); 29 | } 30 | 31 | void push(T&& value) 32 | { 33 | { 34 | ScopedLock lock(m_mutex); 35 | m_queue.push_back(std::move(value)); 36 | } 37 | m_conditionVariable.notify_one(); 38 | } 39 | 40 | bool empty() const 41 | { 42 | ScopedLock lock(m_mutex); 43 | return m_queue.empty(); 44 | } 45 | 46 | template 47 | bool timedWaitAndPop(T& value, const TDuration& duration) 48 | { 49 | UniqueLock lock(m_mutex); 50 | 51 | if (!m_conditionVariable.wait_for(lock, duration, [this]() -> bool { return !m_queue.empty(); })) 52 | return false; 53 | 54 | value = std::move(m_queue.front()); 55 | m_queue.pop_front(); 56 | return true; 57 | } 58 | 59 | private: 60 | TQueue m_queue; 61 | mutable Mutex m_mutex; 62 | std::condition_variable m_conditionVariable; 63 | }; 64 | 65 | } // namespace Disruptor 66 | -------------------------------------------------------------------------------- /Disruptor/BlockingWaitStrategy.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "BlockingWaitStrategy.h" 3 | 4 | #include 5 | 6 | #include "ISequenceBarrier.h" 7 | #include "Sequence.h" 8 | 9 | 10 | namespace Disruptor 11 | { 12 | 13 | std::int64_t BlockingWaitStrategy::waitFor(std::int64_t sequence, 14 | Sequence& cursor, 15 | ISequence& dependentSequence, 16 | ISequenceBarrier& barrier) 17 | { 18 | if (cursor.value() < sequence) 19 | { 20 | boost::unique_lock< decltype(m_gate) > uniqueLock(m_gate); 21 | 22 | while (cursor.value() < sequence) 23 | { 24 | barrier.checkAlert(); 25 | 26 | m_conditionVariable.wait(uniqueLock); 27 | } 28 | } 29 | 30 | std::int64_t availableSequence; 31 | while ((availableSequence = dependentSequence.value()) < sequence) 32 | { 33 | barrier.checkAlert(); 34 | } 35 | 36 | return availableSequence; 37 | } 38 | 39 | void BlockingWaitStrategy::signalAllWhenBlocking() 40 | { 41 | boost::unique_lock< decltype(m_gate) > uniqueLock(m_gate); 42 | 43 | m_conditionVariable.notify_all(); 44 | } 45 | 46 | void BlockingWaitStrategy::writeDescriptionTo(std::ostream& stream) const 47 | { 48 | stream << "BlockingWaitStrategy"; 49 | } 50 | 51 | } // namespace Disruptor 52 | -------------------------------------------------------------------------------- /Disruptor/BlockingWaitStrategy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IWaitStrategy.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | 11 | /** 12 | * Blocking strategy that uses a lock and condition variable for IEventProcessor's waiting on a barrier. 13 | * This strategy should be used when performance and low-latency are not as important as CPU resource. 14 | */ 15 | class BlockingWaitStrategy : public IWaitStrategy 16 | { 17 | public: 18 | /** 19 | * \see IWaitStrategy::waitFor 20 | */ 21 | std::int64_t waitFor(std::int64_t sequence, 22 | Sequence& cursor, 23 | ISequence& dependentSequence, 24 | ISequenceBarrier& barrier) override; 25 | 26 | /** 27 | * \see IWaitStrategy::signalAllWhenBlocking 28 | */ 29 | void signalAllWhenBlocking() override; 30 | 31 | void writeDescriptionTo(std::ostream& stream) const override; 32 | 33 | private: 34 | boost::recursive_mutex m_gate; 35 | boost::condition_variable_any m_conditionVariable; 36 | }; 37 | 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor/BusySpinWaitStrategy.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "BusySpinWaitStrategy.h" 3 | 4 | #include 5 | 6 | #include "ISequenceBarrier.h" 7 | #include "Sequence.h" 8 | 9 | 10 | namespace Disruptor 11 | { 12 | 13 | std::int64_t BusySpinWaitStrategy::waitFor(std::int64_t sequence, 14 | Sequence& /*cursor*/, 15 | ISequence& dependentSequence, 16 | ISequenceBarrier& barrier) 17 | { 18 | std::int64_t availableSequence; 19 | 20 | while ((availableSequence = dependentSequence.value()) < sequence) 21 | { 22 | barrier.checkAlert(); 23 | } 24 | 25 | return availableSequence; 26 | } 27 | 28 | void BusySpinWaitStrategy::signalAllWhenBlocking() 29 | { 30 | } 31 | 32 | void BusySpinWaitStrategy::writeDescriptionTo(std::ostream& stream) const 33 | { 34 | stream << "BusySpinWaitStrategy"; 35 | } 36 | 37 | } // namespace Disruptor 38 | -------------------------------------------------------------------------------- /Disruptor/BusySpinWaitStrategy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IWaitStrategy.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | 11 | /** 12 | * Busy Spin strategy that uses a busy spin loop for IEventProcessor's waiting on a barrier. 13 | * This strategy will use CPU resource to avoid syscalls which can introduce latency jitter. It is best used when threads can be bound to specific CPU cores. 14 | */ 15 | class BusySpinWaitStrategy : public IWaitStrategy 16 | { 17 | public: 18 | /** 19 | * \see IWaitStrategy::waitFor 20 | */ 21 | std::int64_t waitFor(std::int64_t sequence, 22 | Sequence& cursor, 23 | ISequence& dependentSequence, 24 | ISequenceBarrier& barrier) override; 25 | 26 | /** 27 | * \see IWaitStrategy::signalAllWhenBlocking 28 | */ 29 | void signalAllWhenBlocking() override; 30 | 31 | void writeDescriptionTo(std::ostream& stream) const override; 32 | }; 33 | 34 | } // namespace Disruptor 35 | -------------------------------------------------------------------------------- /Disruptor/ClockConfig.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | namespace Disruptor 9 | { 10 | 11 | struct ClockConfig 12 | { 13 | using Clock = std::conditional< std::chrono::high_resolution_clock::is_steady, std::chrono::high_resolution_clock, std::chrono::steady_clock >::type; 14 | 15 | using TimePoint = Clock::time_point; 16 | using Duration = Clock::duration; 17 | 18 | using Frequency = std::ratio< Duration::period::den, Duration::period::num >; 19 | }; 20 | 21 | } // namespace Disruptor 22 | -------------------------------------------------------------------------------- /Disruptor/ExceptionHandlerSetting.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/BatchEventProcessor.h" 4 | #include "Disruptor/ConsumerRepository.h" 5 | #include "Disruptor/IEventHandler.h" 6 | #include "Disruptor/IExceptionHandler.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | 12 | /** 13 | * A support class used as part of setting an exception handler for a specific event handler. 14 | * 15 | * \tparam T the type of event being handled. 16 | */ 17 | template 18 | class ExceptionHandlerSetting 19 | { 20 | public: 21 | ExceptionHandlerSetting(const std::shared_ptr< IEventHandler< T > >& eventHandler, 22 | const std::shared_ptr< ConsumerRepository< T > >& consumerRepository) 23 | : m_eventHandler(eventHandler) 24 | , m_consumerRepository(consumerRepository) 25 | { 26 | } 27 | 28 | /** 29 | * Specify the IExceptionHandler to use with the event handler. 30 | * 31 | * \param exceptionHandler exceptionHandler the exception handler to use. 32 | */ 33 | void with(const std::shared_ptr< IExceptionHandler< T > >& exceptionHandler) 34 | { 35 | std::dynamic_pointer_cast< BatchEventProcessor< T > >(m_consumerRepository->getEventProcessorFor(m_eventHandler))->setExceptionHandler(exceptionHandler); 36 | m_consumerRepository->getBarrierFor(m_eventHandler)->alert(); 37 | } 38 | 39 | private: 40 | std::shared_ptr< IEventHandler< T > > m_eventHandler; 41 | std::shared_ptr< ConsumerRepository< T > > m_consumerRepository; 42 | }; 43 | 44 | } // namespace Disruptor 45 | -------------------------------------------------------------------------------- /Disruptor/ExceptionHandlerWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IExceptionHandler.h" 6 | #include "Disruptor/FatalExceptionHandler.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | 12 | template 13 | class ExceptionHandlerWrapper : public IExceptionHandler< T > 14 | { 15 | public: 16 | void switchTo(const std::shared_ptr< IExceptionHandler< T > >& exceptionHandler) 17 | { 18 | m_handler = exceptionHandler; 19 | } 20 | 21 | void handleEventException(const std::exception& ex, std::int64_t sequence, T& evt) override 22 | { 23 | m_handler->handleEventException(ex, sequence, evt); 24 | } 25 | 26 | void handleOnStartException(const std::exception& ex) override 27 | { 28 | m_handler->handleOnStartException(ex); 29 | } 30 | 31 | void handleOnShutdownException(const std::exception& ex) override 32 | { 33 | m_handler->handleOnShutdownException(ex); 34 | } 35 | 36 | void handleOnTimeoutException(const std::exception& ex, std::int64_t sequence) override 37 | { 38 | m_handler->handleOnTimeoutException(ex, sequence); 39 | } 40 | 41 | private: 42 | std::shared_ptr< IExceptionHandler< T > > m_handler = std::make_shared< FatalExceptionHandler< T > >(); 43 | }; 44 | 45 | } // namespace Disruptor 46 | -------------------------------------------------------------------------------- /Disruptor/FatalException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | DISRUPTOR_DECLARE_EXCEPTION(FatalException); 10 | 11 | } // namespace Disruptor 12 | 13 | 14 | #define DISRUPTOR_THROW_FATAL_EXCEPTION(disruptorMessage, innerException) \ 15 | DISRUPTOR_PRAGMA_PUSH \ 16 | DISRUPTOR_PRAGMA_IGNORE_CONDITIONAL_EXPRESSION_IS_CONSTANT \ 17 | do \ 18 | { \ 19 | std::stringstream disruptorStream; \ 20 | disruptorStream << disruptorMessage; \ 21 | throw ::Disruptor::FatalException(disruptorStream.str(), innerException, __FUNCTION__, __FILE__, __LINE__); \ 22 | } while (0); \ 23 | DISRUPTOR_PRAGMA_POP 24 | -------------------------------------------------------------------------------- /Disruptor/FixedSequenceGroup.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FixedSequenceGroup.h" 3 | 4 | #include 5 | 6 | #include "NotSupportedException.h" 7 | #include "Util.h" 8 | 9 | 10 | namespace Disruptor 11 | { 12 | 13 | FixedSequenceGroup::FixedSequenceGroup(const std::vector< std::shared_ptr< ISequence > >& sequences) 14 | : m_sequences(sequences) 15 | { 16 | } 17 | 18 | std::int64_t FixedSequenceGroup::value() const 19 | { 20 | return Util::getMinimumSequence(m_sequences); 21 | } 22 | 23 | void FixedSequenceGroup::setValue(std::int64_t /*value*/) 24 | { 25 | DISRUPTOR_THROW_NOT_SUPPORTED_EXCEPTION(); 26 | } 27 | 28 | bool FixedSequenceGroup::compareAndSet(std::int64_t /*expectedValue*/, std::int64_t /*newValue*/) 29 | { 30 | DISRUPTOR_THROW_NOT_SUPPORTED_EXCEPTION(); 31 | } 32 | 33 | std::int64_t FixedSequenceGroup::incrementAndGet() 34 | { 35 | DISRUPTOR_THROW_NOT_SUPPORTED_EXCEPTION(); 36 | } 37 | 38 | std::int64_t FixedSequenceGroup::addAndGet(std::int64_t /*increment*/) 39 | { 40 | DISRUPTOR_THROW_NOT_SUPPORTED_EXCEPTION(); 41 | } 42 | 43 | void FixedSequenceGroup::writeDescriptionTo(std::ostream& stream) const 44 | { 45 | auto firstItem = true; 46 | for (auto&& sequence : m_sequences) 47 | { 48 | if (firstItem) 49 | firstItem = false; 50 | else 51 | stream << ", "; 52 | stream << "{ "; 53 | sequence->writeDescriptionTo(stream); 54 | stream << " }"; 55 | } 56 | } 57 | 58 | } // namespace Disruptor 59 | -------------------------------------------------------------------------------- /Disruptor/FixedSequenceGroup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/ISequence.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | 12 | /** 13 | * Hides a group of Sequences behind a single Sequence 14 | */ 15 | class FixedSequenceGroup : public ISequence 16 | { 17 | public: 18 | /** 19 | * 20 | * \param sequences sequences the list of sequences to be tracked under this sequence group 21 | */ 22 | explicit FixedSequenceGroup(const std::vector< std::shared_ptr< ISequence > >& sequences); 23 | 24 | /** 25 | * Get the minimum sequence value for the group. 26 | */ 27 | std::int64_t value() const override; 28 | 29 | /** 30 | * Not supported. 31 | */ 32 | void setValue(std::int64_t value) override; 33 | 34 | /** 35 | * Not supported. 36 | */ 37 | bool compareAndSet(std::int64_t expectedValue, std::int64_t newValue) override; 38 | 39 | /** 40 | * Not supported. 41 | */ 42 | std::int64_t incrementAndGet() override; 43 | 44 | /** 45 | * Not supported. 46 | */ 47 | std::int64_t addAndGet(std::int64_t increment) override; 48 | 49 | void writeDescriptionTo(std::ostream& stream) const override; 50 | 51 | private: 52 | std::vector< std::shared_ptr< ISequence > > m_sequences; 53 | }; 54 | 55 | } // namespace Disruptor 56 | -------------------------------------------------------------------------------- /Disruptor/IConsumerInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Disruptor/IExecutor.h" 7 | #include "Disruptor/ISequence.h" 8 | #include "Disruptor/ISequenceBarrier.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | 14 | class IConsumerInfo 15 | { 16 | public: 17 | virtual ~IConsumerInfo() = default; 18 | 19 | virtual std::vector< std::shared_ptr< ISequence > > sequences() const = 0; 20 | 21 | virtual const std::shared_ptr< ISequenceBarrier >& barrier() const = 0; 22 | 23 | virtual bool isEndOfChain() const = 0; 24 | 25 | virtual void start(const std::shared_ptr< IExecutor >& executor) = 0; 26 | virtual void halt() = 0; 27 | 28 | virtual void markAsUsedInBarrier() = 0; 29 | 30 | virtual bool isRunning() const = 0; 31 | }; 32 | 33 | } // namespace Disruptor 34 | -------------------------------------------------------------------------------- /Disruptor/ICursored.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | /** 10 | * Implementors of this interface must provide a single long value that represents their current cursor value.Used during dynamic add/remove of Sequences from a SequenceGroups.addSequences 11 | */ 12 | class ICursored 13 | { 14 | public: 15 | virtual ~ICursored() = default; 16 | 17 | /** 18 | * Get the current cursor value. 19 | */ 20 | virtual std::int64_t cursor() const = 0; 21 | }; 22 | 23 | } // namespace Disruptor 24 | -------------------------------------------------------------------------------- /Disruptor/IDataProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | template 11 | class IDataProvider 12 | { 13 | public: 14 | virtual ~IDataProvider() = default; 15 | 16 | virtual T& operator[](std::int64_t sequence) const = 0; 17 | }; 18 | 19 | } // namespace Disruptor 20 | -------------------------------------------------------------------------------- /Disruptor/IEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | /** 10 | * Callback interface to be implemented for processing events as they become available in the RingBuffer 11 | * 12 | * \tparam T Type of events for sharing during exchange or parallel coordination of an event 13 | * \remark See BatchEventProcessor.SetExceptionHandler if you want to handle exceptions propagated out of the handler. 14 | */ 15 | template 16 | class IEventHandler 17 | { 18 | public: 19 | virtual ~IEventHandler() = default; 20 | 21 | /** 22 | * Called when a publisher has committed an event to the RingBuffer 23 | * 24 | * \param data Data committed to the RingBuffer 25 | * \param sequence Sequence number committed to the RingBuffer 26 | * \param endOfBatch flag to indicate if this is the last event in a batch from the RingBuffer 27 | */ 28 | virtual void onEvent(T& data, std::int64_t sequence, bool endOfBatch) = 0; 29 | }; 30 | 31 | } // namespace Disruptor 32 | -------------------------------------------------------------------------------- /Disruptor/IEventProcessor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | class ISequence; 10 | 11 | class IEventProcessor 12 | { 13 | public: 14 | virtual ~IEventProcessor() = default; 15 | 16 | /** 17 | * Return a reference to the ISequence being used by this IEventProcessor 18 | */ 19 | virtual std::shared_ptr< ISequence > sequence() const = 0; 20 | 21 | /** 22 | * Signal that this IEventProcessor should stop when it has finished consuming at the next clean break. 23 | * It will call ISequenceBarrier.alert() to notify the thread to check status. 24 | */ 25 | virtual void halt() = 0; 26 | 27 | /** 28 | * Starts this instance 29 | */ 30 | virtual void run() = 0; 31 | 32 | /** 33 | * Gets if the processor is running 34 | */ 35 | virtual bool isRunning() const = 0; 36 | }; 37 | 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor/IEventProcessorFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IEventProcessor.h" 6 | #include "Disruptor/RingBuffer.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | 12 | /** 13 | * A factory interface to make it possible to include custom event processors in a chain 14 | */ 15 | template 16 | class IEventProcessorFactory 17 | { 18 | public: 19 | virtual ~IEventProcessorFactory() = default; 20 | 21 | /** 22 | * Create a new event processor that gates on barrierSequences 23 | * 24 | * \param ringBuffer ring buffer 25 | * \param barrierSequences barrierSequences the sequences to gate on 26 | * \returns a new EventProcessor that gates on before processing events 27 | */ 28 | virtual std::shared_ptr< IEventProcessor > createEventProcessor(const std::shared_ptr< RingBuffer< T > >& ringBuffer, 29 | const std::vector< std::shared_ptr< ISequence > >& barrierSequences) = 0; 30 | }; 31 | 32 | } // namespace Disruptor 33 | -------------------------------------------------------------------------------- /Disruptor/IEventProcessorSequenceAware.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/ISequence.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | 11 | /** 12 | * Implement this interface in your event handler to obtain the sequence. 13 | * 14 | * Used by the to set a callback allowing the event handler to notify 15 | * when it has finished consuming an event if this happens after the OnEvent call. 16 | * 17 | * Typically this would be used when the handler is performing some sort of batching operation such as writing to an IO 18 | * device; after the operation has completed, the implementation should set to update the 19 | * sequence and allow other processes that are dependent on this handler to progress. 20 | */ 21 | class IEventProcessorSequenceAware 22 | { 23 | public: 24 | virtual ~IEventProcessorSequenceAware() = default; 25 | 26 | /** 27 | * Call by the to setup the callback. 28 | * 29 | * \param sequenceCallback callback on which to notify the that the sequence has progressed. 30 | */ 31 | virtual void setSequenceCallback(const std::shared_ptr< ISequence >& sequenceCallback) = 0; 32 | }; 33 | 34 | } // namespace Disruptor 35 | -------------------------------------------------------------------------------- /Disruptor/IEventReleaseAware.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | class IEventReleaser; 10 | 11 | 12 | class IEventReleaseAware 13 | { 14 | public: 15 | virtual ~IEventReleaseAware() = default; 16 | 17 | virtual void setEventReleaser(const std::shared_ptr< IEventReleaser >& eventReleaser) = 0; 18 | }; 19 | 20 | } // namespace Disruptor 21 | -------------------------------------------------------------------------------- /Disruptor/IEventReleaser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Disruptor 5 | { 6 | 7 | class IEventReleaser 8 | { 9 | public: 10 | virtual ~IEventReleaser() = default; 11 | 12 | virtual void release() = 0; 13 | }; 14 | 15 | } // namespace Disruptor 16 | -------------------------------------------------------------------------------- /Disruptor/IEventSequencer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/IDataProvider.h" 4 | #include "Disruptor/ISequenced.h" 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | template 11 | class IEventSequencer : public IDataProvider< T >, public ISequenced 12 | { 13 | }; 14 | 15 | } // namespace Disruptor 16 | -------------------------------------------------------------------------------- /Disruptor/IEventTranslator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | /** 11 | * Implementations translate (write) data representations into events claimed from the RingBuffer. 12 | * When publishing to the RingBuffer, provide an EventTranslator. The RingBuffer will select the next available event by sequence and provide 13 | * it to the EventTranslator(which should update the event), before publishing the sequence update. 14 | * 15 | * \tparam T event implementation storing the data for sharing during exchange or parallel coordination of an event. 16 | */ 17 | template 18 | class IEventTranslator 19 | { 20 | public: 21 | virtual ~IEventTranslator() = default; 22 | 23 | /** 24 | * Translate a data representation into fields set in given event 25 | * 26 | * \param eventData event into which the data should be translated. 27 | * \param sequence sequence that is assigned to event. 28 | */ 29 | virtual void translateTo(T& eventData, std::int64_t sequence) = 0; 30 | }; 31 | 32 | } // namespace Disruptor 33 | -------------------------------------------------------------------------------- /Disruptor/IEventTranslatorVararg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Disruptor 6 | { 7 | 8 | /** 9 | * Translate a data representation into fields set in given event 10 | * 11 | * \param event into which the data should be translated. 12 | * \param sequence that is assigned to event. 13 | * \param args The array of user arguments. 14 | */ 15 | template 16 | class IEventTranslatorVararg 17 | { 18 | public: 19 | virtual ~IEventTranslatorVararg() = default; 20 | 21 | /** 22 | * Translate a data representation into fields set in given event 23 | * 24 | * \param eventData event into which the data should be translated. 25 | * \param sequence sequence that is assigned to event. 26 | */ 27 | virtual void translateTo(T& eventData, std::int64_t sequence, const TArgs&... args) = 0; 28 | }; 29 | 30 | } // namespace Disruptor 31 | -------------------------------------------------------------------------------- /Disruptor/IExecutor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | /** 10 | * Replace the Executor interface in java.util.concurrent 11 | */ 12 | class IExecutor 13 | { 14 | public: 15 | virtual ~IExecutor() = default; 16 | 17 | /** 18 | * Execute the given command in an other thread 19 | * 20 | * \param command The command to execute 21 | */ 22 | virtual std::future< void > execute(const std::function< void() >& command) = 0; 23 | }; 24 | 25 | } // namespace Disruptor 26 | -------------------------------------------------------------------------------- /Disruptor/IHighestPublishedSequenceProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Disruptor 6 | { 7 | 8 | class IHighestPublishedSequenceProvider 9 | { 10 | public: 11 | virtual ~IHighestPublishedSequenceProvider() = default; 12 | 13 | /** 14 | * Get the highest sequence number that can be safely read from the ring buffer. Depending on the implementation of the Sequencer this call may need to scan a number of values 15 | * in the Sequencer. The scan will range from nextSequence to availableSequence. If there are no available values > nextSequence() the return value will be nextSequence - 1 16 | * To work correctly a consumer should pass a value that it 1 higher than the last sequence that was successfully processed. 17 | * 18 | * \param nextSequence The sequence to start scanning from. 19 | * \param availableSequence The sequence to scan to. 20 | * \returns The highest value that can be safely read, will be at least nextSequence - 1 21 | */ 22 | virtual std::int64_t getHighestPublishedSequence(std::int64_t nextSequence, std::int64_t availableSequence) = 0; 23 | }; 24 | 25 | } // namespace Disruptor 26 | -------------------------------------------------------------------------------- /Disruptor/ILifecycleAware.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Disruptor 5 | { 6 | 7 | /** 8 | * Implement this interface in your IEventHandler to be notified when a thread for the BatchEventProcessor starts and shuts down. 9 | */ 10 | class ILifecycleAware 11 | { 12 | public: 13 | virtual ~ILifecycleAware() = default; 14 | 15 | /** 16 | * Called once on thread start before first event is available. 17 | */ 18 | virtual void onStart() = 0; 19 | 20 | /** 21 | * Called once just before the thread is shutdown. Sequence event processing will already have stopped before this method is called. No events wil be processed after this message. 22 | */ 23 | virtual void onShutdown() = 0; 24 | }; 25 | 26 | } // namespace Disruptor 27 | -------------------------------------------------------------------------------- /Disruptor/ISequenceBarrier.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | /** 10 | * Coordination barrier for tracking the cursor for producers and sequence of dependent IEventProcessor's for a RingBuffer 11 | */ 12 | class ISequenceBarrier 13 | { 14 | public: 15 | virtual ~ISequenceBarrier() = default; 16 | 17 | /** 18 | * Wait for the given sequence to be available for consumption. 19 | * 20 | * \param sequence sequence to wait for 21 | * \returns the sequence up to which is available 22 | */ 23 | virtual std::int64_t waitFor(std::int64_t sequence) = 0; 24 | 25 | /** 26 | * Delegate a call to the Sequencer.cursor() 27 | * Returns the value of the cursor for events that have been published. 28 | */ 29 | virtual std::int64_t cursor() = 0; 30 | 31 | /** 32 | * The current alert status for the barrier. Returns true if in alert otherwise false. 33 | */ 34 | virtual bool isAlerted() = 0; 35 | 36 | /** 37 | * Alert the IEventProcessor of a status change and stay in this status until cleared. 38 | */ 39 | virtual void alert() = 0; 40 | 41 | /** 42 | * Clear the current alert status. 43 | */ 44 | virtual void clearAlert() = 0; 45 | 46 | /** 47 | * Check if an alert has been raised and throw an AlertException if it has. 48 | */ 49 | virtual void checkAlert() = 0; 50 | }; 51 | 52 | } // namespace Disruptor 53 | -------------------------------------------------------------------------------- /Disruptor/ISequenceReportingEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/IEventHandler.h" 4 | #include "Disruptor/IEventProcessorSequenceAware.h" 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | /** 11 | * Used by the BatchEventProcessor to set a callback allowing the IEventHandler to notify when it has finished consuming an event if this happens after the IEventHandler.onEvent() call. 12 | * Typically this would be used when the handler is performing some sort of batching operation such as writing to an IO device; after the operation has completed, 13 | * the implementation should set Sequence.value to update the sequence and allow other processes that are dependent on this handler to progress. 14 | * 15 | * \tparam T event implementation storing the data for sharing during exchange or parallel coordination of an event. 16 | */ 17 | template 18 | class ISequenceReportingEventHandler : public IEventHandler< T >, public IEventProcessorSequenceAware 19 | { 20 | public: 21 | virtual ~ISequenceReportingEventHandler() = default; 22 | }; 23 | 24 | } // namespace Disruptor 25 | -------------------------------------------------------------------------------- /Disruptor/ITaskScheduler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | class ITaskScheduler 10 | { 11 | public: 12 | virtual ~ITaskScheduler() = default; 13 | 14 | virtual void start(std::int32_t numberOfThreads ) = 0; 15 | virtual void stop() = 0; 16 | 17 | virtual std::future< void > scheduleAndStart(std::packaged_task< void() >&& task) = 0; 18 | }; 19 | 20 | } // namespace Disruptor 21 | -------------------------------------------------------------------------------- /Disruptor/ITimeoutHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Disruptor 5 | { 6 | 7 | class ITimeoutHandler 8 | { 9 | public: 10 | virtual ~ITimeoutHandler() = default; 11 | 12 | virtual void onTimeout(std::int64_t sequence) = 0; 13 | }; 14 | 15 | } // namespace Disruptor 16 | -------------------------------------------------------------------------------- /Disruptor/IWorkHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Disruptor 4 | { 5 | 6 | /** 7 | * Callback interface to be implemented for processing units of work as they become available in the RingBuffer 8 | * 9 | * \tparam T event implementation storing the data for sharing during exchange or parallel coordination of an event. 10 | */ 11 | template 12 | class IWorkHandler 13 | { 14 | public: 15 | virtual ~IWorkHandler() = default; 16 | 17 | /** 18 | * Callback to indicate a unit of work needs to be processed. 19 | * 20 | * \param evt event published to the RingBuffer 21 | */ 22 | virtual void onEvent(T& evt) = 0; 23 | }; 24 | 25 | } // namespace Disruptor 26 | -------------------------------------------------------------------------------- /Disruptor/InsufficientCapacityException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | DISRUPTOR_DECLARE_EXCEPTION(InsufficientCapacityException); 10 | 11 | } // namespace Disruptor 12 | 13 | 14 | #define DISRUPTOR_THROW_INSUFFICIENT_CAPACITY_EXCEPTION() DISRUPTOR_THROW(::Disruptor::InsufficientCapacityException, "") 15 | -------------------------------------------------------------------------------- /Disruptor/InvalidOperationException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | DISRUPTOR_DECLARE_EXCEPTION(InvalidOperationException); 10 | 11 | } // namespace Disruptor 12 | 13 | 14 | #define DISRUPTOR_THROW_INVALID_OPERATION_EXCEPTION(message) DISRUPTOR_THROW(::Disruptor::InvalidOperationException, message) 15 | -------------------------------------------------------------------------------- /Disruptor/NotSupportedException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | DISRUPTOR_DECLARE_EXCEPTION(NotSupportedException); 10 | 11 | } // namespace Disruptor 12 | 13 | 14 | #define DISRUPTOR_THROW_NOT_SUPPORTED_EXCEPTION() DISRUPTOR_THROW(::Disruptor::NotSupportedException, "") 15 | -------------------------------------------------------------------------------- /Disruptor/Pragmas.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _MSC_VER 4 | 5 | # define DISRUPTOR_PRAGMA_IGNORE_ALL __pragma(warning(push, 0)) 6 | 7 | # define DISRUPTOR_PRAGMA_PUSH __pragma(warning(push)) 8 | # define DISRUPTOR_PRAGMA_POP __pragma(warning(pop)) 9 | 10 | # define DISRUPTOR_PRAGMA_IGNORE_CONDITIONAL_EXPRESSION_IS_CONSTANT __pragma(warning(disable : 4127)) 11 | # define DISRUPTOR_PRAGMA_IGNORE_UNREACHABLE_CODE __pragma(warning(disable : 4702)) 12 | # define DISRUPTOR_PRAGMA_IGNORE_DEPRECATED_DECLARATIONS /* not available with vc++ ? */ 13 | # define DISRUPTOR_PRAGMA_IGNORE_UNUSED_VARIABLES __pragma(warning(disable : 4189)) 14 | 15 | 16 | #else // ifdef _MSC_VER 17 | 18 | # define DISRUPTOR_PRAGMAFY_MESSAGE(text) _Pragma(#text) 19 | 20 | # define DISRUPTOR_PRAGMA_IGNORE_ALL /* not available with g++ ? */ 21 | 22 | # define DISRUPTOR_PRAGMA_PUSH 23 | # define DISRUPTOR_PRAGMA_POP 24 | 25 | # define DISRUPTOR_PRAGMA_IGNORE_CONDITIONAL_EXPRESSION_IS_CONSTANT 26 | # define DISRUPTOR_PRAGMA_IGNORE_UNREACHABLE_CODE 27 | # define DISRUPTOR_PRAGMA_IGNORE_DEPRECATED_DECLARATIONS DISRUPTOR_PRAGMAFY_MESSAGE(GCC diagnostic ignored "-Wdeprecated-declarations") 28 | # define DISRUPTOR_PRAGMA_IGNORE_UNUSED_VARIABLES DISRUPTOR_PRAGMAFY_MESSAGE(GCC diagnostic ignored "-Wunused-variable") 29 | 30 | #endif // ifdef _MSC_VER 31 | -------------------------------------------------------------------------------- /Disruptor/ProducerType.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ProducerType.h" 3 | 4 | 5 | namespace std 6 | { 7 | 8 | ostream& operator<<(ostream& stream, const Disruptor::ProducerType& value) 9 | { 10 | switch (value) 11 | { 12 | case Disruptor::ProducerType::Single: 13 | return stream << "Single"; 14 | case Disruptor::ProducerType::Multi: 15 | return stream << "Multi"; 16 | default: 17 | return stream << static_cast< int >(value); 18 | } 19 | } 20 | 21 | } // namespace std 22 | -------------------------------------------------------------------------------- /Disruptor/ProducerType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Disruptor 5 | { 6 | /** 7 | * Defines producer types to support creation of RingBuffer with correct sequencer and publisher. 8 | */ 9 | enum class ProducerType 10 | { 11 | /** 12 | * Create a RingBuffer with a single event publisher to the RingBuffer 13 | */ 14 | Single, 15 | 16 | /** 17 | * Create a RingBuffer supporting multiple event publishers to the one RingBuffer 18 | */ 19 | Multi 20 | }; 21 | 22 | } // namespace Disruptor 23 | 24 | 25 | #include 26 | 27 | 28 | namespace std 29 | { 30 | 31 | ostream& operator<<(ostream& stream, const Disruptor::ProducerType& value); 32 | 33 | } // namespace std 34 | -------------------------------------------------------------------------------- /Disruptor/RoundRobinThreadAffinedTaskScheduler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "Disruptor/BlockingQueue.h" 11 | #include "Disruptor/ITaskScheduler.h" 12 | 13 | 14 | namespace Disruptor 15 | { 16 | 17 | /** 18 | * An implementation of TaskScheduler which creates an underlying thread pool and set processor affinity to each thread. 19 | */ 20 | class RoundRobinThreadAffinedTaskScheduler : public ITaskScheduler 21 | { 22 | public: 23 | void start(std::int32_t numberOfThreads) override; 24 | void stop() override; 25 | 26 | std::future< void > scheduleAndStart(std::packaged_task< void() >&& task) override; 27 | 28 | private: 29 | void createThreads(std::int32_t numberOfThreads); 30 | void workingLoop(std::int32_t threadId); 31 | void tryExecuteTask(std::packaged_task< void() >& task); 32 | 33 | BlockingQueue< std::packaged_task< void() > > m_tasks; 34 | std::atomic< bool > m_started {false}; 35 | std::vector< boost::thread > m_threads; 36 | }; 37 | 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor/Sequence.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Sequence.h" 3 | 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | const std::int64_t Sequence::InitialCursorValue = -1; 11 | 12 | Sequence::Sequence(std::int64_t initialValue) 13 | : m_fieldsValue(initialValue) 14 | { 15 | } 16 | 17 | std::int64_t Sequence::value() const 18 | { 19 | return std::atomic_load_explicit(&m_fieldsValue, std::memory_order_acquire); 20 | } 21 | 22 | void Sequence::setValue(std::int64_t value) 23 | { 24 | std::atomic_store_explicit(&m_fieldsValue, value, std::memory_order_release); 25 | } 26 | 27 | bool Sequence::compareAndSet(std::int64_t expectedSequence, std::int64_t nextSequence) 28 | { 29 | return std::atomic_compare_exchange_strong(&m_fieldsValue, &expectedSequence, nextSequence); 30 | } 31 | 32 | std::int64_t Sequence::incrementAndGet() 33 | { 34 | return std::atomic_fetch_add(&m_fieldsValue, std::int64_t(1)) + 1; 35 | } 36 | 37 | std::int64_t Sequence::addAndGet(std::int64_t value) 38 | { 39 | return std::atomic_fetch_add(&m_fieldsValue, value) + value; 40 | } 41 | 42 | void Sequence::writeDescriptionTo(std::ostream& stream) const 43 | { 44 | stream << m_fieldsValue.load(); 45 | } 46 | 47 | } // namespace Disruptor 48 | -------------------------------------------------------------------------------- /Disruptor/SequenceGroups.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | class ICursored; 10 | class ISequence; 11 | 12 | /** 13 | * Provides static methods for managing a SequenceGroup object 14 | */ 15 | class SequenceGroups 16 | { 17 | public: 18 | static void addSequences(std::shared_ptr< std::vector< std::shared_ptr< ISequence > > >& sequences, 19 | const ICursored& cursor, 20 | const std::vector< std::shared_ptr< ISequence > >& sequencesToAdd); 21 | 22 | static void addSequences(std::vector< std::shared_ptr< ISequence > >& sequences, 23 | const ICursored& cursor, 24 | const std::vector< std::shared_ptr< ISequence > >& sequencesToAdd); 25 | 26 | static bool removeSequence(std::shared_ptr< std::vector< std::shared_ptr< ISequence > > >& sequences, const std::shared_ptr< ISequence >& sequence); 27 | static bool removeSequence(std::vector< std::shared_ptr< ISequence > >& sequences, const std::shared_ptr< ISequence >& sequence); 28 | 29 | private: 30 | static std::int32_t countMatching(const std::vector< std::shared_ptr< ISequence > >& values, const std::shared_ptr< ISequence >& toMatch); 31 | }; 32 | 33 | } // namespace Disruptor 34 | -------------------------------------------------------------------------------- /Disruptor/SleepingWaitStrategy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IWaitStrategy.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | 11 | /** 12 | * Sleeping strategy that initially spins, then uses a std::this_thread::yield(), and eventually sleep. This strategy is a good compromise between performance and CPU resource. 13 | * Latency spikes can occur after quiet periods. 14 | */ 15 | class SleepingWaitStrategy : public IWaitStrategy 16 | { 17 | public: 18 | explicit SleepingWaitStrategy(std::int32_t retries = m_defaultRetries); 19 | 20 | /** 21 | * \see IWaitStrategy::waitFor() 22 | */ 23 | std::int64_t waitFor(std::int64_t sequence, 24 | Sequence& cursor, 25 | ISequence& dependentSequence, 26 | ISequenceBarrier& barrier) override; 27 | 28 | /** 29 | * \see IWaitStrategy::signalAllWhenBlocking() 30 | */ 31 | void signalAllWhenBlocking() override; 32 | 33 | void writeDescriptionTo(std::ostream& stream) const override; 34 | 35 | private: 36 | static std::int32_t applyWaitMethod(ISequenceBarrier& barrier, std::int32_t counter); 37 | 38 | static const std::int32_t m_defaultRetries = 200; 39 | std::int32_t m_retries = 0; 40 | }; 41 | 42 | } // namespace Disruptor 43 | -------------------------------------------------------------------------------- /Disruptor/SpinWait.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | class SpinWait 11 | { 12 | public: 13 | SpinWait(); 14 | 15 | std::int32_t count() const; 16 | bool nextSpinWillYield() const; 17 | 18 | void spinOnce(); 19 | 20 | void reset(); 21 | 22 | static void spinUntil(const std::function< bool() >& condition); 23 | static bool spinUntil(const std::function< bool() >& condition, std::int64_t millisecondsTimeout); 24 | 25 | static std::int64_t getTickCount(); 26 | 27 | private: 28 | static void spinWaitInternal(std::int32_t iterationCount); 29 | static void yieldProcessor(); 30 | 31 | private: 32 | std::int32_t m_count; 33 | 34 | static const std::int32_t YIELD_THRESHOLD; 35 | static const std::int32_t SLEEP_0_EVERY_HOW_MANY_TIMES; 36 | static const std::int32_t SLEEP_1_EVERY_HOW_MANY_TIMES; 37 | }; 38 | 39 | } // namespace Disruptor 40 | -------------------------------------------------------------------------------- /Disruptor/SpinWaitWaitStrategy.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SpinWaitWaitStrategy.h" 3 | 4 | #include 5 | 6 | #include "ISequenceBarrier.h" 7 | #include "Sequence.h" 8 | #include "SpinWait.h" 9 | 10 | 11 | namespace Disruptor 12 | { 13 | 14 | std::int64_t SpinWaitWaitStrategy::waitFor(std::int64_t sequence, 15 | Sequence& /*cursor*/, 16 | ISequence& dependentSequence, 17 | ISequenceBarrier& barrier) 18 | { 19 | std::int64_t availableSequence; 20 | 21 | SpinWait spinWait; 22 | while ((availableSequence = dependentSequence.value()) < sequence) 23 | { 24 | barrier.checkAlert(); 25 | spinWait.spinOnce(); 26 | } 27 | 28 | return availableSequence; 29 | } 30 | 31 | void SpinWaitWaitStrategy::signalAllWhenBlocking() 32 | { 33 | } 34 | 35 | void SpinWaitWaitStrategy::writeDescriptionTo(std::ostream& stream) const 36 | { 37 | stream << "SpinWaitWaitStrategy"; 38 | } 39 | 40 | } // namespace Disruptor 41 | -------------------------------------------------------------------------------- /Disruptor/SpinWaitWaitStrategy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IWaitStrategy.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | 11 | /** 12 | * Spin strategy that uses a SpinWait for IEventProcessors waiting on a barrier. 13 | * This strategy is a good compromise between performance and CPU resource. Latency spikes can occur after quiet periods. 14 | */ 15 | class SpinWaitWaitStrategy : public IWaitStrategy 16 | { 17 | public: 18 | /** 19 | * \see IWaitStrategy.waitFor() 20 | */ 21 | std::int64_t waitFor(std::int64_t sequence, 22 | Sequence& cursor, 23 | ISequence& dependentSequence, 24 | ISequenceBarrier& barrier) override; 25 | 26 | /** 27 | * \see IWaitStrategy.signalAllWhenBlocking() 28 | */ 29 | void signalAllWhenBlocking() override; 30 | 31 | void writeDescriptionTo(std::ostream& stream) const override; 32 | }; 33 | 34 | } // namespace Disruptor 35 | -------------------------------------------------------------------------------- /Disruptor/ThreadHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Disruptor 6 | { 7 | namespace ThreadHelper 8 | { 9 | 10 | using AffinityMask = std::bitset<64>; 11 | 12 | std::uint32_t getCurrentThreadId(); 13 | std::uint32_t getCurrentProcessor(); 14 | 15 | std::size_t getProcessorCount(); 16 | 17 | bool setThreadAffinity (const AffinityMask& mask); 18 | AffinityMask getThreadAffinity(); 19 | 20 | void setThreadName(const std::string& name); 21 | void setThreadName(int threadId, const std::string& name); 22 | 23 | } // namespace ThreadHelper 24 | } // namespace Disruptor 25 | -------------------------------------------------------------------------------- /Disruptor/ThreadPerTaskScheduler.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "ThreadPerTaskScheduler.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | void ThreadPerTaskScheduler::start(std::int32_t) 10 | { 11 | if (m_started) 12 | return; 13 | 14 | m_started = true; 15 | } 16 | 17 | void ThreadPerTaskScheduler::stop() 18 | { 19 | if (!m_started) 20 | return; 21 | 22 | m_started = false; 23 | 24 | for (auto&& thread : m_threads) 25 | { 26 | if (thread.joinable()) 27 | thread.join(); 28 | } 29 | } 30 | 31 | std::future ThreadPerTaskScheduler::scheduleAndStart(std::packaged_task&& task) 32 | { 33 | auto result = task.get_future(); 34 | 35 | m_threads.emplace_back([this, task{ move(task) }] () mutable 36 | { 37 | while(m_started) 38 | { 39 | try 40 | { 41 | task(); 42 | } 43 | catch (...) 44 | { 45 | } 46 | } 47 | }); 48 | 49 | return result; 50 | } 51 | 52 | } // namespace Disruptor 53 | -------------------------------------------------------------------------------- /Disruptor/ThreadPerTaskScheduler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ITaskScheduler.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | class ThreadPerTaskScheduler : public ITaskScheduler 10 | { 11 | public: 12 | void start(std::int32_t numberOfThreads = 0) override; 13 | void stop() override; 14 | 15 | std::future< void > scheduleAndStart(std::packaged_task< void() >&& task) override; 16 | 17 | private: 18 | std::atomic< bool > m_started{ false }; 19 | std::vector< std::thread > m_threads; 20 | }; 21 | 22 | } // namespace Disruptor 23 | -------------------------------------------------------------------------------- /Disruptor/TimeoutBlockingWaitStrategy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/ClockConfig.h" 6 | #include "Disruptor/IWaitStrategy.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | 12 | class TimeoutBlockingWaitStrategy : public IWaitStrategy 13 | { 14 | public: 15 | explicit TimeoutBlockingWaitStrategy(ClockConfig::Duration timeout); 16 | 17 | /** 18 | * \see IWaitStrategy.waitFor 19 | */ 20 | std::int64_t waitFor(std::int64_t sequence, 21 | Sequence& cursor, 22 | ISequence& dependentSequence, 23 | ISequenceBarrier& barrier) override; 24 | 25 | /** 26 | * \see IWaitStrategy.signalAllWhenBlocking 27 | */ 28 | void signalAllWhenBlocking() override; 29 | 30 | void writeDescriptionTo(std::ostream& stream) const override; 31 | 32 | private: 33 | ClockConfig::Duration m_timeout; 34 | boost::recursive_mutex m_gate; 35 | boost::condition_variable_any m_conditionVariable; 36 | }; 37 | 38 | } // namespace Disruptor 39 | -------------------------------------------------------------------------------- /Disruptor/TimeoutException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disruptor/ExceptionBase.h" 4 | 5 | 6 | namespace Disruptor 7 | { 8 | 9 | DISRUPTOR_DECLARE_EXCEPTION(TimeoutException); 10 | 11 | } // namespace Disruptor 12 | 13 | 14 | #define DISRUPTOR_THROW_TIMEOUT_EXCEPTION() DISRUPTOR_THROW(::Disruptor::TimeoutException, "") 15 | -------------------------------------------------------------------------------- /Disruptor/TypeInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Disruptor 8 | { 9 | 10 | struct TypeInfo 11 | { 12 | explicit TypeInfo(const std::type_info& typeInfo); 13 | 14 | const std::type_info& intrinsicTypeInfo() const; 15 | 16 | const std::string& fullyQualifiedName() const; 17 | const std::string& name() const; 18 | 19 | bool operator==(const TypeInfo& rhs) const; 20 | 21 | static std::string dotNetify(const std::string& typeName); 22 | static std::string unqualifyName(const std::string& fullyQualifiedName); 23 | static std::string demangleTypeName(const std::string& typeName); 24 | 25 | private: 26 | const std::type_info* m_typeInfo; 27 | std::string m_fullyQualifiedName; 28 | std::string m_name; 29 | }; 30 | 31 | namespace Utils 32 | { 33 | 34 | template 35 | const TypeInfo& getMetaTypeInfo() 36 | { 37 | static TypeInfo result(typeid(T)); 38 | return result; 39 | } 40 | 41 | } // namespace Utils 42 | } // namespace Disruptor 43 | 44 | 45 | #include 46 | #include 47 | 48 | 49 | namespace std 50 | { 51 | 52 | template <> 53 | struct hash< Disruptor::TypeInfo > : public unary_function< Disruptor::TypeInfo, size_t > 54 | { 55 | public: 56 | size_t operator()(const Disruptor::TypeInfo& value) const 57 | { 58 | return hash< type_index >()(type_index(value.intrinsicTypeInfo())); 59 | } 60 | }; 61 | 62 | } // namespace std 63 | -------------------------------------------------------------------------------- /Disruptor/Util.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Util.h" 3 | 4 | #include "Disruptor/IEventProcessor.h" 5 | #include "Disruptor/ISequence.h" 6 | 7 | 8 | namespace Disruptor 9 | { 10 | namespace Util 11 | { 12 | 13 | std::int32_t ceilingNextPowerOfTwo(std::int32_t x) 14 | { 15 | std::int32_t result = 2; 16 | 17 | while (result < x) 18 | { 19 | result <<= 1; 20 | } 21 | 22 | return result; 23 | } 24 | 25 | bool isPowerOf2(std::int32_t x) 26 | { 27 | return x > 0 && (x & (x - 1)) == 0; 28 | } 29 | 30 | std::int32_t log2(std::int32_t i) 31 | { 32 | std::int32_t r = 0; 33 | while ((i >>= 1) != 0) 34 | { 35 | ++r; 36 | } 37 | return r; 38 | } 39 | 40 | std::int64_t getMinimumSequence(const std::vector< std::shared_ptr< ISequence > >& sequences, std::int64_t minimum) 41 | { 42 | for (auto i = 0u; i < sequences.size(); ++i) 43 | { 44 | auto sequence = sequences[i]->value(); 45 | if (sequence < minimum) 46 | minimum = sequence; 47 | } 48 | return minimum; 49 | } 50 | 51 | std::vector< std::shared_ptr< ISequence > > getSequencesFor(const std::vector< std::shared_ptr< IEventProcessor > >& processors) 52 | { 53 | std::vector< std::shared_ptr< ISequence > > sequences(processors.size()); 54 | 55 | for (auto i = 0u; i < sequences.size(); ++i) 56 | { 57 | sequences[i] = processors[i]->sequence(); 58 | } 59 | 60 | return sequences; 61 | } 62 | 63 | } // namespace Util 64 | } // namespace Disruptor 65 | -------------------------------------------------------------------------------- /Disruptor/WorkerPoolInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Disruptor/IConsumerInfo.h" 6 | #include "Disruptor/WorkerPool.h" 7 | 8 | 9 | namespace Disruptor 10 | { 11 | 12 | template 13 | class WorkerPoolInfo : public IConsumerInfo 14 | { 15 | public: 16 | WorkerPoolInfo(const std::shared_ptr< WorkerPool< T > >& workerPool, const std::shared_ptr< ISequenceBarrier >& barrier) 17 | : m_workerPool(workerPool) 18 | , m_barrier(barrier) 19 | , m_isEndOfChain(true) 20 | { 21 | } 22 | 23 | std::vector< std::shared_ptr< ISequence > > sequences() const override 24 | { 25 | return m_workerPool->getWorkerSequences(); 26 | } 27 | 28 | const std::shared_ptr< ISequenceBarrier >& barrier() const override 29 | { 30 | return m_barrier; 31 | } 32 | 33 | bool isEndOfChain() const override 34 | { 35 | return m_isEndOfChain; 36 | } 37 | 38 | void start(const std::shared_ptr< IExecutor >& executor) override 39 | { 40 | m_workerPool->start(executor); 41 | } 42 | 43 | void halt() override 44 | { 45 | m_workerPool->halt(); 46 | } 47 | 48 | void markAsUsedInBarrier() override 49 | { 50 | m_isEndOfChain = false; 51 | } 52 | 53 | bool isRunning() const override 54 | { 55 | return m_workerPool->isRunning(); 56 | } 57 | 58 | private: 59 | std::shared_ptr< WorkerPool< T > > m_workerPool; 60 | std::shared_ptr< ISequenceBarrier > m_barrier; 61 | bool m_isEndOfChain; 62 | }; 63 | 64 | } // namespace Disruptor 65 | -------------------------------------------------------------------------------- /Disruptor/YieldingWaitStrategy.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "YieldingWaitStrategy.h" 3 | 4 | #include 5 | 6 | #include "ISequenceBarrier.h" 7 | #include "Sequence.h" 8 | 9 | 10 | namespace Disruptor 11 | { 12 | 13 | std::int64_t YieldingWaitStrategy::waitFor(std::int64_t sequence, 14 | Sequence& /*cursor*/, 15 | ISequence& dependentSequence, 16 | ISequenceBarrier& barrier) 17 | { 18 | std::int64_t availableSequence; 19 | auto counter = m_spinTries; 20 | 21 | while ((availableSequence = dependentSequence.value()) < sequence) 22 | { 23 | counter = applyWaitMethod(barrier, counter); 24 | } 25 | 26 | return availableSequence; 27 | } 28 | 29 | void YieldingWaitStrategy::signalAllWhenBlocking() 30 | { 31 | } 32 | 33 | std::int32_t YieldingWaitStrategy::applyWaitMethod(ISequenceBarrier& barrier, std::int32_t counter) 34 | { 35 | barrier.checkAlert(); 36 | 37 | if (counter == 0) 38 | { 39 | std::this_thread::yield(); 40 | } 41 | else 42 | { 43 | --counter; 44 | } 45 | 46 | return counter; 47 | } 48 | 49 | void YieldingWaitStrategy::writeDescriptionTo(std::ostream& stream) const 50 | { 51 | stream << "YieldingWaitStrategy"; 52 | } 53 | 54 | } // namespace Disruptor 55 | -------------------------------------------------------------------------------- /Disruptor/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // disruptorLib.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /Disruptor/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #if _MSC_VER // only on Windows 11 | 12 | # ifndef WIN32_LEAN_AND_MEAN 13 | # define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 14 | # endif 15 | 16 | # pragma warning(disable: 4512) // Assignment operator could not be generated 17 | 18 | # include "targetver.h" 19 | # include 20 | # include 21 | # include 22 | #endif 23 | 24 | // STL includes 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | -------------------------------------------------------------------------------- /Disruptor/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | branches: 3 | only: 4 | - master 5 | image: Visual Studio 2017 6 | configuration: Release 7 | platform: x64 8 | environment: 9 | BOOST_HOME: C:\Libraries\boost_1_67_0 10 | BOOST_LIB_PATH: C:\Libraries\boost_1_67_0\lib64-msvc-14.1 11 | before_build: 12 | - cmd: set PATH=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin;%PATH% 13 | build: 14 | project: msvc\2017\Disruptor-all.sln 15 | verbosity: normal -------------------------------------------------------------------------------- /cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 3 | endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | 5 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | list(REVERSE files) 8 | foreach (file ${files}) 9 | message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 10 | if (EXISTS "$ENV{DESTDIR}${file}") 11 | execute_process( 12 | COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" 13 | OUTPUT_VARIABLE rm_out 14 | RESULT_VARIABLE rm_retval 15 | ) 16 | if(NOT ${rm_retval} EQUAL 0) 17 | message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 18 | endif (NOT ${rm_retval} EQUAL 0) 19 | else (EXISTS "$ENV{DESTDIR}${file}") 20 | message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 21 | endif (EXISTS "$ENV{DESTDIR}${file}") 22 | endforeach(file) 23 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore CI build directory 2 | build/ 3 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6.2) 2 | 3 | project( googletest-distribution ) 4 | 5 | enable_testing() 6 | 7 | option(BUILD_GTEST "Builds the googletest subproject" OFF) 8 | 9 | #Note that googlemock target already builds googletest 10 | option(BUILD_GMOCK "Builds the googlemock subproject" ON) 11 | 12 | if(BUILD_GMOCK) 13 | add_subdirectory( googlemock ) 14 | elseif(BUILD_GTEST) 15 | add_subdirectory( googletest ) 16 | endif() 17 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This file contains a list of people who've made non-trivial 2 | # contribution to the Google C++ Mocking Framework project. People 3 | # who commit code to the project are encouraged to add their names 4 | # here. Please keep the list sorted by first names. 5 | 6 | Benoit Sigoure 7 | Bogdan Piloca 8 | Chandler Carruth 9 | Dave MacLachlan 10 | David Anderson 11 | Dean Sturtevant 12 | Gene Volovich 13 | Hal Burch 14 | Jeffrey Yasskin 15 | Jim Keller 16 | Joe Walnes 17 | Jon Wray 18 | Keir Mierle 19 | Keith Ray 20 | Kostya Serebryany 21 | Lev Makhlis 22 | Manuel Klimek 23 | Mario Tanev 24 | Mark Paskin 25 | Markus Heule 26 | Matthew Simmons 27 | Mike Bland 28 | Neal Norwitz 29 | Nermin Ozkiranartli 30 | Owen Carlsen 31 | Paneendra Ba 32 | Paul Menage 33 | Piotr Kaminski 34 | Russ Rufer 35 | Sverre Sundsdal 36 | Takeshi Yoshino 37 | Vadim Berman 38 | Vlad Losev 39 | Wolfgang Klier 40 | Zhanyong Wan 41 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/build-aux/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abc-Arbitrage/Disruptor-cpp/5a9390faa9982756427ae1b9ce3e986360808a68/googletest-release-1.8.0/googlemock/build-aux/.keep -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/docs/Documentation.md: -------------------------------------------------------------------------------- 1 | This page lists all documentation wiki pages for Google Mock **(the SVN trunk version)** 2 | - **if you use a released version of Google Mock, please read the documentation for that specific version instead.** 3 | 4 | * [ForDummies](ForDummies.md) -- start here if you are new to Google Mock. 5 | * [CheatSheet](CheatSheet.md) -- a quick reference. 6 | * [CookBook](CookBook.md) -- recipes for doing various tasks using Google Mock. 7 | * [FrequentlyAskedQuestions](FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. 8 | 9 | To contribute code to Google Mock, read: 10 | 11 | * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. 12 | * [Pump Manual](../googletest/docs/PumpManual.md) -- how we generate some of Google Mock's source files. 13 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/docs/KnownIssues.md: -------------------------------------------------------------------------------- 1 | As any non-trivial software system, Google Mock has some known limitations and problems. We are working on improving it, and welcome your help! The follow is a list of issues we know about. 2 | 3 | 4 | 5 | ## README contains outdated information on Google Mock's compatibility with other testing frameworks ## 6 | 7 | The `README` file in release 1.1.0 still says that Google Mock only works with Google Test. Actually, you can configure Google Mock to work with any testing framework you choose. 8 | 9 | ## Tests failing on machines using Power PC CPUs (e.g. some Macs) ## 10 | 11 | `gmock_output_test` and `gmock-printers_test` are known to fail with Power PC CPUs. This is due to portability issues with these tests, and is not an indication of problems in Google Mock itself. You can safely ignore them. 12 | 13 | ## Failed to resolve libgtest.so.0 in tests when built against installed Google Test ## 14 | 15 | This only applies if you manually built and installed Google Test, and then built a Google Mock against it (either explicitly, or because gtest-config was in your path post-install). In this situation, Libtool has a known issue with certain systems' ldconfig setup: 16 | 17 | http://article.gmane.org/gmane.comp.sysutils.automake.general/9025 18 | 19 | This requires a manual run of "sudo ldconfig" after the "sudo make install" for Google Test before any binaries which link against it can be executed. This isn't a bug in our install, but we should at least have documented it or hacked a work-around into our install. We should have one of these solutions in our next release. -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/docs/v1_5/Documentation.md: -------------------------------------------------------------------------------- 1 | This page lists all documentation wiki pages for Google Mock **version 1.5.0** -- **if you use a different version of Google Mock, please read the documentation for that specific version instead.** 2 | 3 | * [ForDummies](V1_5_ForDummies.md) -- start here if you are new to Google Mock. 4 | * [CheatSheet](V1_5_CheatSheet.md) -- a quick reference. 5 | * [CookBook](V1_5_CookBook.md) -- recipes for doing various tasks using Google Mock. 6 | * [FrequentlyAskedQuestions](V1_5_FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. 7 | 8 | To contribute code to Google Mock, read: 9 | 10 | * DevGuide -- read this _before_ writing your first patch. 11 | * [Pump Manual](http://code.google.com/p/googletest/wiki/PumpManual) -- how we generate some of Google Mock's source files. -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/docs/v1_6/Documentation.md: -------------------------------------------------------------------------------- 1 | This page lists all documentation wiki pages for Google Mock **1.6** 2 | - **if you use a released version of Google Mock, please read the documentation for that specific version instead.** 3 | 4 | * [ForDummies](V1_6_ForDummies.md) -- start here if you are new to Google Mock. 5 | * [CheatSheet](V1_6_CheatSheet.md) -- a quick reference. 6 | * [CookBook](V1_6_CookBook.md) -- recipes for doing various tasks using Google Mock. 7 | * [FrequentlyAskedQuestions](V1_6_FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. 8 | 9 | To contribute code to Google Mock, read: 10 | 11 | * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. 12 | * [Pump Manual](http://code.google.com/p/googletest/wiki/V1_6_PumpManual) -- how we generate some of Google Mock's source files. -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/docs/v1_7/Documentation.md: -------------------------------------------------------------------------------- 1 | This page lists all documentation wiki pages for Google Mock **(the SVN trunk version)** 2 | - **if you use a released version of Google Mock, please read the documentation for that specific version instead.** 3 | 4 | * [ForDummies](V1_7_ForDummies.md) -- start here if you are new to Google Mock. 5 | * [CheatSheet](V1_7_CheatSheet.md) -- a quick reference. 6 | * [CookBook](V1_7_CookBook.md) -- recipes for doing various tasks using Google Mock. 7 | * [FrequentlyAskedQuestions](V1_7_FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. 8 | 9 | To contribute code to Google Mock, read: 10 | 11 | * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. 12 | * [Pump Manual](http://code.google.com/p/googletest/wiki/PumpManual) -- how we generate some of Google Mock's source files. -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h: -------------------------------------------------------------------------------- 1 | // This file was GENERATED by command: 2 | // pump.py gmock-generated-actions.h.pump 3 | // DO NOT EDIT BY HAND!!! 4 | 5 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 6 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 7 | 8 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 9 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump: -------------------------------------------------------------------------------- 1 | $$ -*- mode: c++; -*- 2 | $$ This is a Pump source file (http://go/pump). Please use Pump to convert 3 | $$ it to callback-actions.h. 4 | $$ 5 | $var max_callback_arity = 5 6 | $$}} This meta comment fixes auto-indentation in editors. 7 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 8 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 9 | 10 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 11 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/msvc/2005/gmock_config.vsprops: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 15 | 16 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/msvc/2010/gmock_config.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ../../../googletest 5 | 6 | 7 | <_ProjectFileVersion>10.0.30319.1 8 | 9 | 10 | 11 | $(GTestDir)/include;%(AdditionalIncludeDirectories) 12 | 13 | 14 | 15 | 16 | $(GTestDir) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/msvc/2015/gmock.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/msvc/2015/gmock_config.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ../../../googletest 5 | 6 | 7 | <_ProjectFileVersion>10.0.30319.1 8 | 9 | 10 | 11 | $(GTestDir)/include;%(AdditionalIncludeDirectories) 12 | 13 | 14 | 15 | 16 | $(GTestDir) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/msvc/2017/gmock.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/msvc/2017/gmock_config.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ../../../googletest 5 | 6 | 7 | <_ProjectFileVersion>10.0.30319.1 8 | 9 | 10 | 11 | $(GTestDir)/include;%(AdditionalIncludeDirectories) 12 | 13 | 14 | 15 | 16 | $(GTestDir) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/msvc/2019/gmock.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/msvc/2019/gmock_config.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ../../../googletest 5 | 6 | 7 | <_ProjectFileVersion>10.0.30319.1 8 | 9 | 10 | 11 | $(GTestDir)/include;%(AdditionalIncludeDirectories) 12 | 13 | 14 | 15 | 16 | $(GTestDir) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/scripts/generator/README: -------------------------------------------------------------------------------- 1 | 2 | The Google Mock class generator is an application that is part of cppclean. 3 | For more information about cppclean, see the README.cppclean file or 4 | visit http://code.google.com/p/cppclean/ 5 | 6 | cppclean requires Python 2.3.5 or later. If you don't have Python installed 7 | on your system, you will also need to install it. You can download Python 8 | from: http://www.python.org/download/releases/ 9 | 10 | To use the Google Mock class generator, you need to call it 11 | on the command line passing the header file and class for which you want 12 | to generate a Google Mock class. 13 | 14 | Make sure to install the scripts somewhere in your path. Then you can 15 | run the program. 16 | 17 | gmock_gen.py header-file.h [ClassName]... 18 | 19 | If no ClassNames are specified, all classes in the file are emitted. 20 | 21 | To change the indentation from the default of 2, set INDENT in 22 | the environment. For example to use an indent of 4 spaces: 23 | 24 | INDENT=4 gmock_gen.py header-file.h ClassName 25 | 26 | This version was made from SVN revision 281 in the cppclean repository. 27 | 28 | Known Limitations 29 | ----------------- 30 | Not all code will be generated properly. For example, when mocking templated 31 | classes, the template information is lost. You will need to add the template 32 | information manually. 33 | 34 | Not all permutations of using multiple pointers/references will be rendered 35 | properly. These will also have to be fixed manually. 36 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/scripts/generator/cpp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abc-Arbitrage/Disruptor-cpp/5a9390faa9982756427ae1b9ce3e986360808a68/googletest-release-1.8.0/googlemock/scripts/generator/cpp/__init__.py -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/scripts/generator/cpp/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2007 Neal Norwitz 4 | # Portions Copyright 2007 Google Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """Generic utilities for C++ parsing.""" 19 | 20 | __author__ = 'nnorwitz@google.com (Neal Norwitz)' 21 | 22 | 23 | import sys 24 | 25 | 26 | # Set to True to see the start/end token indices. 27 | DEBUG = True 28 | 29 | 30 | def ReadFile(filename, print_error=True): 31 | """Returns the contents of a file.""" 32 | try: 33 | fp = open(filename) 34 | try: 35 | return fp.read() 36 | finally: 37 | fp.close() 38 | except IOError: 39 | if print_error: 40 | print('Error reading %s: %s' % (filename, sys.exc_info()[1])) 41 | return None 42 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googlemock/scripts/generator/gmock_gen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2008 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Driver for starting up Google Mock class generator.""" 18 | 19 | __author__ = 'nnorwitz@google.com (Neal Norwitz)' 20 | 21 | import os 22 | import sys 23 | 24 | if __name__ == '__main__': 25 | # Add the directory of this script to the path so we can import gmock_class. 26 | sys.path.append(os.path.dirname(__file__)) 27 | 28 | from cpp import gmock_class 29 | # Fix the docstring in case they require the usage. 30 | gmock_class.__doc__ = gmock_class.__doc__.replace('gmock_class.py', __file__) 31 | gmock_class.main() 32 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/.gitignore: -------------------------------------------------------------------------------- 1 | # python 2 | *.pyc 3 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This file contains a list of people who've made non-trivial 2 | # contribution to the Google C++ Testing Framework project. People 3 | # who commit code to the project are encouraged to add their names 4 | # here. Please keep the list sorted by first names. 5 | 6 | Ajay Joshi 7 | Balázs Dán 8 | Bharat Mediratta 9 | Chandler Carruth 10 | Chris Prince 11 | Chris Taylor 12 | Dan Egnor 13 | Eric Roman 14 | Hady Zalek 15 | Jeffrey Yasskin 16 | Jói Sigurðsson 17 | Keir Mierle 18 | Keith Ray 19 | Kenton Varda 20 | Manuel Klimek 21 | Markus Heule 22 | Mika Raento 23 | Miklós Fazekas 24 | Pasi Valminen 25 | Patrick Hanna 26 | Patrick Riley 27 | Peter Kaminski 28 | Preston Jackson 29 | Rainer Klaffenboeck 30 | Russ Cox 31 | Russ Rufer 32 | Sean Mcafee 33 | Sigurður Ásgeirsson 34 | Tracy Bialik 35 | Vadim Berman 36 | Vlad Losev 37 | Zhanyong Wan 38 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/build-aux/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abc-Arbitrage/Disruptor-cpp/5a9390faa9982756427ae1b9ce3e986360808a68/googletest-release-1.8.0/googletest/build-aux/.keep -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/docs/Documentation.md: -------------------------------------------------------------------------------- 1 | This page lists all documentation wiki pages for Google Test **(the SVN trunk version)** 2 | -- **if you use a released version of Google Test, please read the 3 | documentation for that specific version instead.** 4 | 5 | * [Primer](Primer.md) -- start here if you are new to Google Test. 6 | * [Samples](Samples.md) -- learn from examples. 7 | * [AdvancedGuide](AdvancedGuide.md) -- learn more about Google Test. 8 | * [XcodeGuide](XcodeGuide.md) -- how to use Google Test in Xcode on Mac. 9 | * [Frequently-Asked Questions](FAQ.md) -- check here before asking a question on the mailing list. 10 | 11 | To contribute code to Google Test, read: 12 | 13 | * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. 14 | * [PumpManual](PumpManual.md) -- how we generate some of Google Test's source files. -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/docs/Samples.md: -------------------------------------------------------------------------------- 1 | If you're like us, you'd like to look at some Google Test sample code. The 2 | [samples folder](../samples) has a number of well-commented samples showing how to use a 3 | variety of Google Test features. 4 | 5 | * [Sample #1](../samples/sample1_unittest.cc) shows the basic steps of using Google Test to test C++ functions. 6 | * [Sample #2](../samples/sample2_unittest.cc) shows a more complex unit test for a class with multiple member functions. 7 | * [Sample #3](../samples/sample3_unittest.cc) uses a test fixture. 8 | * [Sample #4](../samples/sample4_unittest.cc) is another basic example of using Google Test. 9 | * [Sample #5](../samples/sample5_unittest.cc) teaches how to reuse a test fixture in multiple test cases by deriving sub-fixtures from it. 10 | * [Sample #6](../samples/sample6_unittest.cc) demonstrates type-parameterized tests. 11 | * [Sample #7](../samples/sample7_unittest.cc) teaches the basics of value-parameterized tests. 12 | * [Sample #8](../samples/sample8_unittest.cc) shows using `Combine()` in value-parameterized tests. 13 | * [Sample #9](../samples/sample9_unittest.cc) shows use of the listener API to modify Google Test's console output and the use of its reflection API to inspect test results. 14 | * [Sample #10](../samples/sample10_unittest.cc) shows use of the listener API to implement a primitive memory leak checker. 15 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/docs/V1_5_Documentation.md: -------------------------------------------------------------------------------- 1 | This page lists all official documentation wiki pages for Google Test **1.5.0** -- **if you use a different version of Google Test, make sure to read the documentation for that version instead.** 2 | 3 | * [Primer](V1_5_Primer.md) -- start here if you are new to Google Test. 4 | * [Samples](Samples.md) -- learn from examples. 5 | * [AdvancedGuide](V1_5_AdvancedGuide.md) -- learn more about Google Test. 6 | * [XcodeGuide](V1_5_XcodeGuide.md) -- how to use Google Test in Xcode on Mac. 7 | * [Frequently-Asked Questions](V1_5_FAQ.md) -- check here before asking a question on the mailing list. 8 | 9 | To contribute code to Google Test, read: 10 | 11 | * DevGuide -- read this _before_ writing your first patch. 12 | * [PumpManual](V1_5_PumpManual.md) -- how we generate some of Google Test's source files. -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/docs/V1_6_Documentation.md: -------------------------------------------------------------------------------- 1 | This page lists all documentation wiki pages for Google Test **1.6** 2 | -- **if you use a released version of Google Test, please read the 3 | documentation for that specific version instead.** 4 | 5 | * [Primer](V1_6_Primer.md) -- start here if you are new to Google Test. 6 | * [Samples](V1_6_Samples.md) -- learn from examples. 7 | * [AdvancedGuide](V1_6_AdvancedGuide.md) -- learn more about Google Test. 8 | * [XcodeGuide](V1_6_XcodeGuide.md) -- how to use Google Test in Xcode on Mac. 9 | * [Frequently-Asked Questions](V1_6_FAQ.md) -- check here before asking a question on the mailing list. 10 | 11 | To contribute code to Google Test, read: 12 | 13 | * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. 14 | * [PumpManual](V1_6_PumpManual.md) -- how we generate some of Google Test's source files. -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/docs/V1_6_Samples.md: -------------------------------------------------------------------------------- 1 | If you're like us, you'd like to look at some Google Test sample code. The 2 | [samples folder](../samples) has a number of well-commented samples showing how to use a 3 | variety of Google Test features. 4 | 5 | * [Sample #1](../samples/sample1_unittest.cc) shows the basic steps of using Google Test to test C++ functions. 6 | * [Sample #2](../samples/sample2_unittest.cc) shows a more complex unit test for a class with multiple member functions. 7 | * [Sample #3](../samples/sample3_unittest.cc) uses a test fixture. 8 | * [Sample #4](../samples/sample4_unittest.cc) is another basic example of using Google Test. 9 | * [Sample #5](../samples/sample5_unittest.cc) teaches how to reuse a test fixture in multiple test cases by deriving sub-fixtures from it. 10 | * [Sample #6](../samples/sample6_unittest.cc) demonstrates type-parameterized tests. 11 | * [Sample #7](../samples/sample7_unittest.cc) teaches the basics of value-parameterized tests. 12 | * [Sample #8](../samples/sample8_unittest.cc) shows using `Combine()` in value-parameterized tests. 13 | * [Sample #9](../samples/sample9_unittest.cc) shows use of the listener API to modify Google Test's console output and the use of its reflection API to inspect test results. 14 | * [Sample #10](../samples/sample10_unittest.cc) shows use of the listener API to implement a primitive memory leak checker. 15 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/docs/V1_7_Documentation.md: -------------------------------------------------------------------------------- 1 | This page lists all documentation wiki pages for Google Test **(the SVN trunk version)** 2 | -- **if you use a released version of Google Test, please read the 3 | documentation for that specific version instead.** 4 | 5 | * [Primer](V1_7_Primer.md) -- start here if you are new to Google Test. 6 | * [Samples](V1_7_Samples.md) -- learn from examples. 7 | * [AdvancedGuide](V1_7_AdvancedGuide.md) -- learn more about Google Test. 8 | * [XcodeGuide](V1_7_XcodeGuide.md) -- how to use Google Test in Xcode on Mac. 9 | * [Frequently-Asked Questions](V1_7_FAQ.md) -- check here before asking a question on the mailing list. 10 | 11 | To contribute code to Google Test, read: 12 | 13 | * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. 14 | * [PumpManual](V1_7_PumpManual.md) -- how we generate some of Google Test's source files. -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/docs/V1_7_Samples.md: -------------------------------------------------------------------------------- 1 | If you're like us, you'd like to look at some Google Test sample code. The 2 | [samples folder](../samples) has a number of well-commented samples showing how to use a 3 | variety of Google Test features. 4 | 5 | * [Sample #1](../samples/sample1_unittest.cc) shows the basic steps of using Google Test to test C++ functions. 6 | * [Sample #2](../samples/sample2_unittest.cc) shows a more complex unit test for a class with multiple member functions. 7 | * [Sample #3](../samples/sample3_unittest.cc) uses a test fixture. 8 | * [Sample #4](../samples/sample4_unittest.cc) is another basic example of using Google Test. 9 | * [Sample #5](../samples/sample5_unittest.cc) teaches how to reuse a test fixture in multiple test cases by deriving sub-fixtures from it. 10 | * [Sample #6](../samples/sample6_unittest.cc) demonstrates type-parameterized tests. 11 | * [Sample #7](../samples/sample7_unittest.cc) teaches the basics of value-parameterized tests. 12 | * [Sample #8](../samples/sample8_unittest.cc) shows using `Combine()` in value-parameterized tests. 13 | * [Sample #9](../samples/sample9_unittest.cc) shows use of the listener API to modify Google Test's console output and the use of its reflection API to inspect test results. 14 | * [Sample #10](../samples/sample10_unittest.cc) shows use of the listener API to implement a primitive memory leak checker. 15 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/xcode/Config/DebugProject.xcconfig: -------------------------------------------------------------------------------- 1 | // 2 | // DebugProject.xcconfig 3 | // 4 | // These are Debug Configuration project settings for the gtest framework and 5 | // examples. It is set in the "Based On:" dropdown in the "Project" info 6 | // dialog. 7 | // This file is based on the Xcode Configuration files in: 8 | // http://code.google.com/p/google-toolbox-for-mac/ 9 | // 10 | 11 | #include "General.xcconfig" 12 | 13 | // No optimization 14 | GCC_OPTIMIZATION_LEVEL = 0 15 | 16 | // Deployment postprocessing is what triggers Xcode to strip, turn it off 17 | DEPLOYMENT_POSTPROCESSING = NO 18 | 19 | // Dead code stripping off 20 | DEAD_CODE_STRIPPING = NO 21 | 22 | // Debug symbols should be on obviously 23 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES 24 | 25 | // Define the DEBUG macro in all debug builds 26 | OTHER_CFLAGS = $(OTHER_CFLAGS) -DDEBUG=1 27 | 28 | // These are turned off to avoid STL incompatibilities with client code 29 | // // Turns on special C++ STL checks to "encourage" good STL use 30 | // GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS) _GLIBCXX_DEBUG_PEDANTIC _GLIBCXX_DEBUG _GLIBCPP_CONCEPT_CHECKS 31 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/xcode/Config/FrameworkTarget.xcconfig: -------------------------------------------------------------------------------- 1 | // 2 | // FrameworkTarget.xcconfig 3 | // 4 | // These are Framework target settings for the gtest framework and examples. It 5 | // is set in the "Based On:" dropdown in the "Target" info dialog. 6 | // This file is based on the Xcode Configuration files in: 7 | // http://code.google.com/p/google-toolbox-for-mac/ 8 | // 9 | 10 | // Dynamic libs need to be position independent 11 | GCC_DYNAMIC_NO_PIC = NO 12 | 13 | // Dynamic libs should not have their external symbols stripped. 14 | STRIP_STYLE = non-global 15 | 16 | // Let the user install by specifying the $DSTROOT with xcodebuild 17 | SKIP_INSTALL = NO 18 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/xcode/Config/General.xcconfig: -------------------------------------------------------------------------------- 1 | // 2 | // General.xcconfig 3 | // 4 | // These are General configuration settings for the gtest framework and 5 | // examples. 6 | // This file is based on the Xcode Configuration files in: 7 | // http://code.google.com/p/google-toolbox-for-mac/ 8 | // 9 | 10 | // Build for PPC and Intel, 32- and 64-bit 11 | ARCHS = i386 x86_64 ppc ppc64 12 | 13 | // Zerolink prevents link warnings so turn it off 14 | ZERO_LINK = NO 15 | 16 | // Prebinding considered unhelpful in 10.3 and later 17 | PREBINDING = NO 18 | 19 | // Strictest warning policy 20 | WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow 21 | 22 | // Work around Xcode bugs by using external strip. See: 23 | // http://lists.apple.com/archives/Xcode-users/2006/Feb/msg00050.html 24 | SEPARATE_STRIP = YES 25 | 26 | // Force C99 dialect 27 | GCC_C_LANGUAGE_STANDARD = c99 28 | 29 | // not sure why apple defaults this on, but it's pretty risky 30 | ALWAYS_SEARCH_USER_PATHS = NO 31 | 32 | // Turn on position dependent code for most cases (overridden where appropriate) 33 | GCC_DYNAMIC_NO_PIC = YES 34 | 35 | // Default SDK and minimum OS version is 10.4 36 | SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk 37 | MACOSX_DEPLOYMENT_TARGET = 10.4 38 | GCC_VERSION = 4.0 39 | 40 | // VERSIONING BUILD SETTINGS (used in Info.plist) 41 | GTEST_VERSIONINFO_ABOUT = © 2008 Google Inc. 42 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/xcode/Config/ReleaseProject.xcconfig: -------------------------------------------------------------------------------- 1 | // 2 | // ReleaseProject.xcconfig 3 | // 4 | // These are Release Configuration project settings for the gtest framework 5 | // and examples. It is set in the "Based On:" dropdown in the "Project" info 6 | // dialog. 7 | // This file is based on the Xcode Configuration files in: 8 | // http://code.google.com/p/google-toolbox-for-mac/ 9 | // 10 | 11 | #include "General.xcconfig" 12 | 13 | // subconfig/Release.xcconfig 14 | 15 | // Optimize for space and size (Apple recommendation) 16 | GCC_OPTIMIZATION_LEVEL = s 17 | 18 | // Deploment postprocessing is what triggers Xcode to strip 19 | DEPLOYMENT_POSTPROCESSING = YES 20 | 21 | // No symbols 22 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO 23 | 24 | // Dead code strip does not affect ObjC code but can help for C 25 | DEAD_CODE_STRIPPING = YES 26 | 27 | // NDEBUG is used by things like assert.h, so define it for general compat. 28 | // ASSERT going away in release tends to create unused vars. 29 | OTHER_CFLAGS = $(OTHER_CFLAGS) -DNDEBUG=1 -Wno-unused-variable 30 | 31 | // When we strip we want to strip all symbols in release, but save externals. 32 | STRIP_STYLE = all 33 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/xcode/Config/StaticLibraryTarget.xcconfig: -------------------------------------------------------------------------------- 1 | // 2 | // StaticLibraryTarget.xcconfig 3 | // 4 | // These are static library target settings for libgtest.a. It 5 | // is set in the "Based On:" dropdown in the "Target" info dialog. 6 | // This file is based on the Xcode Configuration files in: 7 | // http://code.google.com/p/google-toolbox-for-mac/ 8 | // 9 | 10 | // Static libs can be included in bundles so make them position independent 11 | GCC_DYNAMIC_NO_PIC = NO 12 | 13 | // Static libs should not have their internal globals or external symbols 14 | // stripped. 15 | STRIP_STYLE = debugging 16 | 17 | // Let the user install by specifying the $DSTROOT with xcodebuild 18 | SKIP_INSTALL = NO 19 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/xcode/Config/TestTarget.xcconfig: -------------------------------------------------------------------------------- 1 | // 2 | // TestTarget.xcconfig 3 | // 4 | // These are Test target settings for the gtest framework and examples. It 5 | // is set in the "Based On:" dropdown in the "Target" info dialog. 6 | 7 | PRODUCT_NAME = $(TARGET_NAME) 8 | HEADER_SEARCH_PATHS = ../include 9 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/xcode/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.google.${PRODUCT_NAME} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | GTEST_VERSIONINFO_LONG 21 | CFBundleShortVersionString 22 | GTEST_VERSIONINFO_SHORT 23 | CFBundleGetInfoString 24 | ${PRODUCT_NAME} GTEST_VERSIONINFO_LONG, ${GTEST_VERSIONINFO_ABOUT} 25 | NSHumanReadableCopyright 26 | ${GTEST_VERSIONINFO_ABOUT} 27 | CSResourcesFileMapped 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/googletest/xcode/Samples/FrameworkSample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.google.gtest.${PRODUCT_NAME:identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | CSResourcesFileMapped 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /googletest-release-1.8.0/travis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -evx 3 | env | sort 4 | 5 | mkdir build || true 6 | mkdir build/$GTEST_TARGET || true 7 | cd build/$GTEST_TARGET 8 | cmake -Dgtest_build_samples=ON \ 9 | -Dgmock_build_samples=ON \ 10 | -Dgtest_build_tests=ON \ 11 | -Dgmock_build_tests=ON \ 12 | -DCMAKE_CXX_FLAGS=$CXX_FLAGS \ 13 | ../../$GTEST_TARGET 14 | make 15 | CTEST_OUTPUT_ON_FAILURE=1 make test 16 | -------------------------------------------------------------------------------- /msvc/2015/Disruptor-lib.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.25420.1 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Disruptor", "Disruptor.vcxproj", "{0A1FF4F2-CD19-4B2B-944A-F14B849A2588}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|x64 = Debug|x64 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Debug|x64.ActiveCfg = Debug|x64 14 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Debug|x64.Build.0 = Debug|x64 15 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Release|x64.ActiveCfg = Release|x64 16 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Release|x64.Build.0 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {6BE09E8D-A408-4BC1-97CD-D761CC2E301E} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /msvc/2017/Disruptor-lib.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27004.2006 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Disruptor", "Disruptor.vcxproj", "{0A1FF4F2-CD19-4B2B-944A-F14B849A2588}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|x64 = Debug|x64 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Debug|x64.ActiveCfg = Debug|x64 14 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Debug|x64.Build.0 = Debug|x64 15 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Release|x64.ActiveCfg = Release|x64 16 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Release|x64.Build.0 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {6BE09E8D-A408-4BC1-97CD-D761CC2E301E} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /msvc/2019/Disruptor-all.sln.DotSettings.user: -------------------------------------------------------------------------------- 1 |  2 | <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;Tests&gt;\&lt;Disruptor.Tests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> 3 | <Project Location="C:\Dev\Disruptor-cpp\msvc\2019" Presentation="&lt;Tests&gt;\&lt;Disruptor.Tests&gt;" /> 4 | </SessionState> -------------------------------------------------------------------------------- /msvc/2019/Disruptor-lib.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27004.2006 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Disruptor", "Disruptor.vcxproj", "{0A1FF4F2-CD19-4B2B-944A-F14B849A2588}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|x64 = Debug|x64 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Debug|x64.ActiveCfg = Debug|x64 14 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Debug|x64.Build.0 = Debug|x64 15 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Release|x64.ActiveCfg = Release|x64 16 | {0A1FF4F2-CD19-4B2B-944A-F14B849A2588}.Release|x64.Build.0 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {6BE09E8D-A408-4BC1-97CD-D761CC2E301E} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /msvc/2019/Disruptor.PerfTests.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /msvc/2019/Disruptor.TestTools.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /msvc/2019/Disruptor.Tests.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /msvc/2019/Disruptor.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /msvc/boost.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(BOOST_HOME)/ 7 | $(BoostRoot) 8 | $(BoostRoot)lib\ 9 | $(BoostRoot)lib\msvc$(PlatformToolsetVersion)-x64\ 10 | $(BOOST_LIB_PATH) 11 | 12 | 13 | 14 | $(BoostIncludePath);%(AdditionalIncludeDirectories) 15 | 16 | 17 | $(BoostLibraryPath);%(AdditionalLibraryDirectories) 18 | 19 | 20 | %(Command) 21 | 22 | 23 | -------------------------------------------------------------------------------- /msvc/disruptor.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)')) 6 | 7 | 8 | 9 | $(root)\;%(AdditionalIncludeDirectories) 10 | 11 | 12 | $(root)lib\Debug_$(Platform)_$(PlatformToolset)\Disruptor;%(AdditionalLibraryDirectories) 13 | $(root)lib\Release_$(Platform)_$(PlatformToolset)\Disruptor;%(AdditionalLibraryDirectories) 14 | Disruptor.lib;%(AdditionalDependencies) 15 | 16 | 17 | --------------------------------------------------------------------------------