wip commit. acpi button driver.
[AROS.git] / test / kernel / allocator.c
blob14c9a3391724fa2d034b91e8bface932683c610e
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
7 * WARNING!!!
8 * This test relies on some particular internal functioning of kernel memory allocator!
9 * You'll have to change the code if you change something in kernel!
11 * Note also that this test requires working exec trap handling.
15 * We will not perform access tests because when we exit from trap handler,
16 * execution continues from the same location (re-triggering the trap again).
17 * Fixing this requires adjusting PC register in the context, which is not
18 * portable accross various CPUs and additionally will not currently work
19 * on all ports. We don't want to overcomplicate things so much.
21 #define NO_ACCESS_TESTS
23 #include <aros/kernel.h>
24 #include <exec/execbase.h>
25 #include <proto/exec.h>
26 #include <proto/kernel.h>
28 #include <stdio.h>
30 #if defined(__AROSPLATFORM_SMP__)
31 #include <aros/types/spinlock_s.h>
32 #include <proto/execlock.h>
33 #include <resources/execlock.h>
34 #endif
36 /* Include private kernel.resource stuff, for DumpState() */
37 struct KernelBase;
38 #include "../../rom/kernel/mm_linear.h"
40 #define PAGES_NUM 14
42 volatile static ULONG trap;
44 static void TrapHandler(ULONG code, void *ctx)
46 trap = code;
49 static void TestRead(UBYTE *location)
51 #ifdef NO_ACCESS_TESTS
52 printf("Access tests disabled\n");
53 #else
55 volatile UBYTE val;
57 /* Reset trap indication */
58 trap = -1;
60 printf("Test read from 0x%p... ", location);
61 val = *location;
64 * We can't printf() from trap handler. Instead we just
65 * remember trap code and check it later here.
67 if (trap == -1)
68 printf("Success, value is 0x%02X\n", val);
69 else
70 printf("Hit trap 0x%08X\n", trap);
72 #endif
76 * Print status of all pages in the specified MemHeader.
77 * '#' means allocated page, '.' means free page
79 static void DumpState(struct MemHeader *mh)
81 struct BlockHeader *head = (struct BlockHeader *)mh->mh_First;
82 IPTR p;
84 printf("Page map (%u total):\n", (unsigned)head->size);
86 for (p = 0; p < head->size; p++)
87 printf(P_STATUS(head->map[p]) ? "#" : ".");
89 printf("\n");
92 int main(void)
94 #if defined(KrnStatMemory)
96 #if defined(__AROSPLATFORM_SMP__)
97 void *ExecLockBase = OpenResource("execlock.resource");
98 #endif
99 APTR KernelBase;
100 struct Task *me;
101 ULONG page;
102 struct MemHeader *TestArea;
103 ULONG TestLength;
104 struct MemChunk *mc;
105 APTR region1, region2, region3, region4;
107 KernelBase = OpenResource("kernel.resource");
108 if (!KernelBase)
110 printf("Failed to open kernel.resource!\n");
111 return 1;
114 if (!KrnStatMemory(0, KMS_PageSize, &page, TAG_DONE))
116 printf("MMU support is not implemented for this system!\n"
117 "kernel.resource memory allocator will not work!\n");
118 return 1;
120 printf("System page size: %u (0x%08X)\n", (unsigned)page, (unsigned)page);
122 TestLength = PAGES_NUM * page;
123 TestArea = AllocMem(TestLength, MEMF_ANY);
124 printf("Allocated test region (%u bytes) at 0x%p\n", (unsigned)TestLength, TestArea);
125 if (!TestArea)
127 printf("Failed to allocate test region!\n");
128 return 1;
131 /* Install trap handler */
132 me = FindTask(NULL);
133 me->tc_TrapCode = TrapHandler;
135 /* Compose a MemHeader */
136 TestArea->mh_Node.ln_Succ = NULL;
137 TestArea->mh_Node.ln_Type = NT_MEMORY;
138 TestArea->mh_Node.ln_Name = "Kernel allocator test area";
139 TestArea->mh_Node.ln_Pri = 127; /* This MemHeader must be the first in the list, otherwise KrnFreePages() will find a wrong one */
140 TestArea->mh_Attributes = MEMF_FAST;
141 TestArea->mh_Lower = TestArea;
142 TestArea->mh_Upper = TestArea->mh_Lower + TestLength - 1;
143 TestArea->mh_First = TestArea->mh_Lower + MEMHEADER_TOTAL;
144 TestArea->mh_Free = TestLength - MEMHEADER_TOTAL;
146 mc = TestArea->mh_First;
147 mc->mc_Next = NULL;
148 mc->mc_Bytes = TestArea->mh_Free;
150 /* Give up the area to kernel allocator */
151 KrnInitMemory(TestArea);
152 if (mc->mc_Next || mc->mc_Bytes)
154 printf("KrnInitMemory() failed:\n"
155 " mc_Next is 0x%p\n"
156 " mc_Bytes is %lu\n",
157 mc->mc_Next, mc->mc_Bytes);
158 goto exit;
161 printf("Testing initial no-access protection...\n");
162 TestRead((UBYTE *)TestArea + page);
165 * Insert the area into system list.
166 * We do it manually because in future AddMemList() will call KrnInitMemory() itself.
168 #if defined(__AROSPLATFORM_SMP__)
169 if (ExecLockBase)
170 ObtainSystemLock(&SysBase->MemList, SPINLOCK_MODE_WRITE, LOCKF_FORBID);
171 else
172 Forbid();
173 #else
174 Forbid();
175 #endif
176 Enqueue(&SysBase->MemList, &TestArea->mh_Node);
177 #if defined(__AROSPLATFORM_SMP__)
178 if (ExecLockBase)
179 ReleaseSystemLock(&SysBase->MemList, LOCKF_FORBID);
180 else
181 Permit();
182 #else
183 Permit();
184 #endif
186 printf("Allocating region1 (two read-write pages)...\n");
187 region1 = KrnAllocPages(NULL, 2 * page, MEMF_FAST);
188 printf("region1 at 0x%p\n", region1);
189 DumpState(TestArea);
191 printf("Freeing region1...\n");
192 KrnFreePages(region1, 2 * page);
193 printf("Done!\n");
194 DumpState(TestArea);
196 printf("Allocating region1 (3 read-only pages)...\n");
197 region1 = KrnAllocPages(NULL, 3 * page, MEMF_FAST);
198 printf("region1 at 0x%p\n", region1);
199 DumpState(TestArea);
201 printf("Allocating region2 (4 write-only ;-) pages)...\n");
202 region2 = KrnAllocPages(NULL, 4 * page, MEMF_FAST);
203 printf("region2 at 0x%p\n", region2);
204 DumpState(TestArea);
206 printf("Attempting to allocate page with wrong flags...\n");
207 region3 = KrnAllocPages(NULL, page, MEMF_CHIP|MEMF_FAST);
208 printf("Region at 0x%p\n", region3);
209 if (region3)
211 printf("WARNING!!! This should have been NULL!\n");
212 KrnFreePages(region3, page);
215 printf("Freeing region1...\n");
216 KrnFreePages(region1, 3 * page);
217 printf("Done!\n");
218 DumpState(TestArea);
220 printf("Freeing region2...\n");
221 KrnFreePages(region2, 4 * page);
222 printf("Done!\n");
223 DumpState(TestArea);
225 printf("Allocating region1 (one read-write page)...\n");
226 region1 = KrnAllocPages(NULL, page, MEMF_FAST);
227 printf("region1 at 0x%p\n", region1);
228 DumpState(TestArea);
230 printf("Freeing region1...\n");
231 KrnFreePages(region1, page);
232 printf("Done!\n");
233 DumpState(TestArea);
235 printf("Now we'll try to fragment the memory\n");
237 printf("Allocating region1 (2 pages)...\n");
238 region1 = KrnAllocPages(NULL, 2 * page, MEMF_FAST);
239 printf("region1 at 0x%p\n", region1);
240 DumpState(TestArea);
242 printf("Allocating region2 (3 pages)...\n");
243 region2 = KrnAllocPages(NULL, 3 * page, MEMF_FAST);
244 printf("region2 at 0x%p\n", region2);
245 DumpState(TestArea);
247 printf("Allocating region 3 (1 page)...\n");
248 region3 = KrnAllocPages(NULL, page, MEMF_FAST);
249 printf("Region at 0x%p\n", region3);
250 DumpState(TestArea);
252 printf("Allocating region 4 (2 pages)...\n");
253 region4 = KrnAllocPages(NULL, 2 * page, MEMF_FAST);
254 printf("region4 at 0x%p\n", region1);
255 DumpState(TestArea);
257 printf("Freeing region1...\n");
258 KrnFreePages(region1, 2 * page);
259 printf("Done!\n");
260 DumpState(TestArea);
262 printf("Freeing region3...\n");
263 KrnFreePages(region3, page);
264 printf("Done!\n");
265 DumpState(TestArea);
267 printf("Allocating region 3 (1 page) again...\n");
268 region3 = KrnAllocPages(NULL, page, MEMF_FAST);
269 printf("Region at 0x%p\n", region3);
270 DumpState(TestArea);
272 printf("Freeing region2...\n");
273 KrnFreePages(region2, 3 * page);
274 printf("Done!\n");
275 DumpState(TestArea);
277 printf("Freeing region3...\n");
278 KrnFreePages(region3, page);
279 printf("Done!\n");
280 DumpState(TestArea);
282 printf("Freeing region4...\n");
283 KrnFreePages(region4, 2 * page);
284 printf("Done!\n");
285 DumpState(TestArea);
287 exit:
288 if (TestArea->mh_Node.ln_Succ)
290 Forbid();
291 Remove(&TestArea->mh_Node);
292 Permit();
294 FreeMem(TestArea, TestLength);
296 #else
297 printf("The test can't be built for this kernel.resource implementation\n");
298 #endif
300 return 0;