blob: 3c26919a04e83317197c990df268f769493f4559 [file] [log] [blame]
// 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