aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code/amcsshe.c
diff options
context:
space:
mode:
authorNick Barnes2001-10-31 14:40:56 +0000
committerNick Barnes2001-10-31 14:40:56 +0000
commit7acfca905d76140f4cc0b09c9a12de237de364cd (patch)
tree3ed8babfa3a73d30f29e08ca5d5adcda4ca4e826 /mps/code/amcsshe.c
parentb7ce4893f9902d57cd67ac9a92fa6c3d5a8fc833 (diff)
downloademacs-7acfca905d76140f4cc0b09c9a12de237de364cd.tar.gz
emacs-7acfca905d76140f4cc0b09c9a12de237de364cd.zip
Branch imports for masters.
Copied from Perforce Change: 23678 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code/amcsshe.c')
-rw-r--r--mps/code/amcsshe.c323
1 files changed, 323 insertions, 0 deletions
diff --git a/mps/code/amcsshe.c b/mps/code/amcsshe.c
new file mode 100644
index 00000000000..778ce7c1710
--- /dev/null
+++ b/mps/code/amcsshe.c
@@ -0,0 +1,323 @@
1/* impl.c.amcsshe: POOL CLASS AMC STRESS TEST WITH HEADER
2 *
3 * $HopeName: MMsrc!amcsshe.c(trunk.4) $
4 * Copyright (C) 2001 Harlequin Limited. All rights reserved.
5 */
6
7#include "fmthe.h"
8#include "testlib.h"
9#include "mpscamc.h"
10#include "mpsavm.h"
11#include "mpstd.h"
12#ifdef MPS_OS_W3
13#include "mpsw3.h"
14#endif
15#include "mps.h"
16#include <stdlib.h>
17#include <string.h>
18
19
20/* These values have been tuned to cause one top-generation collection. */
21#define testArenaSIZE ((size_t)1000*1024)
22#define avLEN 3
23#define exactRootsCOUNT 200
24#define ambigRootsCOUNT 50
25#define bogusRootsCOUNT 4096
26#define collectionsCOUNT 37
27#define rampSIZE 9
28#define initTestFREQ 6000
29#define genCOUNT 2
30
31/* testChain -- generation parameters for the test */
32
33static mps_gen_param_s testChain[genCOUNT] = {
34 { 150, 0.85 }, { 170, 0.45 } };
35
36
37/* objNULL needs to be odd so that it's ignored in exactRoots. */
38#define objNULL ((mps_addr_t)0xDECEA5ED)
39
40
41static mps_pool_t pool;
42static mps_ap_t ap;
43static mps_addr_t exactRoots[exactRootsCOUNT];
44static mps_addr_t ambigRoots[ambigRootsCOUNT];
45static mps_addr_t bogusRoots[bogusRootsCOUNT];
46
47
48
49static mps_word_t *ww = NULL;
50static mps_word_t *tvw;
51
52
53static mps_word_t dylan_make_WV(mps_word_t version, mps_word_t vb,
54 mps_word_t es, mps_word_t vf)
55{
56 /* VERSION- ... VB------ reserved ES---VF- */
57 return((version << (MPS_WORD_WIDTH - 8)) |
58 (vb << 16) |
59 (es << 3) |
60 vf);
61}
62
63
64static mps_res_t init(mps_addr_t addr, size_t size,
65 mps_addr_t *refs, size_t nr_refs)
66{
67
68 /* Make sure the size is aligned. */
69 if ((size & (ALIGN-1)) != 0) return MPS_RES_PARAM;
70
71 if (ww == NULL) {
72 ww = malloc(sizeof(mps_word_t) * (BASIC_WRAPPER_SIZE + 1));
73 if (ww == NULL) return MPS_RES_MEMORY;
74 tvw = malloc(sizeof(mps_word_t) * BASIC_WRAPPER_SIZE);
75 if (tvw == NULL) {
76 free(ww);
77 return MPS_RES_MEMORY;
78 }
79
80 /* Build a wrapper wrapper. */
81 ww[WW] = (mps_word_t)ww;
82 ww[WC] = (mps_word_t)ww; /* dummy class */
83 ww[WM] = (1 << 2) | 1; /* dummy subtype_mask */
84 ww[WF] = ((WS - 1) << 2) | 2;
85 ww[WV] = dylan_make_WV(2, 0, 0, 0);
86 ww[WS] = (1 << 2) | 1;
87 ww[WP] = 1;
88
89 /* Build a wrapper for traceable vectors. */
90 tvw[WW] = (mps_word_t)ww;
91 tvw[WC] = (mps_word_t)ww; /* dummy class */
92 tvw[WM] = (1 << 2) | 1; /* dummy subtype_mask */
93 tvw[WF] = 0; /* no fixed part */
94 tvw[WV] = dylan_make_WV(2, 0, 0, 2); /* traceable variable part */
95 tvw[WS] = 1; /* no patterns */
96 }
97
98 /* If there is enough room, make a vector, otherwise just */
99 /* make a padding object. */
100
101 if (size >= sizeof(mps_word_t) * 2) {
102 mps_word_t *p = (mps_word_t *)addr;
103 mps_word_t i, t = (size / sizeof(mps_word_t)) - 2;
104
105 p[0] = (mps_word_t)tvw; /* install vector wrapper */
106 p[1] = (t << 2) | 1; /* tag the vector length */
107 for(i = 0; i < t; ++i) {
108 mps_word_t r = rnd();
109
110 if (r & 1)
111 p[2+i] = ((r & ~(mps_word_t)3) | 1); /* random int */
112 else
113 p[2+i] = (mps_word_t)refs[(r >> 1) % nr_refs]; /* random ptr */
114 }
115 } else {
116 die(MPS_RES_FAIL, "small object");
117 }
118
119 return MPS_RES_OK;
120}
121
122
123static void dylan_write(mps_addr_t addr, mps_addr_t *refs, size_t nr_refs)
124{
125 mps_word_t *p = (mps_word_t *)addr;
126 mps_word_t t = p[1] >> 2;
127
128 /* If the object is a vector, update a random entry. */
129 if (p[0] == (mps_word_t)tvw && t > 0) {
130 mps_word_t r = rnd();
131 size_t i = 2 + (rnd() % t);
132
133 if (r & 1)
134 p[i] = ((r & ~(mps_word_t)3) | 1); /* random int */
135 else
136 p[i] = (mps_word_t)refs[(r >> 1) % nr_refs]; /* random ptr */
137 }
138}
139
140
141static mps_addr_t make(void)
142{
143 size_t length = rnd() % (2*avLEN);
144 size_t size = (length+2) * sizeof(mps_word_t);
145 mps_addr_t p, userP;
146 mps_res_t res;
147
148 do {
149 MPS_RESERVE_BLOCK(res, p, ap, size + headerSIZE);
150 if (res)
151 die(res, "MPS_RESERVE_BLOCK");
152 userP = (mps_addr_t)((char*)p + headerSIZE);
153 res = init(userP, size, exactRoots, exactRootsCOUNT);
154 if (res)
155 die(res, "dylan_init");
156 ((int*)p)[0] = realTYPE;
157 ((int*)p)[1] = 0xED0ED;
158 } while(!mps_commit(ap, p, size + headerSIZE));
159
160 return userP;
161}
162
163
164/* test -- the body of the test */
165
166static void *test(void *arg, size_t s)
167{
168 mps_arena_t arena;
169 mps_fmt_t format;
170 mps_chain_t chain;
171 mps_root_t exactRoot, ambigRoot, bogusRoot;
172 unsigned long objs; size_t i;
173 mps_word_t collections, rampSwitch;
174 mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp();
175 int ramping;
176 mps_ap_t busy_ap;
177 mps_addr_t busy_init;
178
179 arena = (mps_arena_t)arg;
180 (void)s; /* unused */
181
182 die(EnsureHeaderFormat(&format, arena), "fmt_create");
183 die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");
184
185 die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain),
186 "pool_create(amc)");
187
188 die(mps_ap_create(&ap, pool, MPS_RANK_EXACT), "BufferCreate");
189 die(mps_ap_create(&busy_ap, pool, MPS_RANK_EXACT), "BufferCreate 2");
190
191 for(i = 0; i < exactRootsCOUNT; ++i)
192 exactRoots[i] = objNULL;
193 for(i = 0; i < ambigRootsCOUNT; ++i)
194 ambigRoots[i] = (mps_addr_t)rnd();
195
196 die(mps_root_create_table_masked(&exactRoot, arena,
197 MPS_RANK_EXACT, (mps_rm_t)0,
198 &exactRoots[0], exactRootsCOUNT,
199 (mps_word_t)1),
200 "root_create_table(exact)");
201 die(mps_root_create_table(&ambigRoot, arena,
202 MPS_RANK_AMBIG, (mps_rm_t)0,
203 &ambigRoots[0], ambigRootsCOUNT),
204 "root_create_table(ambig)");
205 die(mps_root_create_table(&bogusRoot, arena,
206 MPS_RANK_AMBIG, (mps_rm_t)0,
207 &bogusRoots[0], bogusRootsCOUNT),
208 "root_create_table(bogus)");
209
210 /* create an ap, and leave it busy */
211 die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy");
212
213 collections = 0;
214 rampSwitch = rampSIZE;
215 mps_ap_alloc_pattern_begin(ap, ramp);
216 mps_ap_alloc_pattern_begin(busy_ap, ramp);
217 ramping = 1;
218 objs = 0;
219 while(collections < collectionsCOUNT) {
220 unsigned long c;
221 size_t r;
222
223 c = mps_collections(arena);
224
225 if (collections != c) {
226 collections = c;
227 printf("\nCollection %lu, %lu objects.\n", c, objs);
228 for(r = 0; r < exactRootsCOUNT; ++r) {
229 if (exactRoots[r] != objNULL)
230 die(HeaderFormatCheck(exactRoots[r]), "wrapper check");
231 }
232 if (collections == rampSwitch) {
233 rampSwitch += rampSIZE;
234 if (ramping) {
235 mps_ap_alloc_pattern_end(ap, ramp);
236 mps_ap_alloc_pattern_end(busy_ap, ramp);
237 /* kill half of the roots */
238 for(i = 0; i < exactRootsCOUNT; i += 2) {
239 if (exactRoots[i] != objNULL) {
240 die(HeaderFormatCheck(exactRoots[i]), "ramp kill check");
241 exactRoots[i] = objNULL;
242 }
243 }
244 /* Every other time, switch back immediately. */
245 if (collections & 1) ramping = 0;
246 }
247 if (!ramping) {
248 mps_ap_alloc_pattern_begin(ap, ramp);
249 mps_ap_alloc_pattern_begin(busy_ap, ramp);
250 ramping = 1;
251 }
252 }
253 /* fill bogusRoots with variations of a real pointer */
254 r = rnd() % exactRootsCOUNT;
255 if (exactRoots[i] != objNULL) {
256 char *p = (char*)exactRoots[i];
257
258 for(i = 0; i < bogusRootsCOUNT; ++i, ++p)
259 bogusRoots[i] = (mps_addr_t)p;
260 }
261 }
262
263 r = (size_t)rnd();
264 if (r & 1) {
265 i = (r >> 1) % exactRootsCOUNT;
266 if (exactRoots[i] != objNULL)
267 die(HeaderFormatCheck(exactRoots[i]), "wrapper check");
268 exactRoots[i] = make();
269 if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL)
270 dylan_write(exactRoots[(exactRootsCOUNT-1) - i],
271 exactRoots, exactRootsCOUNT);
272 } else {
273 i = (r >> 1) % ambigRootsCOUNT;
274 ambigRoots[(ambigRootsCOUNT-1) - i] = make();
275 /* Create random interior pointers */
276 ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1);
277 }
278
279 if (r % initTestFREQ == 0)
280 *(int*)busy_init = -1; /* check that the buffer is still there */
281
282 if (objs % 1024 == 0) {
283 putchar('.');
284 fflush(stdout);
285 }
286
287 ++objs;
288 }
289
290 (void)mps_commit(busy_ap, busy_init, 64);
291 mps_ap_destroy(busy_ap);
292 mps_ap_destroy(ap);
293 mps_root_destroy(exactRoot);
294 mps_root_destroy(ambigRoot);
295 mps_root_destroy(bogusRoot);
296 mps_pool_destroy(pool);
297 mps_chain_destroy(chain);
298 mps_fmt_destroy(format);
299
300 return NULL;
301}
302
303
304int main(int argc, char **argv)
305{
306 mps_arena_t arena;
307 mps_thr_t thread;
308 void *r;
309
310 randomize(argc, argv);
311
312 die(mps_arena_create(&arena, mps_arena_class_vm(), 3*testArenaSIZE),
313 "arena_create\n");
314 die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit");
315 die(mps_thread_reg(&thread, arena), "thread_reg");
316 mps_tramp(&r, test, arena, 0);
317 mps_thread_dereg(thread);
318 mps_arena_destroy(arena);
319
320 fflush(stdout); /* synchronize */
321 fprintf(stderr, "\nConclusion: Failed to find any defects.\n");
322 return 0;
323}