1d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller/* 2d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * Copyright (C) 2010 The Android Open Source Project 3d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * 4d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * Licensed under the Apache License, Version 2.0 (the "License"); 5d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * you may not use this file except in compliance with the License. 6d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * You may obtain a copy of the License at 7d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * 8d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * http://www.apache.org/licenses/LICENSE-2.0 9d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * 10d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * Unless required by applicable law or agreed to in writing, software 11d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * distributed under the License is distributed on an "AS IS" BASIS, 12d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * See the License for the specific language governing permissions and 14d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * limitations under the License. 15d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * 16d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller */ 17d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 18d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller/* 19b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez * Binder add integers benchmark (Using google-benchmark library) 20d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * 21d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller */ 22d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 23d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <cerrno> 24d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <grp.h> 25d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <iostream> 26f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck#include <iomanip> 27d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <libgen.h> 28d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <time.h> 29d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <unistd.h> 30d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 31d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <sys/syscall.h> 32d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <sys/time.h> 33d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <sys/types.h> 34d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <sys/wait.h> 35d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 36d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <binder/IPCThreadState.h> 37d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <binder/ProcessState.h> 38d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <binder/IServiceManager.h> 39b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 40b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez#include <benchmark/benchmark.h> 41b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 42d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <utils/Log.h> 43d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <testUtil.h> 44d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 45d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerusing namespace android; 46d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerusing namespace std; 47d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 48d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerconst int unbound = -1; // Indicator for a thread not bound to a specific CPU 49d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 50d2447fd2505466a8c30cdca247325f79ba95be34Louis HuemillerString16 serviceName("test.binderAddInts"); 51d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 52d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstruct options { 53d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int serverCPU; 54d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int clientCPU; 55d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller float iterDelay; // End of iteration delay in seconds 56d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller} options = { // Set defaults 57d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller unbound, // Server CPU 58d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller unbound, // Client CPU 59b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 0.0, // End of iteration delay 60d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}; 61d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 62d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerclass AddIntsService : public BBinder 63d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{ 64d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller public: 6511b95b9c3a946089d52f205838c05373c954b16eChih-Hung Hsieh explicit AddIntsService(int cpu = unbound); 66920f089dc6c15a3be3f68ead68ef1d439d5d7c93Bernhard Rosenkränzer virtual ~AddIntsService() {} 67d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 68d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller enum command { 69d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller ADD_INTS = 0x120, 70d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller }; 71d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 72d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller virtual status_t onTransact(uint32_t code, 73d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller const Parcel& data, Parcel* reply, 74d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller uint32_t flags = 0); 75d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 76d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller private: 77d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int cpu_; 78d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}; 79d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 80d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// File scope function prototypes 81f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reckstatic bool server(void); 82187816e5793ad177f6f70fe6270baf1475d74149John Reckstatic void BM_addInts(benchmark::State& state); 83d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic void bindCPU(unsigned int cpu); 84d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic ostream &operator<<(ostream &stream, const String16& str); 85d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic ostream &operator<<(ostream &stream, const cpu_set_t& set); 86d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 87f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reckstatic bool server(void) 88d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{ 89d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int rv; 90d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 91d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // Add the service 92d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller sp<ProcessState> proc(ProcessState::self()); 93d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller sp<IServiceManager> sm = defaultServiceManager(); 94d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if ((rv = sm->addService(serviceName, 95d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller new AddIntsService(options.serverCPU))) != 0) { 96d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cerr << "addService " << serviceName << " failed, rv: " << rv 97d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller << " errno: " << errno << endl; 98f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck return false; 99d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 100d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 101d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // Start threads to handle server work 102d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller proc->startThreadPool(); 103f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck return true; 104d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller} 105d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 106187816e5793ad177f6f70fe6270baf1475d74149John Reckstatic void BM_addInts(benchmark::State& state) 107d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{ 108d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int rv; 109d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller sp<IServiceManager> sm = defaultServiceManager(); 110d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 111d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // If needed bind to client CPU 112d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (options.clientCPU != unbound) { bindCPU(options.clientCPU); } 113d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 114d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // Attach to service 115d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller sp<IBinder> binder; 116f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck for (int i = 0; i < 3; i++) { 117d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller binder = sm->getService(serviceName); 118d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (binder != 0) break; 119d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cout << serviceName << " not published, waiting..." << endl; 120d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller usleep(500000); // 0.5 s 121f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck } 122f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck 123f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck if (binder == 0) { 124f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck cout << serviceName << " failed to publish, aborting" << endl; 125f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck return; 126f9a1c15c7430c009c522a06b93c8530a0611a6ceJohn Reck } 127d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 128b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez unsigned int iter = 0; 129b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez // Perform the IPC operations in the benchmark 130b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez while (state.KeepRunning()) { 131d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller Parcel send, reply; 132d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 133d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // Create parcel to be sent. Will use the iteration cound 134d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // and the iteration count + 3 as the two integer values 135d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // to be sent. 136b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez state.PauseTiming(); 137d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int val1 = iter; 138d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int val2 = iter + 3; 139d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int expected = val1 + val2; // Expect to get the sum back 140d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller send.writeInt32(val1); 141d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller send.writeInt32(val2); 142b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez state.ResumeTiming(); 143d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // Send the parcel, while timing how long it takes for 144d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // the answer to return. 145d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if ((rv = binder->transact(AddIntsService::ADD_INTS, 146d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller send, &reply)) != 0) { 147d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cerr << "binder->transact failed, rv: " << rv 148d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller << " errno: " << errno << endl; 149d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller exit(10); 150d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 151b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 152b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez state.PauseTiming(); 153d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int result = reply.readInt32(); 154d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (result != (int) (iter + iter + 3)) { 155d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cerr << "Unexpected result for iteration " << iter << endl; 156d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cerr << " result: " << result << endl; 157d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cerr << "expected: " << expected << endl; 158d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 159d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 160f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller if (options.iterDelay > 0.0) { testDelaySpin(options.iterDelay); } 161b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez state.ResumeTiming(); 162d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 163d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller} 164187816e5793ad177f6f70fe6270baf1475d74149John ReckBENCHMARK(BM_addInts); 165b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 166d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 167d2447fd2505466a8c30cdca247325f79ba95be34Louis HuemillerAddIntsService::AddIntsService(int cpu): cpu_(cpu) { 168d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (cpu != unbound) { bindCPU(cpu); } 169920f089dc6c15a3be3f68ead68ef1d439d5d7c93Bernhard Rosenkränzer} 170d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 171d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// Server function that handles parcels received from the client 172d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatus_t AddIntsService::onTransact(uint32_t code, const Parcel &data, 1731281503d76c3ce0599dbfba329ba044036b17c16Andreas Gampe Parcel* reply, uint32_t /* flags */) { 174d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int val1, val2; 175d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller status_t rv(0); 176d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int cpu; 177d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 178d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // If server bound to a particular CPU, check that 179d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // were executing on that CPU. 180d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (cpu_ != unbound) { 181e337f25c84b2dfbeca6cb50abe35f6c2956b08c7David 'Digit' Turner cpu = sched_getcpu(); 182d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (cpu != cpu_) { 183d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cerr << "server onTransact on CPU " << cpu << " expected CPU " 184d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller << cpu_ << endl; 185d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller exit(20); 186d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 187d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 188d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 189d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller // Perform the requested operation 190d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller switch (code) { 191d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller case ADD_INTS: 192d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller val1 = data.readInt32(); 193d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller val2 = data.readInt32(); 194d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller reply->writeInt32(val1 + val2); 195d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller break; 196d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 197d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller default: 198d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cerr << "server onTransact unknown code, code: " << code << endl; 199d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller exit(21); 200d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 201d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 202d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller return rv; 203d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller} 204d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 205d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic void bindCPU(unsigned int cpu) 206d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{ 207d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller int rv; 208d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cpu_set_t cpuset; 209d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 210d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller CPU_ZERO(&cpuset); 211d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller CPU_SET(cpu, &cpuset); 212d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller rv = sched_setaffinity(0, sizeof(cpuset), &cpuset); 213d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 214d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (rv != 0) { 215d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller cerr << "bindCPU failed, rv: " << rv << " errno: " << errno << endl; 216d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller perror(NULL); 217d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller exit(30); 218d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 219d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller} 220d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 221d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic ostream &operator<<(ostream &stream, const String16& str) 222d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{ 223d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller for (unsigned int n1 = 0; n1 < str.size(); n1++) { 224d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if ((str[n1] > 0x20) && (str[n1] < 0x80)) { 225d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller stream << (char) str[n1]; 226d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } else { 227d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller stream << '~'; 228d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 229d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 230d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 231d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller return stream; 232d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller} 233d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 234d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic ostream &operator<<(ostream &stream, const cpu_set_t& set) 235d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{ 236d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller for (unsigned int n1 = 0; n1 < CPU_SETSIZE; n1++) { 237d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (CPU_ISSET(n1, &set)) { 238d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller if (n1 != 0) { stream << ' '; } 239d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller stream << n1; 240d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 241d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller } 242d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller 243d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller return stream; 244d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller} 245b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 246b529b0634351d6e175dd011754095b8e567c21cfJulien Desprezint main(int argc, char *argv[]) 247b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez{ 248b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez int rv; 249b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez ::benchmark::Initialize(&argc, argv); 250b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez // Determine CPUs available for use. 251b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez // This testcase limits its self to using CPUs that were 252b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez // available at the start of the benchmark. 253b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cpu_set_t availCPUs; 254b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez if ((rv = sched_getaffinity(0, sizeof(availCPUs), &availCPUs)) != 0) { 255b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << "sched_getaffinity failure, rv: " << rv 256b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez << " errno: " << errno << endl; 257b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez exit(1); 258b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez } 259b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 260b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez // Parse command line arguments 261b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez int opt; 262b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez while ((opt = getopt(argc, argv, "s:c:d:?")) != -1) { 263b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez char *chptr; // character pointer for command-line parsing 264b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 265b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez switch (opt) { 266b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez case 'c': // client CPU 267b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez case 's': { // server CPU 268b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez // Parse the CPU number 269b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez int cpu = strtoul(optarg, &chptr, 10); 270b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez if (*chptr != '\0') { 271b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << "Invalid cpu specified for -" << (char) opt 272b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez << " option of: " << optarg << endl; 273b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez exit(2); 274b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez } 275b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 276b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez // Is the CPU available? 277b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez if (!CPU_ISSET(cpu, &availCPUs)) { 278b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << "CPU " << optarg << " not currently available" << endl; 279b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << " Available CPUs: " << availCPUs << endl; 280b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez exit(3); 281b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez } 282b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 283b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez // Record the choice 284b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez *((opt == 'c') ? &options.clientCPU : &options.serverCPU) = cpu; 285b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez break; 286b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez } 287b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 288b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez case 'd': // delay between each iteration 289b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez options.iterDelay = strtod(optarg, &chptr); 290b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez if ((*chptr != '\0') || (options.iterDelay < 0.0)) { 291b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << "Invalid delay specified of: " << optarg << endl; 292b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez exit(6); 293b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez } 294b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez break; 295b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 296b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez case '?': 297b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez default: 298b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << basename(argv[0]) << " [options]" << endl; 299b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << " options:" << endl; 300b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << " -s cpu - server CPU number" << endl; 301b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << " -c cpu - client CPU number" << endl; 302b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez cerr << " -d time - delay after operation in seconds" << endl; 303b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez exit(((optopt == 0) || (optopt == '?')) ? 0 : 7); 304b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez } 305b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez } 306b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 307187816e5793ad177f6f70fe6270baf1475d74149John Reck fflush(stdout); 308187816e5793ad177f6f70fe6270baf1475d74149John Reck switch (pid_t pid = fork()) { 309187816e5793ad177f6f70fe6270baf1475d74149John Reck case 0: // Child 310187816e5793ad177f6f70fe6270baf1475d74149John Reck ::benchmark::RunSpecifiedBenchmarks(); 311187816e5793ad177f6f70fe6270baf1475d74149John Reck return 0; 312187816e5793ad177f6f70fe6270baf1475d74149John Reck 313187816e5793ad177f6f70fe6270baf1475d74149John Reck default: // Parent 314187816e5793ad177f6f70fe6270baf1475d74149John Reck if (!server()) { break; } 315187816e5793ad177f6f70fe6270baf1475d74149John Reck 316187816e5793ad177f6f70fe6270baf1475d74149John Reck // Wait for all children to end 317187816e5793ad177f6f70fe6270baf1475d74149John Reck do { 318187816e5793ad177f6f70fe6270baf1475d74149John Reck int stat; 319187816e5793ad177f6f70fe6270baf1475d74149John Reck rv = wait(&stat); 320187816e5793ad177f6f70fe6270baf1475d74149John Reck if ((rv == -1) && (errno == ECHILD)) { break; } 321187816e5793ad177f6f70fe6270baf1475d74149John Reck if (rv == -1) { 322187816e5793ad177f6f70fe6270baf1475d74149John Reck cerr << "wait failed, rv: " << rv << " errno: " 323187816e5793ad177f6f70fe6270baf1475d74149John Reck << errno << endl; 324187816e5793ad177f6f70fe6270baf1475d74149John Reck perror(NULL); 325187816e5793ad177f6f70fe6270baf1475d74149John Reck exit(8); 326187816e5793ad177f6f70fe6270baf1475d74149John Reck } 327187816e5793ad177f6f70fe6270baf1475d74149John Reck } while (1); 328187816e5793ad177f6f70fe6270baf1475d74149John Reck return 0; 329b529b0634351d6e175dd011754095b8e567c21cfJulien Desprez 330187816e5793ad177f6f70fe6270baf1475d74149John Reck case -1: // Error 331187816e5793ad177f6f70fe6270baf1475d74149John Reck exit(9); 332187816e5793ad177f6f70fe6270baf1475d74149John Reck } 333187816e5793ad177f6f70fe6270baf1475d74149John Reck} 334