1#include <SupportDefs.h>
2#include <OS.h>
3
4#include <malloc.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8
9#ifdef MALLOC_DEBUG
10void dump_heap_list(int argc, char **argv);
11void dump_allocations(bool statsOnly, thread_id thread);
12#endif
13
14
15inline uint8
16sum(addr_t address)
17{
18	return (address >> 24) | (address >> 16) | (address >> 8) | address;
19}
20
21
22inline void
23write_test_pattern(void *address, size_t size)
24{
25	for (size_t i = 0; i < size; i++)
26		*((uint8 *)address + i) = sum((addr_t)address + i);
27}
28
29
30inline void
31verify_test_pattern(void *address, size_t size)
32{
33	for (size_t i = 0; i < size; i++) {
34		if (*((uint8 *)address + i) != sum((addr_t)address + i)) {
35			printf("test patern invalid at %p: %u vs. %u\n",
36				(uint8 *)address + i, *((uint8 *)address + i),
37				sum((addr_t)address + i));
38			exit(1);
39		}
40	}
41}
42
43
44void
45allocate_random_no_alignment(int32 count, size_t maxSize)
46{
47	void **allocations = new void *[count];
48	size_t *sizes = new size_t[count];
49	for (int32 i = 0; i < count; i++) {
50		sizes[i] = rand() % maxSize;
51		allocations[i] = malloc(sizes[i]);
52		if (allocations[i] == NULL) {
53			printf("allocation of %lu bytes failed\n", sizes[i]);
54			exit(1);
55		}
56#ifdef __x86_64__
57		if (((addr_t)allocations[i] & 0xf) != 0) {
58			printf("allocation %p not aligned failed\n",
59				allocations[i]);
60			exit(1);
61		}
62#endif
63		write_test_pattern(allocations[i], sizes[i]);
64	}
65
66	for (int32 i = count - 1; i >= 0; i--) {
67		verify_test_pattern(allocations[i], sizes[i]);
68		free(allocations[i]);
69	}
70
71	delete[] allocations;
72	delete[] sizes;
73}
74
75
76void
77allocate_random_fixed_alignment(int32 count, size_t maxSize, size_t alignment)
78{
79	void **allocations = new void *[count];
80	size_t *sizes = new size_t[count];
81	for (int32 i = 0; i < count; i++) {
82		sizes[i] = rand() % maxSize;
83		allocations[i] = memalign(alignment, sizes[i]);
84		if (allocations[i] == NULL) {
85			printf("allocation of %lu bytes failed\n", sizes[i]);
86			exit(1);
87		}
88
89		if ((addr_t)allocations[i] % alignment != 0) {
90			printf("allocation of %lu bytes misaligned: %p -> 0x%08lx "
91				" with alignment %lu (0x%08lx)\n", sizes[i],
92				allocations[i], (addr_t)allocations[i] % alignment, alignment,
93				alignment);
94			exit(1);
95		}
96
97		write_test_pattern(allocations[i], sizes[i]);
98	}
99
100	for (int32 i = count - 1; i >= 0; i--) {
101		verify_test_pattern(allocations[i], sizes[i]);
102		free(allocations[i]);
103	}
104
105	delete[] allocations;
106	delete[] sizes;
107}
108
109
110void
111allocate_random_random_alignment(int32 count, size_t maxSize)
112{
113	for (int32 i = 0; i < count / 128; i++)
114		allocate_random_fixed_alignment(128, maxSize, 1 << (rand() % 18));
115}
116
117
118int
119main(int argc, char *argv[])
120{
121	allocate_random_no_alignment(1024, B_PAGE_SIZE * 128);
122	allocate_random_random_alignment(1024, B_PAGE_SIZE * 128);
123
124#ifdef MALLOC_DEBUG
125	dump_heap_list(0, NULL);
126	dump_allocations(false, -1);
127#endif
128
129	printf("tests succeeded\n");
130	return 0;
131}
132