source: mainline/kernel/test/mm/slab2.c@ 201abde

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 201abde was 201abde, checked in by Martin Decky <martin@…>, 18 years ago

make thread ID 64 bit (task ID is 64 bit already)
cleanup thread syscalls

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <test.h>
30#include <mm/slab.h>
31#include <print.h>
32#include <proc/thread.h>
33#include <arch.h>
34#include <mm/frame.h>
35#include <memstr.h>
36#include <synch/condvar.h>
37#include <synch/mutex.h>
38
39#define ITEM_SIZE 256
40
41/** Fill memory with 2 caches, when allocation fails,
42 * free one of the caches. We should have everything in magazines,
43 * now allocation should clean magazines and allow for full allocation.
44 */
45static void totalmemtest(bool quiet)
46{
47 slab_cache_t *cache1;
48 slab_cache_t *cache2;
49 int i;
50
51 void *data1, *data2;
52 void *olddata1 = NULL, *olddata2 = NULL;
53
54 cache1 = slab_cache_create("cache1_tst", ITEM_SIZE, 0, NULL, NULL, 0);
55 cache2 = slab_cache_create("cache2_tst", ITEM_SIZE, 0, NULL, NULL, 0);
56
57 if (!quiet)
58 printf("Allocating...");
59
60 /* Use atomic alloc, so that we find end of memory */
61 do {
62 data1 = slab_alloc(cache1, FRAME_ATOMIC);
63 data2 = slab_alloc(cache2, FRAME_ATOMIC);
64 if ((!data1) || (!data2)) {
65 if (data1)
66 slab_free(cache1, data1);
67 if (data2)
68 slab_free(cache2, data2);
69 break;
70 }
71 memsetb((uintptr_t) data1, ITEM_SIZE, 0);
72 memsetb((uintptr_t) data2, ITEM_SIZE, 0);
73 *((void **) data1) = olddata1;
74 *((void **) data2) = olddata2;
75 olddata1 = data1;
76 olddata2 = data2;
77 } while (1);
78
79 if (!quiet) {
80 printf("done.\n");
81 printf("Deallocating cache2...");
82 }
83
84 /* We do not have memory - now deallocate cache2 */
85 while (olddata2) {
86 data2 = *((void **) olddata2);
87 slab_free(cache2, olddata2);
88 olddata2 = data2;
89 }
90
91 if (!quiet) {
92 printf("done.\n");
93 printf("Allocating to cache1...\n");
94 }
95
96 for (i = 0; i < 30; i++) {
97 data1 = slab_alloc(cache1, FRAME_ATOMIC);
98 if (!data1) {
99 if (!quiet)
100 printf("Incorrect memory size - use another test.");
101 return;
102 }
103 memsetb((uintptr_t) data1, ITEM_SIZE, 0);
104 *((void **) data1) = olddata1;
105 olddata1 = data1;
106 }
107 while (1) {
108 data1 = slab_alloc(cache1, FRAME_ATOMIC);
109 if (!data1)
110 break;
111 memsetb((uintptr_t) data1, ITEM_SIZE, 0);
112 *((void **) data1) = olddata1;
113 olddata1 = data1;
114 }
115
116 if (!quiet)
117 printf("Deallocating cache1...");
118
119 while (olddata1) {
120 data1 = *((void **) olddata1);
121 slab_free(cache1, olddata1);
122 olddata1 = data1;
123 }
124
125 if (!quiet) {
126 printf("done.\n");
127 slab_print_list();
128 }
129
130 slab_cache_destroy(cache1);
131 slab_cache_destroy(cache2);
132}
133
134static slab_cache_t *thr_cache;
135static semaphore_t thr_sem;
136static condvar_t thread_starter;
137static mutex_t starter_mutex;
138static bool sh_quiet;
139
140#define THREADS 8
141
142static void slabtest(void *priv)
143{
144 void *data = NULL, *new;
145
146 thread_detach(THREAD);
147
148 mutex_lock(&starter_mutex);
149 condvar_wait(&thread_starter,&starter_mutex);
150 mutex_unlock(&starter_mutex);
151
152 if (!sh_quiet)
153 printf("Starting thread #%llu...\n",THREAD->tid);
154
155 /* Alloc all */
156 if (!sh_quiet)
157 printf("Thread #%llu allocating...\n", THREAD->tid);
158
159 while (1) {
160 /* Call with atomic to detect end of memory */
161 new = slab_alloc(thr_cache, FRAME_ATOMIC);
162 if (!new)
163 break;
164 *((void **) new) = data;
165 data = new;
166 }
167
168 if (!sh_quiet)
169 printf("Thread #%llu releasing...\n", THREAD->tid);
170
171 while (data) {
172 new = *((void **)data);
173 *((void **) data) = NULL;
174 slab_free(thr_cache, data);
175 data = new;
176 }
177
178 if (!sh_quiet)
179 printf("Thread #%llu allocating...\n", THREAD->tid);
180
181 while (1) {
182 /* Call with atomic to detect end of memory */
183 new = slab_alloc(thr_cache, FRAME_ATOMIC);
184 if (!new)
185 break;
186 *((void **) new) = data;
187 data = new;
188 }
189
190 if (!sh_quiet)
191 printf("Thread #%llu releasing...\n", THREAD->tid);
192
193 while (data) {
194 new = *((void **)data);
195 *((void **) data) = NULL;
196 slab_free(thr_cache, data);
197 data = new;
198 }
199
200 if (!sh_quiet)
201 printf("Thread #%llu finished\n", THREAD->tid);
202
203 slab_print_list();
204 semaphore_up(&thr_sem);
205}
206
207static void multitest(int size, bool quiet)
208{
209 /* Start 8 threads that just allocate as much as possible,
210 * then release everything, then again allocate, then release
211 */
212 thread_t *t;
213 int i;
214
215 if (!quiet)
216 printf("Running stress test with size %d\n", size);
217
218 condvar_initialize(&thread_starter);
219 mutex_initialize(&starter_mutex);
220
221 thr_cache = slab_cache_create("thread_cache", size, 0, NULL, NULL, 0);
222 semaphore_initialize(&thr_sem,0);
223 for (i = 0; i < THREADS; i++) {
224 if (!(t = thread_create(slabtest, NULL, TASK, 0, "slabtest", false))) {
225 if (!quiet)
226 printf("Could not create thread %d\n", i);
227 } else
228 thread_ready(t);
229 }
230 thread_sleep(1);
231 condvar_broadcast(&thread_starter);
232
233 for (i = 0; i < THREADS; i++)
234 semaphore_down(&thr_sem);
235
236 slab_cache_destroy(thr_cache);
237 if (!quiet)
238 printf("Stress test complete.\n");
239}
240
241char * test_slab2(bool quiet)
242{
243 sh_quiet = quiet;
244
245 if (!quiet)
246 printf("Running reclaim single-thread test .. pass 1\n");
247 totalmemtest(quiet);
248 if (!quiet)
249 printf("Running reclaim single-thread test .. pass 2\n");
250 totalmemtest(quiet);
251 if (!quiet)
252 printf("Reclaim test OK.\n");
253
254 multitest(128, quiet);
255 multitest(2048, quiet);
256 multitest(8192, quiet);
257
258 return NULL;
259}
Note: See TracBrowser for help on using the repository browser.