wifiLoadScanAssoc.c revision 8c48ce6585b1823c1b5e93e049f2eab91ccb73fc
187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller/*
287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Copyright (C) 2010 The Android Open Source Project
387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Licensed under the Apache License, Version 2.0 (the "License");
587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * you may not use this file except in compliance with the License.
687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * You may obtain a copy of the License at
787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *      http://www.apache.org/licenses/LICENSE-2.0
987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
1087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Unless required by applicable law or agreed to in writing, software
1187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * distributed under the License is distributed on an "AS IS" BASIS,
1287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * See the License for the specific language governing permissions and
1487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * limitations under the License.
1587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
1687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller */
1787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
1887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller/*
1987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * WiFi load, scan, associate, unload stress test
2087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
2187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Repeatedly executes the following sequence:
2287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
2387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   1. Load WiFi driver
2487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   2. Start supplicant
2587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   3. Random delay
2687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   4. Obtain supplicant status (optional)
2787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   5. Stop supplicant
2887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   6. Unload WiFi driver
2987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
3087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * The "Obtain supplicant status" step is optional and is pseudo
3187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * randomly performed 50% of the time.  The default range of
3287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * delay after start supplicant is intentionally selected such
3387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * that the obtain supplicant status and stop supplicant steps
3487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * may be performed while the WiFi driver is still performing a scan
3587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * or associate.  The default values are given by DEFAULT_DELAY_MIN
3687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * and DEFAULT_DELAY_MAX.  Other values can be specified through the
3787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * use of the -d and -D command-line options.
3887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
3987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Each sequence is refered to as a pass and by default an unlimited
4087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * number of passes are performed.  An override of the range of passes
4187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * to be executed is available through the use of the -s (start) and
4287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * -e (end) command-line options.  There is also a default time in
4387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * which the test executes, which is given by DEFAULT_DURATION and
4487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * can be overriden through the use of the -t command-line option.
4587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller */
4687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
4787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <assert.h>
4887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <errno.h>
4987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <libgen.h>
5087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <math.h>
5187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <sched.h>
5287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <stdio.h>
5387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <stdlib.h>
5487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <time.h>
5587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <unistd.h>
5687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
5787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <sys/syscall.h>
5887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <sys/types.h>
5987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <sys/wait.h>
6087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
6187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <hardware_legacy/wifi.h>
6287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
6387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define LOG_TAG "wifiLoadScanAssocTest"
6487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <utils/Log.h>
6587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <testUtil.h>
6687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
6787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define DEFAULT_START_PASS     0
6887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define DEFAULT_END_PASS     999
6987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define DEFAULT_DURATION       FLT_MAX // A fairly long time, so that
7087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                                       // range of passes will have
7187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                                       // precedence
7287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define DEFAULT_DELAY_MIN      0.0     // Min delay after start supplicant
7387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define DEFAULT_DELAY_MAX     20.0     // Max delay after start supplicant
7487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define DELAY_EXP            150.0     // Exponent which determines the
7587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                                       // amount by which values closer
7687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                                       // to DELAY_MIN are favored.
7787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
7887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define CMD_STATUS           "wpa_cli status 2>&1"
7987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define CMD_STOP_FRAMEWORK   "stop 2>&1"
8087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define CMD_START_FRAMEWORK  "start 2>&1"
8187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
8287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define MAXSTR      100
8387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define MAXCMD      500
8487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
8587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillertypedef unsigned int bool_t;
8687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define true (0 == 0)
8787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define false (!true)
8887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
8987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// Local description of sched_setaffinity(2), sched_getaffinity(2), and
9087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// getcpu(2)
9187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define CPU_SETSIZE 1024
9287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillertypedef struct {uint64_t bits[CPU_SETSIZE / 64]; } cpu_set_t;
9387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint sched_setaffinity(pid_t pid, unsigned int cpusetsize, const cpu_set_t *set);
9487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *set);
9587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerstruct getcpu_cache;
9687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache);
9787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid CPU_CLR(int cpu, cpu_set_t *set);
9887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint CPU_ISSET(int cpu, const cpu_set_t *set);
9987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid CPU_SET(int cpu, cpu_set_t *set);
10087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid CPU_ZERO(cpu_set_t *set);
10187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
10287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// File scope variables
10387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillercpu_set_t availCPU;
10487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerunsigned int numAvailCPU;
10587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerfloat delayMin = DEFAULT_DELAY_MIN;
10687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerfloat delayMax = DEFAULT_DELAY_MAX;
10787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerbool_t driverLoadedAtStart;
10887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
10987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// File scope prototypes
11087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerstatic void init(void);
11187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerstatic void execCmd(const char *cmd);
11287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerstatic void randDelay(void);
11387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerstatic void randBind(const cpu_set_t *availSet, int *chosenCPU);
11487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
11587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller/*
11687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Main
11787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
11887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Performs the following high-level sequence of operations:
11987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
12087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   1. Command-line parsing
12187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
12287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   2. Initialization
12387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
12487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   3. Execute passes that repeatedly perform the WiFi load, scan,
12587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *      associate, unload sequence.
12687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
12787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   4. Restore state of WiFi driver to state it was at the
12887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *      start of the test.
12987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
13087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   5. Restart framework
13187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller */
13287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint
13387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillermain(int argc, char *argv[])
13487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
13587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    FILE *fp;
13687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int rv, opt;
13787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int cpu;
13887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    char *chptr;
13987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    unsigned int pass;
14087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    char cmd[MAXCMD];
14187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    float duration = DEFAULT_DURATION;
14287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    unsigned int startPass = DEFAULT_START_PASS, endPass = DEFAULT_END_PASS;
14387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    struct timeval startTime, currentTime, delta;
14487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
14587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testSetLogCatTag(LOG_TAG);
14687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
14787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Parse command line arguments
14887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    while ((opt = getopt(argc, argv, "d:D:s:e:t:?")) != -1) {
14987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        switch (opt) {
15087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        case 'd': // Minimum Delay
15187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            delayMin = strtod(optarg, &chptr);
15287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            if ((*chptr != '\0') || (delayMin < 0.0)) {
15387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                testPrintE("Invalid command-line specified minimum delay "
15487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                    "of: %s", optarg);
15587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                exit(1);
15687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            }
15787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            break;
15887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
15987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        case 'D': // Maximum Delay
16087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            delayMax = strtod(optarg, &chptr);
16187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            if ((*chptr != '\0') || (delayMax < 0.0)) {
16287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                testPrintE("Invalid command-line specified maximum delay "
16387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                    "of: %s", optarg);
16487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                exit(2);
16587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            }
16687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            break;
16787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
16887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        case 't': // Duration
16987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            duration = strtod(optarg, &chptr);
17087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            if ((*chptr != '\0') || (duration < 0.0)) {
17187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                testPrintE("Invalid command-line specified duration of: %s",
17287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                    optarg);
17387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                exit(3);
17487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            }
17587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            break;
17687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
17787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        case 's': // Starting Pass
17887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            startPass = strtoul(optarg, &chptr, 10);
17987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            if (*chptr != '\0') {
18087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                testPrintE("Invalid command-line specified starting pass "
18187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                    "of: %s", optarg);
18287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                exit(4);
18387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            }
18487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            break;
18587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
18687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        case 'e': // Ending Pass
18787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            endPass = strtoul(optarg, &chptr, 10);
18887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            if (*chptr != '\0') {
18987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                testPrintE("Invalid command-line specified ending pass "
19087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                    "of: %s", optarg);
19187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                exit(5);
19287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            }
19387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            break;
19487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
19587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        case '?':
19687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        default:
19787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("  %s [options]", basename(argv[0]));
19887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("    options:");
19987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("      -s Starting pass");
20087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("      -e Ending pass");
20187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("      -t Duration");
20287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("      -d Delay min");
20387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("      -D Delay max");
2048c48ce6585b1823c1b5e93e049f2eab91ccb73fcLouis Huemiller            exit(((optopt == 0) || (optopt == '?')) ? 0 : 6);
20587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
20687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
20787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (delayMax < delayMin) {
20887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("Unexpected maximum delay less than minimum delay");
20987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("  delayMin: %f delayMax: %f", delayMin, delayMax);
21087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(7);
21187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
21287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (endPass < startPass) {
21387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("Unexpected ending pass before starting pass");
21487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("  startPass: %u endPass: %u", startPass, endPass);
21587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(8);
21687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
21787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (argc != optind) {
21887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("Unexpected command-line postional argument");
21987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("  %s [-s start_pass] [-e end_pass] [-d duration]",
22087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            basename(argv[0]));
22187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(9);
22287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
22387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("duration: %g", duration);
22487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("startPass: %u", startPass);
22587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("endPass: %u", endPass);
22687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("delayMin: %f", delayMin);
22787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("delayMax: %f", delayMax);
22887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
22987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    init();
23087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
23187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // For each pass
23287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    gettimeofday(&startTime, NULL);
23387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    for (pass = startPass; pass <= endPass; pass++) {
23487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Stop if duration of work has already been performed
23587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        gettimeofday(&currentTime, NULL);
23687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        delta = tvDelta(&startTime, &currentTime);
23787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if (tv2double(&delta) > duration) { break; }
23887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
23987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintI("==== pass %u", pass);
24087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
24187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Use a pass dependent sequence of random numbers
24287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        srand48(pass);
24387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
24487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Load WiFi Driver
24587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        randBind(&availCPU, &cpu);
24687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((rv = wifi_load_driver()) != 0) {
24787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("CPU: %i wifi_load_driver() failed, rv: %i\n",
24887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                cpu, rv);
24987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(20);
25087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
25187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintI("CPU: %i wifi_load_driver succeeded", cpu);
25287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
25387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Start Supplicant
25487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        randBind(&availCPU, &cpu);
25587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((rv = wifi_start_supplicant()) != 0) {
25687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("CPU: %i wifi_start_supplicant() failed, rv: %i\n",
25787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                cpu, rv);
25887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(21);
25987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
26087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintI("CPU: %i wifi_start_supplicant succeeded", cpu);
26187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
26287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Sleep a random amount of time
26387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        randDelay();
26487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
26587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        /*
26687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller         * Obtain WiFi Status
26787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller         * Half the time skip this step, which helps increase the
26887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller         * level of randomization.
26987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller         */
27087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if (testRandBool()) {
27187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STATUS);
27287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            if (rv >= (signed) sizeof(cmd) - 1) {
27387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                testPrintE("Command too long for: %s\n", CMD_STATUS);
27487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                exit(22);
27587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            }
27687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            execCmd(cmd);
27787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
27887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
27987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Stop Supplicant
28087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        randBind(&availCPU, &cpu);
28187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((rv = wifi_stop_supplicant()) != 0) {
28287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("CPU: %i wifi_stop_supplicant() failed, rv: %i\n",
28387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                cpu, rv);
28487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(23);
28587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
28687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintI("CPU: %i wifi_stop_supplicant succeeded", cpu);
28787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
28887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Unload WiFi Module
28987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        randBind(&availCPU, &cpu);
29087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((rv = wifi_unload_driver()) != 0) {
29187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("CPU: %i wifi_unload_driver() failed, rv: %i\n",
29287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                cpu, rv);
29387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(24);
29487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
29587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintI("CPU: %i wifi_unload_driver succeeded", cpu);
29687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
29787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
29887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // If needed restore WiFi driver to state it was in at the
29987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // start of the test.  It is assumed that it the driver
30087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // was loaded, then the wpa_supplicant was also running.
30187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (driverLoadedAtStart) {
30287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Load driver
30387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((rv = wifi_load_driver()) != 0) {
30487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("main load driver failed, rv: %i", rv);
30587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(25);
30687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
30787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
30887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Start supplicant
30987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((rv = wifi_start_supplicant()) != 0) {
31087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("main start supplicant failed, rv: %i", rv);
31187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(26);
31287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
31387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
31487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Obtain WiFi Status
31587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STATUS);
31687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if (rv >= (signed) sizeof(cmd) - 1) {
31787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("Command too long for: %s\n", CMD_STATUS);
31887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(22);
31987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
32087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        execCmd(cmd);
32187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
32287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
32387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Start framework
32487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
32587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (rv >= (signed) sizeof(cmd) - 1) {
32687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("Command too long for: %s\n", CMD_START_FRAMEWORK);
32787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(27);
32887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
32987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    execCmd(cmd);
33087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
3318c48ce6585b1823c1b5e93e049f2eab91ccb73fcLouis Huemiller    testPrintI("Successfully completed %u passes", pass - startPass);
3328c48ce6585b1823c1b5e93e049f2eab91ccb73fcLouis Huemiller
33387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return 0;
33487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
33587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
33687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller/*
33787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Initialize
33887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
33987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Perform testcase initialization, which includes:
34087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
34187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   1. Determine which CPUs are available for use
34287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
34387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   2. Determine total number of available CPUs
34487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
34587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   3. Stop framework
34687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
34787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   4. Determine whether WiFi driver is loaded and if so
34887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *      stop wpa_supplicant and unload WiFi driver.
34987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller */
35087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid
35187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerinit(void)
35287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
35387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int rv;
35487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    unsigned int n1;
35587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    char cmd[MAXCMD];
35687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
35787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Use whichever CPUs are available at start of test
35887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv = sched_getaffinity(0, sizeof(availCPU), &availCPU);
35987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (rv != 0) {
36087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("init sched_getaffinity failed, rv: %i errno: %i",
36187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            rv, errno);
36287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(40);
36387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
36487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
36587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // How many CPUs are available
36687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    numAvailCPU = 0;
36787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    for (n1 = 0; n1 < CPU_SETSIZE; n1++) {
36887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if (CPU_ISSET(n1, &availCPU)) { numAvailCPU++; }
36987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
37087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("numAvailCPU: %u", numAvailCPU);
37187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
37287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Stop framework
37387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
37487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (rv >= (signed) sizeof(cmd) - 1) {
37587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("Command too long for: %s\n", CMD_STOP_FRAMEWORK);
37687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(41);
37787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
37887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    execCmd(cmd);
37987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
38087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Is WiFi driver loaded?
38187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // If so stop the wpa_supplicant and unload the driver.
38287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    driverLoadedAtStart = is_wifi_driver_loaded();
38387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("driverLoadedAtStart: %u", driverLoadedAtStart);
38487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (driverLoadedAtStart) {
38587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Stop wpa_supplicant
38687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Might already be stopped, in which case request should
38787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // return immediately with success.
38887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((rv = wifi_stop_supplicant()) != 0) {
38987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("init stop supplicant failed, rv: %i", rv);
39087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(42);
39187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
39287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintI("Stopped wpa_supplicant");
39387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
39487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((rv = wifi_unload_driver()) != 0) {
39587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("init unload driver failed, rv: %i", rv);
39687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            exit(43);
39787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
39887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintI("WiFi driver unloaded");
39987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
40087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
40187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
40287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
40387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller/*
40487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Execute Command
40587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
40687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Executes the command pointed to by cmd.  Which CPU executes the
40787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * command is randomly selected from the set of CPUs that were
40887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * available during testcase initialization.  Output from the
40987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * executed command is captured and sent to LogCat Info.  Once
41087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * the command has finished execution, it's exit status is captured
41187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * and checked for an exit status of zero.  Any other exit status
41287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * causes diagnostic information to be printed and an immediate
41387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * testcase failure.
41487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller */
41587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid
41687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis HuemillerexecCmd(const char *cmd)
41787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
41887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    FILE *fp;
41987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int rv;
42087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int status;
42187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    char str[MAXSTR];
42287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int cpu;
42387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
42487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Randomly bind to one of the available CPUs
42587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    randBind(&availCPU, &cpu);
42687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
42787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Display CPU executing on and command to be executed
42887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("CPU: %u cmd: %s", cpu, cmd);
42987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
43087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Execute the command
43187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    fflush(stdout);
43287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if ((fp = popen(cmd, "r")) == NULL) {
43387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("execCmd popen failed, errno: %i", errno);
43487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(61);
43587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
43687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
43787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Obtain and display each line of output from the executed command
43887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    while (fgets(str, sizeof(str), fp) != NULL) {
43987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if ((strlen(str) > 1) && (str[strlen(str) - 1] == '\n')) {
44087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            str[strlen(str) - 1] = '\0';
44187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
44287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintI(" out: %s", str);
44387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        delay(0.1);
44487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
44587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
44687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Obtain and check return status of executed command.
44787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Fail on non-zero exit status
44887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    status = pclose(fp);
44987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) {
45087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("Unexpected command failure");
45187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("  status: %#x", status);
45287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if (WIFEXITED(status)) {
45387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("WEXITSTATUS: %i", WEXITSTATUS(status));
45487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
45587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if (WIFSIGNALED(status)) {
45687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            testPrintE("WTERMSIG: %i", WTERMSIG(status));
45787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
45887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(62);
45987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
46087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
46187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
46287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller/*
46387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Random Delay
46487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
46587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Delays for a random amount of time within the range given
46687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * by the file scope variables delayMin and delayMax.  The
46787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * selected amount of delay can come from any part of the
46887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * range, with a bias towards values closer to delayMin.
46987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * The amount of bias is determined by the setting of DELAY_EXP.
47087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * The setting of DELAY_EXP should always be > 1.0, with higher
47187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * values causing a more significant bias toward the value
47287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * of delayMin.
47387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller */
47487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid randDelay(void)
47587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
47687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    const unsigned long nanosecspersec = 1000000000;
47787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    float            fract, biasedFract, amt;
47887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    struct timespec  remaining;
47987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    struct timeval   start, current, delta;
48087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
48187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Obtain start time
48287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    gettimeofday(&start, NULL);
48387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
48487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Determine random amount to sleep.
48587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Values closer to delayMin are prefered by an amount
48687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // determined by the value of DELAY_EXP.
48787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    fract = (double) lrand48() / (double) (1UL << 31);
48887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    biasedFract = pow(DELAY_EXP, fract) / pow(DELAY_EXP, 1.0);
48987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    amt = delayMin + ((delayMax - delayMin) * biasedFract);
49087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
49187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    do {
49287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Get current time
49387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        gettimeofday(&current, NULL);
49487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
49587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // How much time is left
49687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        delta = tvDelta(&start, &current);
49787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if (tv2double(&delta) > amt) { break; }
49887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
49987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Request to sleep for the remaining time
50087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        remaining = double2ts(amt - tv2double(&delta));
50187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        (void) nanosleep(&remaining, NULL);
50287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    } while (true);
50387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
50487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    testPrintI("delay: %.2f",
50587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        (float) (tv2double(&current) - tv2double(&start)));
50687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
50787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
50887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerstatic void
50987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis HuemillerrandBind(const cpu_set_t *availSet, int *chosenCPU)
51087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
51187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int rv;
51287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    cpu_set_t cpuset;
51387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    unsigned int chosenAvail, avail, cpu, currentCPU;
51487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
51587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Randomly bind to a CPU
51687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Lower 16 bits from random number generator thrown away,
51787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // because the low-order bits tend to have the same sequence for
51887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // different seed values.
51987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    chosenAvail = (lrand48() >> 16) % numAvailCPU;
52087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    CPU_ZERO(&cpuset);
52187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    avail = 0;
52287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    for (cpu = 0; cpu < CPU_SETSIZE; cpu++) {
52387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        if (CPU_ISSET(cpu, availSet)) {
52487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            if (chosenAvail == avail) {
52587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                CPU_SET(cpu, &cpuset);
52687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller                break;
52787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            }
52887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            avail++;
52987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        }
53087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
53187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    assert(cpu < CPU_SETSIZE);
53287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    sched_setaffinity(0, sizeof(cpuset), &cpuset);
53387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
53487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Confirm executing on requested CPU
53587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if ((rv = getcpu(&currentCPU, NULL, NULL)) != 0) {
53687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("randBind getcpu() failed, rv: %i errno: %i", rv, errno);
53787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(80);
53887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
53987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
54087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (currentCPU != cpu) {
54187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        testPrintE("randBind executing on unexpected CPU %i, expected %i",
54287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller            currentCPU, cpu);
54387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        exit(81);
54487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
54587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
54687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Let the caller know which CPU was chosen
54787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    *chosenCPU = cpu;
54887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
54987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
55087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// Local implementation of sched_setaffinity(2), sched_getaffinity(2), and
55187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// getcpu(2)
55287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint
55387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillersched_setaffinity(pid_t pid, unsigned int cpusetsize, const cpu_set_t *set)
55487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
55587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int rv;
55687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
55787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv = syscall(__NR_sched_setaffinity, pid, cpusetsize, set);
55887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
55987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return rv;
56087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
56187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
56287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint
56387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillersched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *set)
56487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
56587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int rv;
56687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
56787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv = syscall(__NR_sched_getaffinity, pid, cpusetsize, set);
56887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (rv < 0) { return rv; }
56987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
57087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Kernel implementation of sched_getaffinity() returns the number
57187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // of bytes in the set that it set.  Set the rest of our set bits
57287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // to 0.
57387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    memset(((char *) set) + rv, 0x00, sizeof(cpu_set_t) - rv);
57487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
57587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return 0;
57687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
57787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
57887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint
57987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillergetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
58087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
58187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    int rv;
58287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
58387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv = syscall(345, cpu, node, tcache);
58487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
58587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return rv;
58687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
58787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
58887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid
58987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis HuemillerCPU_CLR(int cpu, cpu_set_t *set)
59087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
59187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (cpu < 0) { return; }
59287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if ((unsigned) cpu >= (sizeof(cpu_set_t) * CHAR_BIT)) { return; }
59387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
59487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    *((uint64_t *)set + (cpu / 64)) &= ~(1ULL << (cpu % 64));
59587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
59687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
59787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerint
59887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis HuemillerCPU_ISSET(int cpu, const cpu_set_t *set)
59987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
60087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (cpu < 0) { return 0; }
60187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if ((unsigned) cpu >= (sizeof(cpu_set_t) * CHAR_BIT)) { return 0; }
60287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
60387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if ((*((uint64_t *)set + (cpu / 64))) & (1ULL << (cpu % 64))) {
60487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        return true;
60587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
60687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
60787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return false;
60887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
60987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
61087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid
61187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis HuemillerCPU_SET(int cpu, cpu_set_t *set)
61287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
61387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (cpu < 0) { return; }
61487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if ((unsigned) cpu > (sizeof(cpu_set_t) * CHAR_BIT)) { return; }
61587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
61687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    *((uint64_t *)set + (cpu / 64)) |= 1ULL << (cpu % 64);
61787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
61887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
61987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillervoid
62087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis HuemillerCPU_ZERO(cpu_set_t *set)
62187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
62287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    memset(set, 0x00, sizeof(cpu_set_t));
62387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
624