Created
April 25, 2018 18:35
-
-
Save samehmohamed88/8435b952215b22059356561a717b6136 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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