Skip to content

Instantly share code, notes, and snippets.

@dnikku
Last active November 11, 2015 18:11
Show Gist options
  • Save dnikku/ee891049764caecbba9c to your computer and use it in GitHub Desktop.
Save dnikku/ee891049764caecbba9c to your computer and use it in GitHub Desktop.
_beginthreadex/CreateThread leaks when using CRT or not (with multiple wait)
#include "stdafx.h"
/*
stdafx.f:
#include <time.h>
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <process.h>
*/
static volatile LONG g_scheduledThreads = 0;
static volatile LONG g_executedThreads = 0;
static volatile INT64 g_size = 0;
static CRITICAL_SECTION g_cs;
static ULONGLONG g_started = GetTickCount64();
int getLogTime() {
return (int) ((GetTickCount64() - g_started) / 1000);
}
void printCounts(int step) {
printf(" %03d sec: step:%d, scheduled:%d, completed:%d\n", getLogTime(), step, g_scheduledThreads, g_executedThreads);
}
void executeThread(int v){
//leaks:
time_t tt = _time64(NULL);
//leaks: FILETIME ft; GetSystemTimeAsFileTime(&ft);
//no leaks: char sz[524 * 1024]; sprintf(sz, "Salutare de la mare");
//no leaks: SYSTEMTIME stm; GetSystemTime(&stm); g_size += stm.wSecond;
//EnterCriticalSection(&g_cs); g_executedThreads++; LeaveCriticalSection(&g_cs);
InterlockedAdd(&g_executedThreads, 1);
}
static unsigned int __stdcall _beginthreadex_wrapper(void *arg) {
executeThread(1);
return 0;
}
const int maxThreadsCount = MAXIMUM_WAIT_OBJECTS;
bool _beginthreadex_factory(int& step) {
DWORD lastError = 0;
HANDLE threads[maxThreadsCount];
int threadsCount = 0;
while (threadsCount < maxThreadsCount){
unsigned int id;
threads[threadsCount] = (HANDLE)_beginthreadex(NULL,
64 * 1024, _beginthreadex_wrapper, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION, &id);
if (threads[threadsCount] == NULL) {
lastError = GetLastError();
break;
}
else threadsCount++;
}
if (threadsCount > 0) {
WaitForMultipleObjects(threadsCount, threads, TRUE, INFINITE);
for (int i = 0; i < threadsCount; i++) CloseHandle(threads[i]);
}
step += threadsCount;
g_scheduledThreads += threadsCount;
if (threadsCount < maxThreadsCount) {
printf(" %03d sec: step:%d, _beginthreadex failed. err(%d); errno(%d). exiting ...\n", getLogTime(), step, lastError, errno);
return false;
}
else return true;
}
int _tmain(int argc, _TCHAR* argv[]) {
printf("starting ...\n");
//InitializeCriticalSection(&g_cs);
bool(*f_wrapper) (int&) = _beginthreadex_factory;
int loop = 1;
while (true) {
int step = 0;
for (int i = 0; i < 10000; i++) {
int j = 0;
if (!f_wrapper(step)){
Sleep(5 * 1000); // wait some time ...
printf(" sleep 5 seconds\n");
printCounts(step);
// try to create 10 more threads
printf(" try to create 2 more times\n");
for (j = 1; j < 2; j++) f_wrapper(step);
break; // exit from for ...
}
if (step % 6400 == 0) printCounts(step); // print progress
}
Sleep(4 * 1000); // wait to stop all threads
printCounts(step);
printf("rerun loop: %d", loop++);
getchar(); // press enter to rerun
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment