blob: 889b97c4716cd74c86a12c8fdc980ce2cf81edba [file] [log] [blame]
Will Drewryb5518472009-12-10 12:31:47 -08001// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// Microbenchmark of basic read/write throughput
6#include "microbenchmark/microbenchmark.h"
7
8#include <fcntl.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <sys/stat.h>
12#include <sys/types.h>
13#include <sys/unistd.h>
14#include <syscall.h>
15#include <time.h>
16
17namespace chromeos {
18namespace benchmarks {
19
20#define IO_SIZE 4096
21#define CALL_SYSCALL(_SCAF, syscallargs...) \
22 (_SCAF ? IO_SIZE : syscall(syscallargs))
23static long kDefaultAmount = 0x4000;
24static const char *kDevUrandom = "/dev/urandom";
25static const char *kDevNull = "/dev/null";
26
27// Lovely globals used from Setup->Test.
28static int rfd = -1;
29static int wfd = -1;
30static long amount = kDefaultAmount;
31
32static void ReadWriteSetup(uint64 runs) {
33 CommandLine *cl = CommandLine::ForCurrentProcess();
34 std::string amount_str = cl->GetSwitchValueASCII("readwrite-amount");
35 std::string source = cl->GetSwitchValueASCII("readwrite-source");
36 std::string destination = cl->GetSwitchValueASCII("readwrite-destination");
37
38 if (amount_str.empty()) {
39 LOG(INFO) << "--readwrite-amount is missing.";
40 LOG(INFO) << "Defaulting to " << amount << " bytes";
41 } else {
42 amount = strtol(amount_str.c_str(), NULL, 0);
43 if (amount < 0 || amount > 0xffffff) {
44 LOG(ERROR) << "Amount specified was too large: " << amount;
45 LOG(INFO) << "Using default amount of " << kDefaultAmount;
46 }
47 amount = kDefaultAmount;
48 }
49 if (source.empty()) {
50 LOG(INFO) << "--readwrite-source missing.";
51 LOG(INFO) << "Defaulting to /dev/urandom as a source";
52 source = kDevUrandom;
53 }
54 if (destination.empty()) {
55 LOG(INFO) << "--readwrite-destination missing.";
56 LOG(INFO) << "Defaulting to /dev/null as a destination";
57 destination = kDevNull;
58 }
59 wfd = open("/dev/null", O_WRONLY);
60 rfd = open("/dev/zero", O_RDONLY);
61 LOG_IF(FATAL, wfd < 0 || rfd < 0) << "Failed to open /dev/null or /dev/zero";
62}
63
64static void ReadWrite(bool scaffold_only) {
65 ssize_t so_far = 0;
66 ssize_t bytes = 0;
67 char buf[IO_SIZE];
68 while (so_far < amount) {
69 bytes = CALL_SYSCALL(scaffold_only, __NR_read, rfd, buf, sizeof(buf));
70 PLOG_IF(FATAL, bytes < 0) << "An unexpected error occurred during read.";
71 so_far += bytes;
72 PLOG_IF(FATAL,
73 CALL_SYSCALL(scaffold_only, __NR_write, wfd, buf, bytes) != bytes)
74 << "An unexpected error occurred during write.";
75 }
76}
77CHROMEOS_MICROBENCHMARK_WITH_SETUP(ReadWriteSetup, ReadWrite, 1000);
78#undef IO_SIZE
79#undef CALL_SYSCALL
80
81} // namespace benchmarks
82} // namespace chromeos