-int main(int argc, char *argv[])
-{
- int rv;
-
- // Determine CPUs available for use.
- // This testcase limits its self to using CPUs that were
- // available at the start of the benchmark.
- cpu_set_t availCPUs;
- if ((rv = sched_getaffinity(0, sizeof(availCPUs), &availCPUs)) != 0) {
- cerr << "sched_getaffinity failure, rv: " << rv
- << " errno: " << errno << endl;
- exit(1);
- }
-
- // Parse command line arguments
- int opt;
- while ((opt = getopt(argc, argv, "s:c:n:d:?")) != -1) {
- char *chptr; // character pointer for command-line parsing
-
- switch (opt) {
- case 'c': // client CPU
- case 's': { // server CPU
- // Parse the CPU number
- int cpu = strtoul(optarg, &chptr, 10);
- if (*chptr != '\0') {
- cerr << "Invalid cpu specified for -" << (char) opt
- << " option of: " << optarg << endl;
- exit(2);
- }
-
- // Is the CPU available?
- if (!CPU_ISSET(cpu, &availCPUs)) {
- cerr << "CPU " << optarg << " not currently available" << endl;
- cerr << " Available CPUs: " << availCPUs << endl;
- exit(3);
- }
-
- // Record the choice
- *((opt == 'c') ? &options.clientCPU : &options.serverCPU) = cpu;
- break;
- }
-
- case 'n': // iterations
- options.iterations = strtoul(optarg, &chptr, 10);
- if (*chptr != '\0') {
- cerr << "Invalid iterations specified of: " << optarg << endl;
- exit(4);
- }
- if (options.iterations < 1) {
- cerr << "Less than 1 iteration specified by: "
- << optarg << endl;
- exit(5);
- }
- break;
-
- case 'd': // Delay between each iteration
- options.iterDelay = strtod(optarg, &chptr);
- if ((*chptr != '\0') || (options.iterDelay < 0.0)) {
- cerr << "Invalid delay specified of: " << optarg << endl;
- exit(6);
- }
- break;
-
- case '?':
- default:
- cerr << basename(argv[0]) << " [options]" << endl;
- cerr << " options:" << endl;
- cerr << " -s cpu - server CPU number" << endl;
- cerr << " -c cpu - client CPU number" << endl;
- cerr << " -n num - iterations" << endl;
- cerr << " -d time - delay after operation in seconds" << endl;
- exit(((optopt == 0) || (optopt == '?')) ? 0 : 7);
- }
- }
-
- // Display selected options
- cout << "serverCPU: ";
- if (options.serverCPU == unbound) {
- cout << " unbound";
- } else {
- cout << options.serverCPU;
- }
- cout << endl;
- cout << "clientCPU: ";
- if (options.clientCPU == unbound) {
- cout << " unbound";
- } else {
- cout << options.clientCPU;
- }
- cout << endl;
- cout << "iterations: " << options.iterations << endl;
- cout << "iterDelay: " << options.iterDelay << endl;
-
- // Fork client, use this process as server
- fflush(stdout);
- switch (pid_t pid = fork()) {
- case 0: // Child
- client();
- return 0;
-
- default: // Parent
- if (!server()) { break; }
-
- // Wait for all children to end
- do {
- int stat;
- rv = wait(&stat);
- if ((rv == -1) && (errno == ECHILD)) { break; }
- if (rv == -1) {
- cerr << "wait failed, rv: " << rv << " errno: "
- << errno << endl;
- perror(NULL);
- exit(8);
- }
- } while (1);
- return 0;
-
- case -1: // Error
- exit(9);
- }
-
- return 0;
-}
-