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(¤tTime, NULL); 23687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller delta = tvDelta(&startTime, ¤tTime); 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(¤t, NULL); 49487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller 49587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller // How much time is left 49687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller delta = tvDelta(&start, ¤t); 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(¤t) - 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(¤tCPU, 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