mirror of https://github.com/lianthony/NT4.0
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
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);
|
|
}
|
|
|