Skip to content

Instantly share code, notes, and snippets.

@samehmohamed88
Created April 25, 2018 18:35
Show Gist options
  • Save samehmohamed88/8435b952215b22059356561a717b6136 to your computer and use it in GitHub Desktop.
Save samehmohamed88/8435b952215b22059356561a717b6136 to your computer and use it in GitHub Desktop.
#include <ctype.h>
#include <errno.h>
#include <libgen.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
int hogcpu (void);
int hogio (void);
int hogvm (long long bytes, long long stride, long long hang, int keep);
int hoghdd (long long bytes);
int
hogvm (long long bytes, long long stride, long long hang, int keep)
{
char *ptr = 0;
char c;
int do_malloc = 1;
for(int i=0; i < 10000000; i++)
{
if (do_malloc)
{
if (!(ptr = (char *) malloc (bytes * sizeof (char))))
{
return 1;
}
if (keep)
do_malloc = 0;
}
for (i = 0; i < bytes; i += stride)
ptr[i] = 'Z'; /* Ensure that COW happens. */
if (hang == 0)
{
while (1)
sleep (1024);
}
else if (hang > 0)
{
sleep (hang);
}
for (i = 0; i < bytes; i += stride)
{
c = ptr[i];
if (c != 'Z')
{
return 1;
}
}
if (do_malloc)
{
free (ptr);
}
}
return 0;
}
int
hogcpu (void)
{
for(int i=0; i < 1000000; i++)
sqrt (rand ());
return 0;
}
int
hogio ()
{
for(int i=0; i < 10000; i++)
sync ();
return 0;
}
int main()
{
struct timespec start, end;
double cpu_time_used;
int i, pid, children = 0, retval = 0;
long starttime, stoptime, runtime, forks;
int do_dryrun = 0;
long long do_backoff = 3000;
long long do_timeout = 0;
long long do_cpu = 1;
long long do_io = 1;
long long do_vm = 1;
long long do_vm_bytes = 256 * 1024 * 1024;
long long do_vm_stride = 4096;
long long do_vm_hang = -1;
int do_vm_keep = 0;
long long do_hdd = 0;
long long do_hdd_bytes = 1024 * 1024 * 1024;
long long backoff, timeout = 0;
/* Calculate the backoff value so we get good fork throughput. */
backoff = do_backoff * forks;
clock_gettime(CLOCK_REALTIME, &start);
while ((forks = (do_cpu + do_io + do_vm + do_hdd)))
{
if (do_cpu)
{
switch (pid = fork ())
{
case 0: /* child */
alarm (timeout);
usleep (backoff);
if (do_dryrun)
exit (0);
exit (hogcpu ());
case -1: /* error */
break;
default:
++children;
}
--do_cpu;
}
if (do_io)
{
switch (pid = fork ())
{
case 0: /* child */
alarm (timeout);
usleep (backoff);
if (do_dryrun)
exit (0);
exit (hogio ());
case -1: /* error */
break;
default: /* parent */
++children;
}
--do_io;
}
if (do_vm)
{
switch (pid = fork ())
{
case 0: /* child */
alarm (timeout);
usleep (backoff);
if (do_dryrun)
exit (0);
exit (hogvm
(do_vm_bytes, do_vm_stride, do_vm_hang, do_vm_keep));
case -1: /* error */
break;
default: /* parent */
++children;
}
--do_vm;
}
}
/* Wait for our children to exit. */
while (children)
{
int status, ret;
if ((pid = wait (&status)) > 0)
{
--children;
if (WIFEXITED (status))
{
if ((ret = WEXITSTATUS (status)) == 0)
{
printf( "<-- worker %i returned normally\n", pid);
}
else
{
printf( "<-- worker %i returned error %i\n", pid, ret);
++retval;
printf( "now reaping child worker processes\n");
if (signal (SIGUSR1, SIG_IGN) == SIG_ERR)
printf( "handler error: %s\n", strerror (errno));
if (kill (-1 * getpid (), SIGUSR1) == -1)
printf( "kill error: %s\n", strerror (errno));
}
}
}
}
clock_gettime(CLOCK_REALTIME, &end);
cpu_time_used = (end.tv_nsec = start.tv_nsec) / 1000000000.0;
/* Print final status message. */
if (retval)
{
printf( "failed run completed in %.2f s\n", cpu_time_used);
}
else
{
printf( "successful run completed in -- %.2f s\n", cpu_time_used);
}
exit (retval);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment