#include <stdatomic.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <tcl.h>

_Atomic unsigned long long threadCount = 0;
_Atomic unsigned long long interpCount = 0;

void *threadRunner(void *arg) {
	Tcl_Interp *interp;
	int tclReturnValue;

	threadCount++;

	interp = Tcl_CreateInterp();

	interpCount++;

	tclReturnValue = Tcl_Init(interp);
	if (tclReturnValue != TCL_OK) {
		fprintf(stderr, "warning: TclInit() failed.\n");
	}

	Tcl_DeleteInterp(interp);

	interpCount--;

	Tcl_FinalizeThread();

	threadCount--;

	return(NULL);
}

int main(int argc, char **argv) {
	pthread_t threadId;
	struct timespec sleepTime;
	int pthreadCreateRet;
	int idx = 0;
	int tclMajor, tclMinor, tclPatchLevel;

	Tcl_FindExecutable(argv[0]);

	Tcl_GetVersion(&tclMajor, &tclMinor, &tclPatchLevel, NULL);

	printf("Testing Tcl version %i.%i.%i\n", tclMajor, tclMinor, tclPatchLevel);

	for (idx = 0;; idx++) {
		if ((idx % 1024) == 0) {
			idx = 0;

			printf("Thread Count: %llu, Interp Count: %llu\n", threadCount, interpCount);
		}

		pthreadCreateRet = pthread_create(&threadId, NULL, threadRunner, NULL);
		if (pthreadCreateRet != 0) {
			fprintf(stderr, "error: pthread_create() failed, exiting.\n");

			return(1);
		}

		sleepTime.tv_sec = 0;
		sleepTime.tv_nsec = 1000000;
		nanosleep(&sleepTime, NULL);
	}

	return(0);
}
