// main.cpp
#include <windows.h>
#include <process.h>
#include <iostream>
#include <assert.h>
using namespace std;
int nNumThreads = 0;
int nNumAllocs = 0;
int nAllocSize = 0;
HANDLE hStartEvent = NULL;
unsigned __stdcall threadfunc1( void* pParm )
{
HANDLE hHeap = (HANDLE) pParm;
for( int i=0; i<nNumAllocs; i++ ) {
char* p = (char*) HeapAlloc( hHeap, 0, nAllocSize );
HeapFree( hHeap, 0, p );
} // for
return 0;
}
unsigned __stdcall threadfunc2( void* pParm )
{
HANDLE hHeap = (HANDLE) pParm;
for( int i=0; i<nNumAllocs; i++ ) {
char* p =
(char*) HeapAlloc(hHeap, HEAP_NO_SERIALIZE, nAllocSize);
HeapFree( hHeap, HEAP_NO_SERIALIZE, p );
} // for
return 0;
}
void
go( char* pTest, char* pNumThreads, char* pNumAllocs,
char* pAllocSize )
{
nNumThreads = atoi( pNumThreads );
nNumAllocs = atoi( pNumAllocs );
nAllocSize = atoi( pAllocSize );
DWORD dwStart, dwEnd;
BOOL bOneHeap = ( lstrcmp( pTest, "1") == 0 );
if( bOneHeap ) {
cout << "one heap per process" << endl;
} else {
cout << "one heap per thread" << endl;
} // else
cout << nNumThreads << " threads" << endl;
cout << nNumAllocs << " allocations per thread" << endl;
cout << nAllocSize << " bytes per allocation" << endl;
HANDLE* aThreads = new HANDLE[nNumThreads];
HANDLE* aHeaps = NULL;
if( !bOneHeap ) {
// Create a heap for each thread
aHeaps = new HANDLE[nNumThreads];
for( int i=0; i<nNumThreads; i++ ) {
aHeaps[i] = HeapCreate(HEAP_NO_SERIALIZE, 0x100000, 0);
} // for
} // if
unsigned int notused;
for( int i=0; i<nNumThreads; i++ ) {
aThreads[i] =
(HANDLE) _beginthreadex(NULL, 0,
(bOneHeap ? threadfunc1 : threadfunc2),
(bOneHeap ? GetProcessHeap() : aHeaps[i]),
CREATE_SUSPENDED, ¬used );
} // for
dwStart = GetTickCount();
for( i=0; i<nNumThreads; i++ ) {
DWORD dwResult = ResumeThread( aThreads[i] );
assert( dwResult != 0xffffffff );
} // for
WaitForMultipleObjects(nNumThreads, aThreads, TRUE, INFINITE);
dwEnd = GetTickCount();
delete [] aThreads;
if( !bOneHeap ) {
for( i=0; i<nNumThreads; i++ ) {
HeapDestroy( aHeaps[i] ) ;
} // for
delete [] aHeaps;
} // if
cout << "time: " << (dwEnd-dwStart) << endl;
}
int main(int argc, TCHAR* argv[], TCHAR* envp[])
{
if( argc != 5 ) {
cout << "usage: HeapDemo <1|2> <numthreads>"
<< " <numallocs> <allocsize>" << endl;
cout << "first param=1 uses one process wide heap "
<< "(heap access is serialized)" << endl;
cout << "first param=2 uses one heap per thread "
<< "(no heap serialization)" << endl;
return 0;
} else {
go( argv[1], argv[2], argv[3], argv[4] );
} // else
return 0;
}