#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

struct S {
	int i, j, k, l, m, n;
};

void * CallingMalloc( void * arg __attribute__((unused)) ) {
	for ( volatile int i = 0; i < 10000; i += 1 ) {
		volatile int      * ip  = (volatile int      *)malloc( sizeof(   int  ) *   1 );
		volatile int      * aip = (volatile int      *)malloc( sizeof(   int  ) * 100 );
		volatile struct S * sp  = (volatile struct S *)malloc( sizeof(struct S) * 200 );

		sp->i = 0;
		sp->j = 1;
		sp->k = 2;
		sp->l = 3;
		sp->m = 4;
		sp->n = 5;
		for(int j = 0; j < 100; j++) {
			aip[j] = j;
		}
		*ip = i;

		free( (void*)sp );
		free( (void*)aip );
		free( (void*)ip );
	}
	return NULL;
}

int main(int argc, const char * const argv[]) {
	char * endptr;
	int nThreads = 15;
	switch(argc) {
	case 1:
		break;
	case 2:
		nThreads = strtol(argv[1], &endptr, 10);
		if( *endptr != 0 || nThreads <= 0 ) {
			fprintf(stderr, "Invalid number of threads %s\n", argv[1]);
			return 1;
		}
		break;
	default:
		fprintf(stderr, "Usage: %s [no of threads]\n", argv[0]);
		return 1;
	}
	printf("Running %d threads\n", nThreads);
	while(true) {
		pthread_t t[nThreads];
		for(int i = 0; i < nThreads; i++) {
			pthread_create( &t[i], NULL, CallingMalloc, NULL );
		}

		for(int i = 0; i < nThreads; i++) {
			pthread_join( t[i], NULL );
		}
	}
	return 0;
}