|
-
- #include "asserts.h"
- #include "ThreadSharedState.h"
- #include "ThreadServer.h"
- #include "ThreadClient.h"
- #include "ThreadPriority.h"
-
- #include <assert.h>
- #include <memory>
- #include <vector>
-
-
-
- // test that we can build and tear down.
- static void test0()
- {
- assertEQ(ThreadSharedState::_dbgCount, 0);
- {
- std::shared_ptr<ThreadSharedState> noise = std::make_shared<ThreadSharedState>();
- std::unique_ptr<ThreadServer> server(new ThreadServer(noise));
- std::unique_ptr<ThreadClient> client(new ThreadClient(noise, std::move(server)));
- }
- assertEQ(ThreadSharedState::_dbgCount, 0);
- }
-
- static void test1()
- {
- for (int i = 0; i < 200; ++i)
- test0();
- }
-
- /**************************************************************************/
-
- // client will send to server
- class Test1Message : public ThreadMessage
- {
- public:
- Test1Message() : ThreadMessage(Type::TEST1)
- {
- }
- int payload = 0;
- };
-
- // client will send to server
- class Test2Message : public ThreadMessage
- {
- public:
- Test2Message() : ThreadMessage(Type::TEST2)
- {
- }
- };
-
- class TestServer : public ThreadServer
- {
- public:
- TestServer(std::shared_ptr<ThreadSharedState> state) : ThreadServer(state)
- {
- }
- void handleMessage(ThreadMessage* msg) override
- {
- switch (msg->type) {
- case ThreadMessage::Type::TEST1:
- {
- Test1Message * tstMsg = static_cast<Test1Message *>(msg);
- assertEQ(tstMsg->payload, nextExpectedPayload);
- ++nextExpectedPayload;
- tstMsg->payload += 1000;
- sendMessageToClient(tstMsg); // send back the modified one
- }
- break;
- default:
- assert(false);
- }
- }
- int nextExpectedPayload = 100;
- };
-
- static void test2()
- {
- // Set up all the objects
- std::unique_ptr<Test1Message> msg(new Test1Message());
- std::shared_ptr<ThreadSharedState> state = std::make_shared<ThreadSharedState>();
- std::unique_ptr<TestServer> server(new TestServer(state));
- std::unique_ptr<ThreadClient> client(new ThreadClient(state, std::move(server)));
-
- for (int count = 0; count < 50; ++count) {
- msg->payload = 100 + count;
- const int expectedPayload = msg->payload + 1000;
- for (bool done = false; !done; ) {
- bool b = client->sendMessage(msg.get());
- if (b) {
- done = true;
- }
- }
-
- for (bool done = false; !done; ) {
- auto rxmsg = client->getMessage();
- if (rxmsg) {
- done = true;
- assert(rxmsg->type == ThreadMessage::Type::TEST1);
- Test1Message* tmsg = reinterpret_cast<Test1Message *>(rxmsg);
- assertEQ(tmsg->payload, expectedPayload);
- }
- }
- }
- }
-
- // not a real test
- static void test3()
- {
- bool b = ThreadPriority::boostNormal();
- bool b2 = ThreadPriority::boostRealtime();
- printf("\nnormal boost: %d\n", b);
- printf("realtime boost: %d\n", b2);
- ThreadPriority::restore();
- }
-
- static std::atomic<bool> stopNow;
- static std::atomic<int> count;
- static double xxx, yyy;
- static std::atomic<int> slow;
- static std::atomic<int> fast;
-
- //thread func
- static void t4(bool iAmIt,int boost)
- {
- // printf("t4 called with %d\n", iAmIt);
-
- if (iAmIt) {
- switch (boost) {
- case 0:
- printf("no boost\n");
- break;
- case 1:
- printf("boosting\n");
- ThreadPriority::boostNormal();
- break;
- case 2:
- printf("boosting RT\n");
- ThreadPriority::boostRealtime();
- break;
- default:
- assert(false);
- }
-
- fflush(stdout);
-
- }
- while (!stopNow) {
- for (int i = 0; i < 100000; ++i) {
- yyy = yyy + (double) rand();
- }
-
- if (iAmIt) {
- ++fast;
- } else {
- ++slow;
- }
- }
- }
-
- // runs all the test treads, returns ratio of work done in the default theads
- // and work done in test thread.
- static double test4sub(int boost)
- {
- stopNow = false;
- count = 0;
- xxx = 0;
- yyy = 0;
- slow = 0;
- fast = 0;
- int numSlow = 0;
- std::vector< std::shared_ptr<std::thread>> threads;
-
- threads.push_back(std::make_shared<std::thread>(t4, true, boost));
- for (int i = 0; i < 9; ++i) {
- threads.push_back(std::make_shared<std::thread>(t4, false, 0));
- ++numSlow;
- }
-
- printf("started all\n");
- xxx = 0;
- yyy = 0;
-
- std::this_thread::sleep_for(std::chrono::seconds(20));
- stopNow = true;
-
- for (auto thread : threads) {
- thread->join();
- }
-
- ThreadPriority::restore();
- const double ret = (double) slow / (double) fast;
- printf("slow/fast was %f (%d) ratio=%d\n", ret, (int) slow, numSlow);
- return ret;
- }
-
- static void test4()
- {
- printf("testing thread priorities, part1. will take a while\n"); fflush(stdout);
- const double ref = test4sub(0);
- printf("testing thread priorities, part2. will take a while\n"); fflush(stdout);
- const double boosted = test4sub(1);
- printf("testing thread priorities, part3. will take a while\n"); fflush(stdout);
- const double boostedRT = test4sub(2);
- printf("ref = %f, boosted = %f rt=%f\n", ref, boosted, boostedRT); fflush(stdout);
- }
-
- #ifdef ARCH_WIN
- static void test5()
- {
- ThreadPriority::boostRealtimeWindows();
- }
- #endif
- /*****************************************************************/
-
- void testThread(bool extended)
- {
-
- assertEQ(ThreadSharedState::_dbgCount, 0);
- assertEQ(ThreadMessage::_dbgCount, 0);
- test0();
- test1();
- test2();
- test3();
- if (extended) {
- test4();
- }
- #ifdef ARCH_WIN
- test5();
- #endif
- assertEQ(ThreadSharedState::_dbgCount, 0);
- assertEQ(ThreadMessage::_dbgCount, 0);
- }
|