/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1991 by Mike Parker.				    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

/* A simple diagnostic program that spawns many processes and loads the system
   down. Its purpose it to try an cause a lot of system activity in an attempt
   to ferret out bugs in the low level RCI process context switch code (which
   is embedded into UNIX).
*/
   
#include <signal.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>

#define NPROCS 20

int pids[NPROCS];

int dead[NPROCS];

int runchild()
{
 int pid;

 pid = fork();
 if (pid < 0)
  { perror("fork");
    exit(1);
  }
 if (pid != 0) return(pid);
 child();
}

child()
{
 int exit();
 struct itimerval itv;
 double d;
 double dd;

 int allocSize;
 char *memory;
 int i;

 allocSize = irandom (10,64000);
 memory = (char*)malloc(allocSize);
 for (i=0; i<allocSize; i += 512)
  { memory[i] = 0;
  }

 itv.it_value.tv_sec = mth$int_random() % 15;
 itv.it_value.tv_usec = mth$int_random() % 1000000;
 itv.it_interval.tv_sec = 0;
 itv.it_interval.tv_usec = 0;
 signal(SIGALRM,exit);
 if (setitimer(ITIMER_REAL,&itv,(struct itimerval *)0) < 0)
  { perror("setitimer");
  }
 dd = d;
 while (1)
  { d += .1;
    dd += .1;
    if (d != dd)
     { printf("---------------- %g != %g ----------------\n",d,dd);
     }
  }
}

reapchild()
{
 int pid;
 int i;

 while (1)
  { pid = wait3((union wait *)0,WNOHANG,(struct rusage *)0);
    if (pid <= 0) break;
    for (i=0;dead[i];i++) ;
    dead[i] = pid;
  }
}

main()
{
 int i;
 int j;

 signal(SIGCHLD,reapchild);
 for (i=0;i<NPROCS;i++)
  { pids[i] = 0;
    dead[i] = 0;
  }
 while (1)
  { for (i=0;i<NPROCS;i++)
     { if (pids[i] == 0)
	{ pids[i] = runchild();
	}
     }
    for (i=0;i<NPROCS;i++)
     { if (dead[i] != 0)
	{ for (j=0;j<NPROCS;j++)
	   { if (pids[j] == dead[i])
	      { pids[j] = 0;
	      }
	   }
	  dead[i] = 0;
	}
     }
  }
}
