Skip to content

Instantly share code, notes, and snippets.

@dag-erling
Last active October 18, 2021 08:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dag-erling/ab57cd6aff0b213a060b9aaa366ecfa0 to your computer and use it in GitHub Desktop.
Save dag-erling/ab57cd6aff0b213a060b9aaa366ecfa0 to your computer and use it in GitHub Desktop.
Drive your load average arbitrarily high
/*-
* Copyright (c) 2021 Dag-Erling Smørgrav
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* This program will drive your load average arbitrarily high while
* consuming a minimum of memory. In theory, the load average sould reach
* 90%-95% of the number of threads specified on the command line (-n).
* The percentage will be lower if you increase the sleep time (-s).
* Memory usage should be asymptotical to one page (4096 kB) per thread.
* Note that it may take a while (possibly minutes) for the load to reach
* the target.
*/
#include <err.h>
#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
static unsigned long nthreads = 10;
static unsigned long sleeptime = 1;
static struct timespec rqtp = { .tv_sec = 0, .tv_nsec = 1 };
static void *spin(void *) __attribute__((__noreturn__));
static void *spin(void *arg __attribute__((__unused__)))
{
for (;;) {
clock_nanosleep(CLOCK_MONOTONIC, 0, &rqtp, NULL);
}
}
static unsigned long optul(int opt, const char *optarg,
unsigned long min, unsigned long max)
{
unsigned long num;
if (*optarg == '+') {
optarg++;
}
while (*optarg != '\0') {
if (*optarg < '0' || *optarg > '9') {
errx(1, "-%c: invalid number", opt);
}
if (num * 10 + *optarg - '0' < num) {
errx(1, "-%c: overflow", opt);
}
num = num * 10 + *optarg - '0';
optarg++;
}
if (num < min || num > max) {
errx(1, "-%c: value must be between %lu and %lu", opt, min, max);
}
return num;
}
static void usage(const char *arg0)
{
for (const char *p = arg0; *p != '\0'; p++) {
if (*p == '/') {
arg0 = p + 1;
}
}
fprintf(stderr, "usage: %s [-n nthreads] [-t sleeptime]\n", arg0);
exit(1);
}
int main(int argc, char *argv[])
{
pthread_attr_t attr;
pthread_t thr;
int opt;
while ((opt = getopt(argc, argv, "n:s:")) != -1) {
switch (opt) {
case 'n':
nthreads = optul(opt, optarg, 1, ULONG_MAX);
break;
case 's':
sleeptime = optul(opt, optarg, 1, ULONG_MAX);
break;
default:
usage(argv[0]);
}
}
if (argc > optind) {
usage(argv[0]);
}
argc -= optind;
argv += optind;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 64); // will be rounded up
for (unsigned long i = 0; i < nthreads; i++) {
pthread_create(&thr, &attr, spin, NULL);
}
pthread_join(thr, NULL);
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment