micro_bench.cpp revision 25ada90c4b99bd5471e3677542b62cef8d439399
182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris/*
282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** Copyright 2010 The Android Open Source Project
382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris**
482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** Licensed under the Apache License, Version 2.0 (the "License");
582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** you may not use this file except in compliance with the License.
682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** You may obtain a copy of the License at
782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris**
882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris**     http://www.apache.org/licenses/LICENSE-2.0
982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris**
1082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** Unless required by applicable law or agreed to in writing, software
1182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** distributed under the License is distributed on an "AS IS" BASIS,
1282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** See the License for the specific language governing permissions and
1482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris** limitations under the License.
1582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris*/
1682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
1782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris/*
1825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris * Micro-benchmarking of sleep/cpu speed/memcpy/memset/memory reads/strcmp.
1982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris */
2082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
2182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#include <stdio.h>
2282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#include <stdlib.h>
2382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#include <ctype.h>
2482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#include <math.h>
2582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#include <sched.h>
2682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#include <sys/resource.h>
2782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#include <time.h>
2882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#include <unistd.h>
2982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
3082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// The default size of data that will be manipulated in each iteration of
3182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// a memory benchmark. Can be modified with the --data_size option.
3282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#define DEFAULT_DATA_SIZE       1000000000
3382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
3482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// Number of nanoseconds in a second.
3582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#define NS_PER_SEC              1000000000
3682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
3782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// The maximum number of arguments that a benchmark will accept.
3882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#define MAX_ARGS    2
3982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
4082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// Use macros to compute values to try and avoid disturbing memory as much
4182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// as possible after each iteration.
4282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#define COMPUTE_AVERAGE_KB(avg_kb, bytes, time_ns) \
4382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        avg_kb = ((bytes) / 1024.0) / ((double)(time_ns) / NS_PER_SEC);
4482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
4582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#define COMPUTE_RUNNING(avg, running_avg, square_avg, cur_idx) \
4682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    running_avg = ((running_avg) / ((cur_idx) + 1)) * (cur_idx) + (avg) / ((cur_idx) + 1); \
4782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    square_avg = ((square_avg) / ((cur_idx) + 1)) * (cur_idx) + ((avg) / ((cur_idx) + 1)) * (avg);
4825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris#define COMPUTE_MIN_MAX(avg, min, max) \
4925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    if (avg < min || min == 0.0) { \
5025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        min = avg; \
5125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    } \
5225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    if (avg > max) { \
5325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        max = avg; \
5425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    }
5582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
5682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris#define GET_STD_DEV(running_avg, square_avg) \
5782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    sqrt((square_avg) - (running_avg) * (running_avg))
5882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
5982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// Contains information about benchmark options.
6082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferristypedef struct {
6182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_average;
6282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_each_iter;
6382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
6482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int dst_align;
6525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    int dst_or_mask;
6682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int src_align;
6725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    int src_or_mask;
6882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
6982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int cpu_to_lock;
7082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
7182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int data_size;
7282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
7382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int args[MAX_ARGS];
7482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int num_args;
7582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris} command_data_t;
7682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
7782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// Struct that contains a mapping of benchmark name to benchmark function.
7882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferristypedef struct {
7982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    const char *name;
8082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int (*ptr)(const command_data_t &cmd_data);
8182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris} function_t;
8282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
8382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// Get the current time in nanoseconds.
8482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisuint64_t nanoTime() {
8582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris  struct timespec t;
8682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
8782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris  t.tv_sec = t.tv_nsec = 0;
8882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris  clock_gettime(CLOCK_MONOTONIC, &t);
8982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris  return static_cast<uint64_t>(t.tv_sec) * NS_PER_SEC + t.tv_nsec;
9082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
9182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
9282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// Allocate memory with a specific alignment and return that pointer.
9382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// This function assumes an alignment value that is a power of 2.
9482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// If the alignment is 0, then use the pointer returned by malloc.
9525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferrisuint8_t *getAlignedMemory(uint8_t *orig_ptr, int alignment, int or_mask) {
9625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris  uint64_t ptr = reinterpret_cast<uint64_t>(orig_ptr);
9782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris  if (alignment > 0) {
9882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris      // When setting the alignment, set it to exactly the alignment chosen.
9982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris      // The pointer returned will be guaranteed not to be aligned to anything
10082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris      // more than that.
10182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris      ptr += alignment - (ptr & (alignment - 1));
10225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris      ptr |= alignment | or_mask;
10382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris  }
10482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
10582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris  return reinterpret_cast<uint8_t*>(ptr);
10682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
10782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
10825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris// Allocate memory with a specific alignment and return that pointer.
10925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris// This function assumes an alignment value that is a power of 2.
11025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris// If the alignment is 0, then use the pointer returned by malloc.
11125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferrisuint8_t *allocateAlignedMemory(size_t size, int alignment, int or_mask) {
11225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris  uint64_t ptr = reinterpret_cast<uint64_t>(malloc(size + 3 * alignment));
11325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris  if (!ptr)
11425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris      return NULL;
11525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris  return getAlignedMemory((uint8_t*)ptr, alignment, or_mask);
11625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris}
11725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
11882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisint benchmarkSleep(const command_data_t &cmd_data) {
11982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    uint64_t time_ns;
12082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
12182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int delay = cmd_data.args[0];
12282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int iters = cmd_data.args[1];
12382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_each_iter = cmd_data.print_each_iter;
12482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_average = cmd_data.print_average;
12582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    double avg, running_avg = 0.0, square_avg = 0.0;
12625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    double max = 0.0, min = 0.0;
12782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    for (int i = 0; iters == -1 || i < iters; i++) {
12882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime();
12982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        sleep(delay);
13082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime() - time_ns;
13182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
13282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        avg = (double)time_ns / NS_PER_SEC;
13382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
13482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_average) {
13582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            COMPUTE_RUNNING(avg, running_avg, square_avg, i);
13625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            COMPUTE_MIN_MAX(avg, min, max);
13782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
13882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
13982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_each_iter) {
14082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            printf("sleep(%d) took %.06f seconds\n", delay, avg);
14182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
14282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
14382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
14482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (print_average) {
14525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("  sleep(%d) average %.06f seconds std dev %f min %.06f seconds max %0.6f seconds\n", delay,
14625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               running_avg, GET_STD_DEV(running_avg, square_avg),
14725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               min, max);
14882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
14982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
15082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    return 0;
15182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
15282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
15382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisint benchmarkCpu(const command_data_t &cmd_data) {
15482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    // Use volatile so that the loop is not optimized away by the compiler.
15582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    volatile int cpu_foo;
15682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
15782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    uint64_t time_ns;
15882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int iters = cmd_data.args[1];
15982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_each_iter = cmd_data.print_each_iter;
16082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_average = cmd_data.print_average;
16182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    double avg, running_avg = 0.0, square_avg = 0.0;
16225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    double max = 0.0, min = 0.0;
16382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    for (int i = 0; iters == -1 || i < iters; i++) {
16482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime();
16582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        for (cpu_foo = 0; cpu_foo < 100000000; cpu_foo++);
16682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime() - time_ns;
16782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
16882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        avg = (double)time_ns / NS_PER_SEC;
16982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
17082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_average) {
17182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            COMPUTE_RUNNING(avg, running_avg, square_avg, i);
17225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            COMPUTE_MIN_MAX(avg, min, max);
17382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
17482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
17582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_each_iter) {
17682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            printf("cpu took %.06f seconds\n", avg);
17782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
17882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
17982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
18082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (print_average) {
18125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("  cpu average %.06f seconds std dev %f min %0.6f seconds max %0.6f seconds\n",
18225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               running_avg, GET_STD_DEV(running_avg, square_avg),
18325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               min, max);
18482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
18582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
18682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    return 0;
18782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
18882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
18982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisint benchmarkMemset(const command_data_t &cmd_data) {
19082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int size = cmd_data.args[0];
19182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int iters = cmd_data.args[1];
19282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
19325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    uint8_t *dst = allocateAlignedMemory(size, cmd_data.dst_align, cmd_data.dst_or_mask);
19482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (!dst)
19582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return -1;
19682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
19782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    double avg_kb, running_avg_kb = 0.0, square_avg_kb = 0.0;
19825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    double max_kb = 0.0, min_kb = 0.0;
19982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    uint64_t time_ns;
20082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int j;
20182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_average = cmd_data.print_average;
20282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_each_iter = cmd_data.print_each_iter;
20382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int copies = cmd_data.data_size/size;
20482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    for (int i = 0; iters == -1 || i < iters; i++) {
20582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime();
20682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        for (j = 0; j < copies; j++)
20782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            memset(dst, 0, size);
20882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime() - time_ns;
20982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
21082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        // Compute in kb to avoid any overflows.
21182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        COMPUTE_AVERAGE_KB(avg_kb, copies * size, time_ns);
21282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
21382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_average) {
21482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            COMPUTE_RUNNING(avg_kb, running_avg_kb, square_avg_kb, i);
21525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            COMPUTE_MIN_MAX(avg_kb, min_kb, max_kb);
21682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
21782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
21882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_each_iter) {
21982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            printf("memset %dx%d bytes took %.06f seconds (%f MB/s)\n",
22082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                   copies, size, (double)time_ns / NS_PER_SEC, avg_kb / 1024.0);
22182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
22282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
22382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
22482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (print_average) {
22525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("  memset %dx%d bytes average %.2f MB/s std dev %.4f min %.2f MB/s max %.2f MB/s\n",
22682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris               copies, size, running_avg_kb / 1024.0,
22725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               GET_STD_DEV(running_avg_kb, square_avg_kb) / 1024.0,
22825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               min_kb / 1024.0, max_kb / 1024.0);
22982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
23082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    return 0;
23182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
23282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
23382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisint benchmarkMemcpy(const command_data_t &cmd_data) {
23482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int size = cmd_data.args[0];
23582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int iters = cmd_data.args[1];
23682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
23725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    uint8_t *src = allocateAlignedMemory(size, cmd_data.src_align, cmd_data.src_or_mask);
23882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (!src)
23982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return -1;
24025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    uint8_t *dst = allocateAlignedMemory(size, cmd_data.dst_align, cmd_data.dst_or_mask);
24182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (!dst)
24282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return -1;
24382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
24425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    // Initialize the source and destination to known values.
24525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    // If not initialized, the benchmark results are skewed.
24625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    memset(src, 0xffff, size);
24725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    memset(dst, 0, size);
24825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
24982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    uint64_t time_ns;
25082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    double avg_kb, running_avg_kb = 0.0, square_avg_kb = 0.0;
25125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    double max_kb = 0.0, min_kb = 0.0;
25282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int j;
25382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_average = cmd_data.print_average;
25482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_each_iter = cmd_data.print_each_iter;
25582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int copies = cmd_data.data_size / size;
25682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    for (int i = 0; iters == -1 || i < iters; i++) {
25782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime();
25882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        for (j = 0; j < copies; j++)
25982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            memcpy(dst, src, size);
26082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime() - time_ns;
26182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
26282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        // Compute in kb to avoid any overflows.
26382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        COMPUTE_AVERAGE_KB(avg_kb, copies * size, time_ns);
26482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
26582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_average) {
26682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            COMPUTE_RUNNING(avg_kb, running_avg_kb, square_avg_kb, i);
26725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            COMPUTE_MIN_MAX(avg_kb, min_kb, max_kb);
26882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
26982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
27082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_each_iter) {
27182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            printf("memcpy %dx%d bytes took %.06f seconds (%f MB/s)\n",
27282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                   copies, size, (double)time_ns / NS_PER_SEC, avg_kb / 1024.0);
27382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
27482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
27582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (print_average) {
27625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("  memcpy %dx%d bytes average %.2f MB/s std dev %.4f min %.2f MB/s max %.2f MB/s\n",
27782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris               copies, size, running_avg_kb/1024.0,
27825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               GET_STD_DEV(running_avg_kb, square_avg_kb) / 1024.0,
27925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               min_kb / 1024.0, max_kb / 1024.0);
28025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    }
28125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    return 0;
28225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris}
28325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
28425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferrisint benchmarkStrcmp(const command_data_t &cmd_data) {
28525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    int size = cmd_data.args[0];
28625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    int iters = cmd_data.args[1];
28725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
28825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    // Allocate a large chunk of memory to hold both strings.
28925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    uint8_t *memory = (uint8_t*)malloc(2*size + 2048);
29025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    if (!memory)
29125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        return -1;
29225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
29325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    char *string1 = reinterpret_cast<char*>(getAlignedMemory(memory, cmd_data.src_align, cmd_data.src_or_mask));
29425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    char *string2 = reinterpret_cast<char*>(getAlignedMemory((uint8_t*)string1+size, cmd_data.dst_align, cmd_data.dst_or_mask));
29525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
29625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    for (int i = 0; i < size - 1; i++) {
29725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        string1[i] = (char)(32 + (i % 96));
29825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        string2[i] = string1[i];
29925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    }
30025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    string1[size-1] = '\0';
30125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    string2[size-1] = '\0';
30225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
30325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    uint64_t time_ns;
30425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    double avg_kb, running_avg_kb = 0.0, square_avg_kb = 0.0;
30525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    double max_kb = 0.0, min_kb = 0.0;
30625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    int j;
30725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    bool print_average = cmd_data.print_average;
30825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    bool print_each_iter = cmd_data.print_each_iter;
30925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    int copies = cmd_data.data_size / size;
31025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
31125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    int retval = 0;
31225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    for (int i = 0; iters == -1 || i < iters; i++) {
31325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        time_ns = nanoTime();
31425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        for (j = 0; j < copies; j++) {
31525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            retval = strcmp(string1, string2);
31625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            if (retval != 0) {
31725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris                printf("strcmp failed, return value %d\n", retval);
31825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            }
31925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        }
32025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        time_ns = nanoTime() - time_ns;
32125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
32225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        // Compute in kb to avoid any overflows.
32325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        COMPUTE_AVERAGE_KB(avg_kb, copies * size, time_ns);
32425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
32525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        if (print_average) {
32625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            COMPUTE_RUNNING(avg_kb, running_avg_kb, square_avg_kb, i);
32725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            COMPUTE_MIN_MAX(avg_kb, min_kb, max_kb);
32825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        }
32925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris
33025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        if (print_each_iter) {
33125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            printf("strcmp %dx%d bytes took %.06f seconds (%f MB/s)\n",
33225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris                   copies, size, (double)time_ns / NS_PER_SEC, avg_kb / 1024.0);
33325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        }
33425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    }
33525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    if (print_average) {
33625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("  strcmp %dx%d bytes average %.2f MB/s std dev %.4f min %.2f MB/s max %.2f MB/s\n",
33725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               copies, size, running_avg_kb/1024.0,
33825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               GET_STD_DEV(running_avg_kb, square_avg_kb) / 1024.0,
33925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               min_kb / 1024.0, max_kb / 1024.0);
34082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
34182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    return 0;
34282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
34382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
34482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisint benchmarkMemread(const command_data_t &cmd_data) {
34582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int size = cmd_data.args[0];
34682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int iters = cmd_data.args[1];
34782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
34882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int *src = reinterpret_cast<int*>(malloc(size));
34982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (!src)
35082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return -1;
35182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
35282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    // Use volatile so the compiler does not optimize away the reads.
35382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    volatile int foo;
35482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    uint64_t time_ns;
35582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int j, k;
35682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    double avg_kb, running_avg_kb = 0.0, square_avg_kb = 0.0;
35725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    double max_kb = 0.0, min_kb = 0.0;
35882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_average = cmd_data.print_average;
35982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    bool print_each_iter = cmd_data.print_each_iter;
36082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    int c = cmd_data.data_size / size;
36182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    for (int i = 0; iters == -1 || i < iters; i++) {
36282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime();
36382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        for (j = 0; j < c; j++)
36482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            for (k = 0; k < size/4; k++)
36582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                foo = src[k];
36682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        time_ns = nanoTime() - time_ns;
36782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
36882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        // Compute in kb to avoid any overflows.
36982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        COMPUTE_AVERAGE_KB(avg_kb, c * size, time_ns);
37082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
37182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_average) {
37282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            COMPUTE_RUNNING(avg_kb, running_avg_kb, square_avg_kb, i);
37325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            COMPUTE_MIN_MAX(avg_kb, min_kb, max_kb);
37482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
37582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
37682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (print_each_iter) {
37782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            printf("read %dx%d bytes took %.06f seconds (%f MB/s)\n",
37882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                   c, size, (double)time_ns / NS_PER_SEC, avg_kb / 1024.0);
37982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
38082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
38182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
38282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (print_average) {
38325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("  read %dx%d bytes average %.2f MB/s std dev %.4f min %.2f MB/s max %.2f MB/s\n",
38482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris               c, size, running_avg_kb/1024.0,
38525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               GET_STD_DEV(running_avg_kb, square_avg_kb) / 1024.0,
38625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris               min_kb / 1024.0, max_kb / 1024.0);
38782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
38882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
38982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    return 0;
39082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
39182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
39282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris// Create the mapping structure.
39382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisfunction_t function_table[] = {
39482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    { "sleep", benchmarkSleep },
39582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    { "cpu", benchmarkCpu },
39682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    { "memset", benchmarkMemset },
39782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    { "memcpy", benchmarkMemcpy },
39882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    { "memread", benchmarkMemread },
39925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    { "strcmp", benchmarkStrcmp },
40082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    { NULL, NULL }
40182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris};
40282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
40382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisvoid usage() {
40482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("Usage:\n");
40582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("  micro_bench [--data_size DATA_BYTES] [--print_average]\n");
40682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("              [--no_print_each_iter] [--lock_to_cpu CORE]\n");
40782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    --data_size DATA_BYTES\n");
40882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      For the data benchmarks (memcpy/memset/memread) the approximate\n");
40982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      size of data, in bytes, that will be manipulated in each iteration.\n");
41082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    --print_average\n");
41182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      Print the average and standard deviation of all iterations.\n");
41282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    --no_print_each_iter\n");
41382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      Do not print any values in each iteration.\n");
41482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    --lock_to_cpu CORE\n");
41582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      Lock to the specified CORE. The default is to use the last core found.\n");
41682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    ITERS\n");
41782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      The number of iterations to execute each benchmark. If not\n");
41882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      passed in then run forever.\n");
41982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("  micro_bench sleep TIME_TO_SLEEP [ITERS]\n");
42082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    TIME_TO_SLEEP\n");
42182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      The time in seconds to sleep.\n");
42282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("  micro_bench cpu UNUSED [ITERS]\n");
42382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("  micro_bench [--dst_align ALIGN] memset NUM_BYTES [ITERS]\n");
42482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    --dst_align ALIGN\n");
42582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      Align the memset destination pointer to ALIGN. The default is to use the\n");
42682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      value returned by malloc.\n");
42782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("  micro_bench [--src_align ALIGN] [--dst_align ALIGN] memcpy NUM_BYTES [ITERS]\n");
42882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    --src_align ALIGN\n");
42982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      Align the memcpy source pointer to ALIGN. The default is to use the\n");
43082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      value returned by malloc.\n");
43182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("    --dst_align ALIGN\n");
43282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      Align the memcpy destination pointer to ALIGN. The default is to use the\n");
43382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("      value returned by malloc.\n");
43482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("  micro_bench memread NUM_BYTES [ITERS]\n");
43582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
43682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
43782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisfunction_t *processOptions(int argc, char **argv, command_data_t *cmd_data) {
43882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    function_t *command = NULL;
43982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
44082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    // Initialize the command_flags.
44182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    cmd_data->print_average = false;
44282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    cmd_data->print_each_iter = true;
44382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    cmd_data->dst_align = 0;
44482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    cmd_data->src_align = 0;
44525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    cmd_data->src_or_mask = 0;
44625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    cmd_data->dst_or_mask = 0;
44782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    cmd_data->num_args = 0;
44882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    cmd_data->cpu_to_lock = -1;
44982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    cmd_data->data_size = DEFAULT_DATA_SIZE;
45082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    for (int i = 0; i < MAX_ARGS; i++) {
45182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        cmd_data->args[i] = -1;
45282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
45382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
45482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    for (int i = 1; i < argc; i++) {
45582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        if (argv[i][0] == '-') {
45682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            int *save_value = NULL;
45782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            if (strcmp(argv[i], "--print_average") == 0) {
45882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris              cmd_data->print_average = true;
45982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            } else if (strcmp(argv[i], "--no_print_each_iter") == 0) {
46082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris              cmd_data->print_each_iter = false;
46182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            } else if (strcmp(argv[i], "--dst_align") == 0) {
46282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris              save_value = &cmd_data->dst_align;
46382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            } else if (strcmp(argv[i], "--src_align") == 0) {
46482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris              save_value = &cmd_data->src_align;
46525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            } else if (strcmp(argv[i], "--dst_or_mask") == 0) {
46625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris              save_value = &cmd_data->dst_or_mask;
46725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris            } else if (strcmp(argv[i], "--src_or_mask") == 0) {
46825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris              save_value = &cmd_data->src_or_mask;
46982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            } else if (strcmp(argv[i], "--lock_to_cpu") == 0) {
47082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris              save_value = &cmd_data->cpu_to_lock;
47182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            } else if (strcmp(argv[i], "--data_size") == 0) {
47282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris              save_value = &cmd_data->data_size;
47382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            } else {
47482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                printf("Unknown option %s\n", argv[i]);
47582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                return NULL;
47682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            }
47782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            if (save_value) {
47882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                // Checking both characters without a strlen() call should be
47982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                // safe since as long as the argument exists, one character will
48082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                // be present (\0). And if the first character is '-', then
48182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                // there will always be a second character (\0 again).
48282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                if (i == argc - 1 || (argv[i + 1][0] == '-' && !isdigit(argv[i + 1][1]))) {
48382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                    printf("The option %s requires one argument.\n",
48482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                           argv[i]);
48582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                    return NULL;
48682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                }
48725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris                *save_value = (int)strtol(argv[++i], NULL, 0);
48882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            }
48982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        } else if (!command) {
49082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            for (function_t *function = function_table; function->name != NULL; function++) {
49182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                if (strcmp(argv[i], function->name) == 0) {
49282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                    command = function;
49382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                    break;
49482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                }
49582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            }
49682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            if (!command) {
49782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                printf("Uknown command %s\n", argv[i]);
49882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                return NULL;
49982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            }
50082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        } else if (cmd_data->num_args > MAX_ARGS) {
50182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            printf("More than %d number arguments passed in.\n", MAX_ARGS);
50282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            return NULL;
50382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        } else {
50482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            cmd_data->args[cmd_data->num_args++] = atoi(argv[i]);
50582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
50682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
50782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
50882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    // Check the arguments passed in make sense.
50982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (cmd_data->num_args != 1 && cmd_data->num_args != 2) {
51082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        printf("Not enough arguments passed in.\n");
51182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return NULL;
51282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    } else if (cmd_data->dst_align < 0) {
51382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        printf("The --dst_align option must be greater than or equal to 0.\n");
51482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return NULL;
51582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    } else if (cmd_data->src_align < 0) {
51682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        printf("The --src_align option must be greater than or equal to 0.\n");
51782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return NULL;
51882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    } else if (cmd_data->data_size <= 0) {
51982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        printf("The --data_size option must be a positive number.\n");
52082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return NULL;
52182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    } else if ((cmd_data->dst_align & (cmd_data->dst_align - 1))) {
52282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        printf("The --dst_align option must be a power of 2.\n");
52382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return NULL;
52482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    } else if ((cmd_data->src_align & (cmd_data->src_align - 1))) {
52582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        printf("The --src_align option must be a power of 2.\n");
52682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return NULL;
52725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    } else if (!cmd_data->src_align && cmd_data->src_or_mask) {
52825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("The --src_or_mask option requires that --src_align be set.\n");
52925ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        return NULL;
53025ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    } else if (!cmd_data->dst_align && cmd_data->dst_or_mask) {
53125ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("The --dst_or_mask option requires that --dst_align be set.\n");
53225ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        return NULL;
53325ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    } else if (cmd_data->src_or_mask > cmd_data->src_align) {
53425ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("The value of --src_or_mask cannot be larger that --src_align.\n");
53525ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        return NULL;
53625ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris    } else if (cmd_data->dst_or_mask > cmd_data->dst_align) {
53725ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        printf("The value of --src_or_mask cannot be larger that --src_align.\n");
53825ada90c4b99bd5471e3677542b62cef8d439399Christopher Ferris        return NULL;
53982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
54082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
54182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    return command;
54282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
54382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
54482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisbool raisePriorityAndLock(int cpu_to_lock) {
54582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    cpu_set_t cpuset;
54682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
54782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (setpriority(PRIO_PROCESS, 0, -20)) {
54882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        perror("Unable to raise priority of process.\n");
54982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return false;
55082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
55182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
55282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    CPU_ZERO(&cpuset);
55382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (sched_getaffinity(0, sizeof(cpuset), &cpuset) != 0) {
55482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        perror("sched_getaffinity failed");
55582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return false;
55682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
55782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
55882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (cpu_to_lock < 0) {
55982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        // Lock to the last active core we find.
56082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        for (int i = 0; i < CPU_SETSIZE; i++) {
56182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            if (CPU_ISSET(i, &cpuset)) {
56282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris                cpu_to_lock = i;
56382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris            }
56482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        }
56582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    } else if (!CPU_ISSET(cpu_to_lock, &cpuset)) {
56682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        printf("Cpu %d does not exist.\n", cpu_to_lock);
56782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return false;
56882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
56982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
57082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (cpu_to_lock < 0) {
57182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        printf("Cannot find any valid cpu to lock.\n");
57282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return false;
57382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
57482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
57582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    CPU_ZERO(&cpuset);
57682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    CPU_SET(cpu_to_lock, &cpuset);
57782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
57882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        perror("sched_setaffinity failed");
57982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris        return false;
58082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
58182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
58282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    return true;
58382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
58482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
58582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferrisint main(int argc, char **argv) {
58682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    command_data_t cmd_data;
58782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
58882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    function_t *command = processOptions(argc, argv, &cmd_data);
58982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (!command) {
59082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris      usage();
59182ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris      return -1;
59282ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
59382ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
59482ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    if (!raisePriorityAndLock(cmd_data.cpu_to_lock)) {
59582ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris      return -1;
59682ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    }
59782ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris
59882ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    printf("%s\n", command->name);
59982ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris    return (*command->ptr)(cmd_data);
60082ac1af86d8ca3b7a42af9ca02e4d0b556681bc8Christopher Ferris}
601