Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

249 lines
6.8 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
tmpheap.c
Abstract:
Test program for the MP heap package.
Author:
John Vert (jvert) 10-Jul-1995
Revision History:
--*/
#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
#include "windows.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "mpheap.h"
DWORD
ThreadStartup(
LPVOID Parameter
);
LPVOID Malloc(DWORD dwBytes);
VOID Free(LPVOID lpMem);
BOOL Suicide = FALSE;
HANDLE MpHeap;
LPVOID
Malloc(
DWORD dwBytes
)
{
return(MpHeapAlloc(MpHeap,0,dwBytes));
}
VOID
Free(
LPVOID lpMem
)
{
MpHeapFree(MpHeap,lpMem);
}
int
_CRTAPI1
main (argc, argv)
int argc;
char *argv[];
{
ULONG NumThreads;
ULONG i;
HANDLE *h;
DWORD ThreadId;
DWORD Parallelism;
DWORD Seconds;
ULONG StartContextSwitches;
NTSTATUS Status;
SYSTEM_CONTEXT_SWITCH_INFORMATION SwitchInfo;
LPMPHEAP_STATISTICS HeapStats;
PVOID Foo;
DWORD StatSize;
DWORD Error;
if (argc != 4) {
fprintf(stderr, "Usage: tmpheap NumThreads HeapParallelism Seconds\n");
exit(1);
}
NumThreads = atoi(argv[1]);
Parallelism = atoi(argv[2]);
Seconds = atoi(argv[3]);
MpHeap = MpHeapCreate(0, 0, Parallelism);
if (MpHeap == NULL) {
fprintf(stderr, "MpHeapCreate failed error %d\n",GetLastError);
exit(1);
}
h = Malloc(NumThreads * sizeof(HANDLE));
if (h==NULL) {
fprintf(stderr, "Malloc thread handle array failed\n");
exit(1);
}
Status = NtQuerySystemInformation(SystemContextSwitchInformation,
&SwitchInfo,
sizeof(SwitchInfo),
NULL);
if (!NT_SUCCESS(Status)) {
fprintf(stderr, "NtQuerySystemInformation failed %08lx\n", Status);
exit(1);
}
StartContextSwitches = SwitchInfo.ContextSwitches;
for (i=0; i<NumThreads; i++) {
h[i] = CreateThread(NULL,
0,
ThreadStartup,
NULL,
0,
&ThreadId);
if (h==NULL) {
fprintf(stderr, "CreateThread %d failed %d\n",i,GetLastError());
exit(1);
}
}
Sleep(Seconds * 1000);
Status = NtQuerySystemInformation(SystemContextSwitchInformation,
&SwitchInfo,
sizeof(SwitchInfo),
NULL);
if (!NT_SUCCESS(Status)) {
fprintf(stderr, "second NtQuerySystemInformation failed %08lx\n", Status);
}
Suicide = TRUE;
WaitForMultipleObjects(NumThreads, h, TRUE, INFINITE);
StatSize = Parallelism * sizeof(MPHEAP_STATISTICS);
HeapStats = (LPMPHEAP_STATISTICS)LocalAlloc(LMEM_FIXED, StatSize);
if (HeapStats != NULL) {
Error = MpHeapGetStatistics(MpHeap,&StatSize, HeapStats);
if (Error==ERROR_SUCCESS) {
for (i=0; i<StatSize/sizeof(MPHEAP_STATISTICS);i++) {
printf("HEAP %d\n",i);
printf(" Allocations: %8d\n",HeapStats[i].TotalAllocates);
printf(" Contention : %8d (%d%%)\n",HeapStats[i].Contention,
100*HeapStats[i].Contention/HeapStats[i].TotalAllocates);
printf(" Lookaside Allocs: %8d (%d%%)\n",
HeapStats[i].LookasideAllocates,
100*HeapStats[i].LookasideAllocates/HeapStats[i].TotalAllocates);
printf(" Frees: %8d\n",HeapStats[i].TotalFrees);
printf(" Lookaside Frees: %8d (%d%%)\n",
HeapStats[i].LookasideFrees,
100*HeapStats[i].LookasideFrees/HeapStats[i].TotalFrees);
printf(" Delayed Frees: %8d (%d%%)\n",
HeapStats[i].DelayedFrees,
100*HeapStats[i].DelayedFrees/HeapStats[i].TotalFrees);
}
printf("%d seconds, %d context switches\n\n",
Seconds,
SwitchInfo.ContextSwitches - StartContextSwitches);
} else {
fprintf(stderr, "MpHeapStatistics failed with error %d\n",Error);
}
MpHeapDestroy(MpHeap);
LocalFree(HeapStats);
}
return(0);
}
DWORD
ThreadStartup(
LPVOID Parameter
)
{
DWORD Seed = GetCurrentThreadId();
PULONG Buffer;
DWORD BufferSize;
DWORD Delay;
DWORD i,j;
DWORD Fill;
PULONG Last = NULL;
BOOL AllocAgain;
DWORD MaxSize=0;
DWORD CurrentSize=0;
DWORD CurrentAllocs = 0;
DWORD MaxAllocs = 0;
//
// Loop allocating/filling/freeing random chunks
// of memory.
//
Fill = GetCurrentThreadId();
while (!Suicide) {
//
// Decide whether to allocate a new chunk or free the
// last chunk.
//
AllocAgain = (BOOL)((RtlRandom(&Seed) & 0xff) > 0x80);
if (AllocAgain) {
BufferSize = (RtlRandom(&Seed) & 0xfff) + sizeof(PUCHAR) + sizeof(ULONG);
CurrentAllocs++;
if (CurrentAllocs > MaxAllocs) {
MaxAllocs = CurrentAllocs;
}
Buffer = Malloc(BufferSize);
if (Buffer == NULL) {
fprintf(stderr,"malloc of %d returned NULL\n",BufferSize);
return(0);
}
CurrentSize += BufferSize;
if (CurrentSize > MaxSize) {
if ((CurrentSize >> 18) != (MaxSize >> 18)) {
printf("Thread %x up to %d bytes %d allocs\n",
GetCurrentThreadId(),
CurrentSize,
CurrentAllocs);
}
MaxSize = CurrentSize;
}
if ((CurrentSize > MaxSize) &&
(CurrentSize-MaxSize > 0x10000)) {
}
for (j=0; j<BufferSize/sizeof(ULONG); j++) {
Buffer[j] = Fill;
}
Buffer[0] = (ULONG)Last;
Buffer[1] = BufferSize;
Last = Buffer;
} else if (Buffer != NULL) {
Last = (PULONG)Buffer[0];
CurrentSize -= Buffer[1];
--CurrentAllocs;
Free(Buffer);
Buffer = Last;
}
Delay = RtlRandom(&Seed) & 0x1ff;
for (i=0; i< Delay; i++) {
Fill = GetCurrentThreadId();
}
if ((RtlRandom(&Seed) & 0xffff) < CurrentAllocs) {
//
// Magic number, free EVERYTHING!
//
while (Buffer != NULL) {
Last = (PULONG)Buffer[0];
CurrentSize -= Buffer[1];
--CurrentAllocs;
Free(Buffer);
Buffer = Last;
}
}
}
return(0);
}