aboutsummaryrefslogtreecommitdiffstats
path: root/fnet/src/tests/locking/drainpackets.cpp
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /fnet/src/tests/locking/drainpackets.cpp
Publish
Diffstat (limited to 'fnet/src/tests/locking/drainpackets.cpp')
-rw-r--r--fnet/src/tests/locking/drainpackets.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/fnet/src/tests/locking/drainpackets.cpp b/fnet/src/tests/locking/drainpackets.cpp
new file mode 100644
index 00000000000..066923f0c70
--- /dev/null
+++ b/fnet/src/tests/locking/drainpackets.cpp
@@ -0,0 +1,134 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/vespalib/testkit/test_kit.h>
+#include <vespa/fnet/fnet.h>
+
+
+class MyPacket : public FNET_Packet
+{
+public:
+ uint32_t GetPCODE() { return 0; }
+ uint32_t GetLength() { return 0; }
+ void Encode(FNET_DataBuffer *) {}
+ bool Decode(FNET_DataBuffer *, uint32_t)
+ { return true; }
+};
+
+
+TEST("drain packets") {
+ FastOS_Time start;
+ FastOS_Time stop;
+
+ FNET_Mutex lock;
+
+ FNET_PacketQueue q1(512);
+ FNET_PacketQueue q2(512);
+ FNET_PacketQueue q3(512);
+
+ int i;
+
+ // create dummy packets
+
+ for (i = 0; i < 500; i++) {
+ q1.QueuePacket_NoLock(new MyPacket(), FNET_Context());
+ }
+
+ // drain packets directly with single lock interval
+
+ start.SetNow();
+
+ for (i = 0; i < 10000; i++) {
+
+ FNET_Packet *packet;
+ FNET_Context context;
+
+ lock.Lock();
+
+ while (!q1.IsEmpty_NoLock()) {
+ packet = q1.DequeuePacket_NoLock(&context);
+ q3.QueuePacket_NoLock(packet, context);
+ }
+
+ lock.Unlock();
+
+ //------------------------
+
+ lock.Lock();
+
+ while (!q3.IsEmpty_NoLock()) {
+ packet = q3.DequeuePacket_NoLock(&context);
+ q1.QueuePacket_NoLock(packet, context);
+ }
+
+ lock.Unlock();
+ }
+
+ stop.SetNow();
+ stop -= start;
+ fprintf(stderr, "direct, single lock interval (10M packets): %1.2f ms\n",
+ stop.MilliSecs());
+
+ // flush packets, then move without lock
+
+ start.SetNow();
+
+ for (i = 0; i < 10000; i++) {
+
+ FNET_Packet *packet;
+ FNET_Context context;
+
+ lock.Lock();
+ q1.FlushPackets_NoLock(&q2);
+ lock.Unlock();
+
+ while (!q2.IsEmpty_NoLock()) {
+ packet = q2.DequeuePacket_NoLock(&context);
+ q3.QueuePacket_NoLock(packet, context);
+ }
+
+ //------------------------
+
+ lock.Lock();
+ q3.FlushPackets_NoLock(&q2);
+ lock.Unlock();
+
+ while (!q2.IsEmpty_NoLock()) {
+ packet = q2.DequeuePacket_NoLock(&context);
+ q1.QueuePacket_NoLock(packet, context);
+ }
+ }
+
+ stop.SetNow();
+ stop -= start;
+ fprintf(stderr, "indirect (10M packets): %1.2f ms\n", stop.MilliSecs());
+
+ // drain packets directly with multiple lock intervals
+
+ start.SetNow();
+
+ for (i = 0; i < 10000; i++) {
+
+ FNET_Packet *packet;
+ FNET_Context context;
+
+ while ((packet = q1.DequeuePacket(0, &context)) != NULL) {
+ q3.QueuePacket_NoLock(packet, context);
+ }
+
+ //------------------------
+
+ while ((packet = q3.DequeuePacket(0, &context)) != NULL) {
+ q1.QueuePacket_NoLock(packet, context);
+ }
+ }
+
+ stop.SetNow();
+ stop -= start;
+ fprintf(stderr, "direct, multiple lock intervals (10M packets): %1.2f ms\n",
+ stop.MilliSecs());
+
+ EXPECT_TRUE(q1.GetPacketCnt_NoLock() == 500 &&
+ q2.GetPacketCnt_NoLock() == 0 &&
+ q3.GetPacketCnt_NoLock() == 0);
+}
+
+TEST_MAIN() { TEST_RUN_ALL(); }