null-common.h (5037B)
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #include "common.h" 23 24 namespace capnp { 25 namespace benchmark { 26 namespace null { 27 28 uint64_t arena[1024*1024]; 29 uint64_t* arenaPos = arena; 30 31 template <typename T> 32 T* allocate(int count = 1) { 33 T* result = reinterpret_cast<T*>(arenaPos); 34 arenaPos += (sizeof(T) * count + 7) / 8; 35 if (arenaPos > arena + sizeof(arena) / sizeof(arena[0])) { 36 throw std::bad_alloc(); 37 } 38 return result; 39 } 40 41 char* copyString(const char* str) { 42 size_t len = strlen(str); 43 char* result = allocate<char>(len); 44 memcpy(result, str, len + 1); 45 return result; 46 } 47 48 template <typename T> 49 struct List { 50 size_t size; 51 T* items; 52 53 inline T* begin() const { return items; } 54 inline T* end() const { return items + size; } 55 56 inline List<T>& init(size_t size) { 57 this->size = size; 58 items = allocate<T>(size); 59 return *this; 60 } 61 }; 62 63 // ======================================================================================= 64 65 struct SingleUseObjects { 66 class ObjectSizeCounter { 67 public: 68 ObjectSizeCounter(uint64_t iters): counter(0) {} 69 70 void add(uint64_t wordCount) { 71 counter += wordCount; 72 } 73 74 uint64_t get() { return counter; } 75 76 private: 77 uint64_t counter; 78 }; 79 }; 80 81 struct ReusableObjects { 82 class ObjectSizeCounter { 83 public: 84 ObjectSizeCounter(uint64_t iters): iters(iters), maxSize(0) {} 85 86 void add(size_t wordCount) { 87 maxSize = std::max(wordCount, maxSize); 88 } 89 90 uint64_t get() { return iters * maxSize; } 91 92 private: 93 uint64_t iters; 94 size_t maxSize; 95 }; 96 }; 97 98 // ======================================================================================= 99 100 template <typename TestCase, typename ReuseStrategy, typename Compression> 101 struct BenchmarkMethods { 102 static uint64_t syncClient(int inputFd, int outputFd, uint64_t iters) { 103 fprintf(stderr, "Null benchmark doesn't do I/O.\n"); 104 exit(1); 105 } 106 107 static uint64_t asyncClientSender( 108 int outputFd, ProducerConsumerQueue<typename TestCase::Expectation>* expectations, 109 uint64_t iters) { 110 fprintf(stderr, "Null benchmark doesn't do I/O.\n"); 111 exit(1); 112 } 113 114 static void asyncClientReceiver( 115 int inputFd, ProducerConsumerQueue<typename TestCase::Expectation>* expectations, 116 uint64_t iters) { 117 fprintf(stderr, "Null benchmark doesn't do I/O.\n"); 118 exit(1); 119 } 120 121 static uint64_t asyncClient(int inputFd, int outputFd, uint64_t iters) { 122 fprintf(stderr, "Null benchmark doesn't do I/O.\n"); 123 exit(1); 124 } 125 126 static uint64_t server(int inputFd, int outputFd, uint64_t iters) { 127 fprintf(stderr, "Null benchmark doesn't do I/O.\n"); 128 exit(1); 129 } 130 131 static uint64_t passByObject(uint64_t iters, bool countObjectSize) { 132 typename ReuseStrategy::ObjectSizeCounter sizeCounter(iters); 133 134 for (; iters > 0; --iters) { 135 arenaPos = arena; 136 137 typename TestCase::Request request; 138 typename TestCase::Expectation expected = TestCase::setupRequest(&request); 139 140 typename TestCase::Response response; 141 TestCase::handleRequest(request, &response); 142 if (!TestCase::checkResponse(response, expected)) { 143 throw std::logic_error("Incorrect response."); 144 } 145 146 sizeCounter.add((arenaPos - arena) * sizeof(arena[0])); 147 } 148 149 return sizeCounter.get(); 150 } 151 152 static uint64_t passByBytes(uint64_t iters) { 153 fprintf(stderr, "Null benchmark doesn't do I/O.\n"); 154 exit(1); 155 } 156 }; 157 158 struct BenchmarkTypes { 159 typedef void Uncompressed; 160 typedef void Packed; 161 #if HAVE_SNAPPY 162 typedef void SnappyCompressed; 163 #endif // HAVE_SNAPPY 164 165 typedef ReusableObjects ReusableResources; 166 typedef SingleUseObjects SingleUseResources; 167 168 template <typename TestCase, typename ReuseStrategy, typename Compression> 169 struct BenchmarkMethods: public null::BenchmarkMethods<TestCase, ReuseStrategy, Compression> {}; 170 }; 171 172 } // namespace null 173 } // namespace benchmark 174 } // namespace capnp