binderAddInts.cpp revision 11b95b9c3a946089d52f205838c05373c954b16e
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/*
19d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * Binder add integers benchmark
20d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller *
21d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * Measures the rate at which a short binder IPC operation can be
22d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * performed.  The operation consists of the client sending a parcel
23d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * that contains two integers.  For each parcel that the server
24d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * receives, it adds the two integers and sends the sum back to
25d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * the client.
26d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller *
27d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller * This benchmark supports the following command-line options:
28d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller *
29d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller *   -c cpu - bind client to specified cpu (default: unbound)
30d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller *   -s cpu - bind server to specified cpu (default: unbound)
31d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller *   -n num - perform IPC operation num times (default: 1000)
32d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller *   -d time - delay specified amount of seconds after each
33d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller *             IPC operation. (default 1e-3)
34d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller */
35d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
36d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <cerrno>
37d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <grp.h>
38d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <iostream>
39d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <libgen.h>
40d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <time.h>
41d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <unistd.h>
42d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
43d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <sys/syscall.h>
44d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <sys/time.h>
45d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <sys/types.h>
46d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <sys/wait.h>
47d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
48d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <binder/IPCThreadState.h>
49d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <binder/ProcessState.h>
50d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <binder/IServiceManager.h>
51d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <utils/Log.h>
52d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller#include <testUtil.h>
53d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
54d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerusing namespace android;
55d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerusing namespace std;
56d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
57d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerconst int unbound = -1; // Indicator for a thread not bound to a specific CPU
58d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
59d2447fd2505466a8c30cdca247325f79ba95be34Louis HuemillerString16 serviceName("test.binderAddInts");
60d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
61d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstruct options {
62d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int serverCPU;
63d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int clientCPU;
64d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    unsigned int iterations;
65d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    float        iterDelay; // End of iteration delay in seconds
66d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller} options = { // Set defaults
67d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    unbound, // Server CPU
68d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    unbound, // Client CPU
69d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    1000,    // Iterations
70d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    1e-3,    // End of iteration delay
71d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller};
72d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
73d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerclass AddIntsService : public BBinder
74d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
75d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller  public:
7611b95b9c3a946089d52f205838c05373c954b16eChih-Hung Hsieh    explicit AddIntsService(int cpu = unbound);
77920f089dc6c15a3be3f68ead68ef1d439d5d7c93Bernhard Rosenkränzer    virtual ~AddIntsService() {}
78d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
79d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    enum command {
80d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        ADD_INTS = 0x120,
81d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    };
82d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
83d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    virtual status_t onTransact(uint32_t code,
84d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                                const Parcel& data, Parcel* reply,
85d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                                uint32_t flags = 0);
86d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
87d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller  private:
88d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int cpu_;
89d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller};
90d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
91d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// File scope function prototypes
92d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic void server(void);
93d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic void client(void);
94d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic void bindCPU(unsigned int cpu);
95d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic ostream &operator<<(ostream &stream, const String16& str);
96d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic ostream &operator<<(ostream &stream, const cpu_set_t& set);
97d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
98d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerint main(int argc, char *argv[])
99d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
100d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int rv;
101d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
102d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Determine CPUs available for use.
103d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // This testcase limits its self to using CPUs that were
104d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // available at the start of the benchmark.
105d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cpu_set_t availCPUs;
106d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if ((rv = sched_getaffinity(0, sizeof(availCPUs), &availCPUs)) != 0) {
107d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        cerr << "sched_getaffinity failure, rv: " << rv
108d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            << " errno: " << errno << endl;
109d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        exit(1);
110d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
111d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
112d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Parse command line arguments
113d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int opt;
114d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    while ((opt = getopt(argc, argv, "s:c:n:d:?")) != -1) {
115d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        char *chptr; // character pointer for command-line parsing
116d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
117d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        switch (opt) {
118d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        case 'c': // client CPU
119d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        case 's': { // server CPU
120d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            // Parse the CPU number
121d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            int cpu = strtoul(optarg, &chptr, 10);
122d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            if (*chptr != '\0') {
123d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                cerr << "Invalid cpu specified for -" << (char) opt
124d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                    << " option of: " << optarg << endl;
125d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                exit(2);
126d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            }
127d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
128d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            // Is the CPU available?
129d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            if (!CPU_ISSET(cpu, &availCPUs)) {
130d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                cerr << "CPU " << optarg << " not currently available" << endl;
131d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                cerr << "  Available CPUs: " << availCPUs << endl;
132d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                exit(3);
133d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            }
134d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
135d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            // Record the choice
136d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            *((opt == 'c') ? &options.clientCPU : &options.serverCPU) = cpu;
137d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            break;
138d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        }
139d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
140d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        case 'n': // iterations
141d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            options.iterations = strtoul(optarg, &chptr, 10);
142d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            if (*chptr != '\0') {
143d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                cerr << "Invalid iterations specified of: " << optarg << endl;
144d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                exit(4);
145d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            }
146d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            if (options.iterations < 1) {
147d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                cerr << "Less than 1 iteration specified by: "
148d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                    << optarg << endl;
149d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                exit(5);
150d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            }
151d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            break;
152d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
153d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        case 'd': // Delay between each iteration
154d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            options.iterDelay = strtod(optarg, &chptr);
155d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            if ((*chptr != '\0') || (options.iterDelay < 0.0)) {
156d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                cerr << "Invalid delay specified of: " << optarg << endl;
157d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                exit(6);
158d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            }
159d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            break;
160d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
161d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        case '?':
162d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        default:
163d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << basename(argv[0]) << " [options]" << endl;
164d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "  options:" << endl;
165d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "    -s cpu - server CPU number" << endl;
166d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "    -c cpu - client CPU number" << endl;
167d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "    -n num - iterations" << endl;
168d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "    -d time - delay after operation in seconds" << endl;
169d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            exit(((optopt == 0) || (optopt == '?')) ? 0 : 7);
170d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        }
171d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
172d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
173d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Display selected options
174d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cout << "serverCPU: ";
175d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if (options.serverCPU == unbound) {
176d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        cout << " unbound";
177d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    } else {
178d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        cout << options.serverCPU;
179d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
180d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cout << endl;
181d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cout << "clientCPU: ";
182d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if (options.clientCPU == unbound) {
183d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        cout << " unbound";
184d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    } else {
185d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        cout << options.clientCPU;
186d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
187d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cout << endl;
188d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cout << "iterations: " << options.iterations << endl;
189d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cout << "iterDelay: " << options.iterDelay << endl;
190d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
191d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Fork client, use this process as server
192d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    fflush(stdout);
193d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    switch (pid_t pid = fork()) {
194d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    case 0: // Child
195d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        client();
196d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        return 0;
197d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
198d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    default: // Parent
199d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        server();
200d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
201d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        // Wait for all children to end
202d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        do {
203d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            int stat;
204d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            rv = wait(&stat);
205d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            if ((rv == -1) && (errno == ECHILD)) { break; }
206d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            if (rv == -1) {
207d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                cerr << "wait failed, rv: " << rv << " errno: "
208d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                    << errno << endl;
209d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                perror(NULL);
210d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                exit(8);
211d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            }
212d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        } while (1);
213d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        return 0;
214d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
215d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    case -1: // Error
216d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        exit(9);
217d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
218d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
219d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    return 0;
220d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
221d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
222d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic void server(void)
223d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
224d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int rv;
225d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
226d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Add the service
227d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    sp<ProcessState> proc(ProcessState::self());
228d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    sp<IServiceManager> sm = defaultServiceManager();
229d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if ((rv = sm->addService(serviceName,
230d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        new AddIntsService(options.serverCPU))) != 0) {
231d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        cerr << "addService " << serviceName << " failed, rv: " << rv
232d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            << " errno: " << errno << endl;
233d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
234d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
235d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Start threads to handle server work
236d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    proc->startThreadPool();
237d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
238d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
239d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic void client(void)
240d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
241d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int rv;
242d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    sp<IServiceManager> sm = defaultServiceManager();
243d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    double min = FLT_MAX, max = 0.0, total = 0.0; // Time in seconds for all
244d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                                                  // the IPC calls.
245d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
246d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // If needed bind to client CPU
247d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if (options.clientCPU != unbound) { bindCPU(options.clientCPU); }
248d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
249d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Attach to service
250d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    sp<IBinder> binder;
251d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    do {
252d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        binder = sm->getService(serviceName);
253d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        if (binder != 0) break;
254d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        cout << serviceName << " not published, waiting..." << endl;
255d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        usleep(500000); // 0.5 s
256d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    } while(true);
257d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
258d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Perform the IPC operations
259d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    for (unsigned int iter = 0; iter < options.iterations; iter++) {
260d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        Parcel send, reply;
261d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
262d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        // Create parcel to be sent.  Will use the iteration cound
263d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        // and the iteration count + 3 as the two integer values
264d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        // to be sent.
265d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        int val1 = iter;
266d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        int val2 = iter + 3;
267d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        int expected = val1 + val2;  // Expect to get the sum back
268d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        send.writeInt32(val1);
269d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        send.writeInt32(val2);
270d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
271d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        // Send the parcel, while timing how long it takes for
272d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        // the answer to return.
273d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        struct timespec start;
274d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        clock_gettime(CLOCK_MONOTONIC, &start);
275d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        if ((rv = binder->transact(AddIntsService::ADD_INTS,
276d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            send, &reply)) != 0) {
277d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "binder->transact failed, rv: " << rv
278d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                << " errno: " << errno << endl;
279d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            exit(10);
280d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        }
281d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        struct timespec current;
282d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        clock_gettime(CLOCK_MONOTONIC, &current);
283d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
284d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        // Calculate how long this operation took and update the stats
285d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        struct timespec deltaTimespec = tsDelta(&start, &current);
286d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        double delta = ts2double(&deltaTimespec);
287d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        min = (delta < min) ? delta : min;
288d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        max = (delta > max) ? delta : max;
289d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        total += delta;
290d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        int result = reply.readInt32();
291d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        if (result != (int) (iter + iter + 3)) {
292d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "Unexpected result for iteration " << iter << endl;
293d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "  result: " << result << endl;
294d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "expected: " << expected << endl;
295d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        }
296d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
297f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller        if (options.iterDelay > 0.0) { testDelaySpin(options.iterDelay); }
298d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
299d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
300d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Display the results
301d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cout << "Time per iteration min: " << min
302d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        << " avg: " << (total / options.iterations)
303d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        << " max: " << max
304d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        << endl;
305d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
306d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
307d2447fd2505466a8c30cdca247325f79ba95be34Louis HuemillerAddIntsService::AddIntsService(int cpu): cpu_(cpu) {
308d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if (cpu != unbound) { bindCPU(cpu); }
309920f089dc6c15a3be3f68ead68ef1d439d5d7c93Bernhard Rosenkränzer}
310d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
311d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// Server function that handles parcels received from the client
312d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatus_t AddIntsService::onTransact(uint32_t code, const Parcel &data,
3131281503d76c3ce0599dbfba329ba044036b17c16Andreas Gampe                                    Parcel* reply, uint32_t /* flags */) {
314d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int val1, val2;
315d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    status_t rv(0);
316d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int cpu;
317d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
318d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // If server bound to a particular CPU, check that
319d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // were executing on that CPU.
320d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if (cpu_ != unbound) {
321e337f25c84b2dfbeca6cb50abe35f6c2956b08c7David 'Digit' Turner        cpu = sched_getcpu();
322d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        if (cpu != cpu_) {
323d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            cerr << "server onTransact on CPU " << cpu << " expected CPU "
324d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                  << cpu_ << endl;
325d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            exit(20);
326d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        }
327d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
328d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
329d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // Perform the requested operation
330d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    switch (code) {
331d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    case ADD_INTS:
332d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        val1 = data.readInt32();
333d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        val2 = data.readInt32();
334d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        reply->writeInt32(val1 + val2);
335d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        break;
336d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
337d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    default:
338d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller      cerr << "server onTransact unknown code, code: " << code << endl;
339d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller      exit(21);
340d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
341d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
342d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    return rv;
343d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
344d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
345d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic void bindCPU(unsigned int cpu)
346d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
347d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    int rv;
348d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    cpu_set_t cpuset;
349d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
350d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    CPU_ZERO(&cpuset);
351d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    CPU_SET(cpu, &cpuset);
352d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    rv = sched_setaffinity(0, sizeof(cpuset), &cpuset);
353d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
354d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if (rv != 0) {
355d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        cerr << "bindCPU failed, rv: " << rv << " errno: " << errno << endl;
356d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        perror(NULL);
357d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        exit(30);
358d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
359d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
360d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
361d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic ostream &operator<<(ostream &stream, const String16& str)
362d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
363d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    for (unsigned int n1 = 0; n1 < str.size(); n1++) {
364d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        if ((str[n1] > 0x20) && (str[n1] < 0x80)) {
365d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            stream << (char) str[n1];
366d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        } else {
367d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            stream << '~';
368d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        }
369d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
370d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
371d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    return stream;
372d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
373d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
374d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic ostream &operator<<(ostream &stream, const cpu_set_t& set)
375d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
376d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    for (unsigned int n1 = 0; n1 < CPU_SETSIZE; n1++) {
377d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        if (CPU_ISSET(n1, &set)) {
378d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            if (n1 != 0) { stream << ' '; }
379d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller            stream << n1;
380d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        }
381d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
382d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
383d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    return stream;
384d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
385