// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors // Licensed under the MIT License: // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #include "common.h" namespace capnp { namespace benchmark { namespace null { uint64_t arena[1024*1024]; uint64_t* arenaPos = arena; template <typename T> T* allocate(int count = 1) { T* result = reinterpret_cast<T*>(arenaPos); arenaPos += (sizeof(T) * count + 7) / 8; if (arenaPos > arena + sizeof(arena) / sizeof(arena[0])) { throw std::bad_alloc(); } return result; } char* copyString(const char* str) { size_t len = strlen(str); char* result = allocate<char>(len); memcpy(result, str, len + 1); return result; } template <typename T> struct List { size_t size; T* items; inline T* begin() const { return items; } inline T* end() const { return items + size; } inline List<T>& init(size_t size) { this->size = size; items = allocate<T>(size); return *this; } }; // ======================================================================================= struct SingleUseObjects { class ObjectSizeCounter { public: ObjectSizeCounter(uint64_t iters): counter(0) {} void add(uint64_t wordCount) { counter += wordCount; } uint64_t get() { return counter; } private: uint64_t counter; }; }; struct ReusableObjects { class ObjectSizeCounter { public: ObjectSizeCounter(uint64_t iters): iters(iters), maxSize(0) {} void add(size_t wordCount) { maxSize = std::max(wordCount, maxSize); } uint64_t get() { return iters * maxSize; } private: uint64_t iters; size_t maxSize; }; }; // ======================================================================================= template <typename TestCase, typename ReuseStrategy, typename Compression> struct BenchmarkMethods { static uint64_t syncClient(int inputFd, int outputFd, uint64_t iters) { fprintf(stderr, "Null benchmark doesn't do I/O.\n"); exit(1); } static uint64_t asyncClientSender( int outputFd, ProducerConsumerQueue<typename TestCase::Expectation>* expectations, uint64_t iters) { fprintf(stderr, "Null benchmark doesn't do I/O.\n"); exit(1); } static void asyncClientReceiver( int inputFd, ProducerConsumerQueue<typename TestCase::Expectation>* expectations, uint64_t iters) { fprintf(stderr, "Null benchmark doesn't do I/O.\n"); exit(1); } static uint64_t asyncClient(int inputFd, int outputFd, uint64_t iters) { fprintf(stderr, "Null benchmark doesn't do I/O.\n"); exit(1); } static uint64_t server(int inputFd, int outputFd, uint64_t iters) { fprintf(stderr, "Null benchmark doesn't do I/O.\n"); exit(1); } static uint64_t passByObject(uint64_t iters, bool countObjectSize) { typename ReuseStrategy::ObjectSizeCounter sizeCounter(iters); for (; iters > 0; --iters) { arenaPos = arena; typename TestCase::Request request; typename TestCase::Expectation expected = TestCase::setupRequest(&request); typename TestCase::Response response; TestCase::handleRequest(request, &response); if (!TestCase::checkResponse(response, expected)) { throw std::logic_error("Incorrect response."); } sizeCounter.add((arenaPos - arena) * sizeof(arena[0])); } return sizeCounter.get(); } static uint64_t passByBytes(uint64_t iters) { fprintf(stderr, "Null benchmark doesn't do I/O.\n"); exit(1); } }; struct BenchmarkTypes { typedef void Uncompressed; typedef void Packed; #if HAVE_SNAPPY typedef void SnappyCompressed; #endif // HAVE_SNAPPY typedef ReusableObjects ReusableResources; typedef SingleUseObjects SingleUseResources; template <typename TestCase, typename ReuseStrategy, typename Compression> struct BenchmarkMethods: public null::BenchmarkMethods<TestCase, ReuseStrategy, Compression> {}; }; } // namespace null } // namespace benchmark } // namespace capnp