diff --git a/mps/src/amcsshe.c b/mps/src/amcsshe.c new file mode 100644 index 00000000000..92b136469c4 --- /dev/null +++ b/mps/src/amcsshe.c @@ -0,0 +1,288 @@ +/* impl.c.amcsshe: POOL CLASS AMC STRESS TEST WITH HEADER + * + * $HopeName$ + * Copyright (C) 2000 Harlequin Limited. All rights reserved. + */ + +#include "fmthe.h" +#include "testlib.h" + +#include "mpscamc.h" +#include "mpsavm.h" +#include "mpstd.h" +#ifdef MPS_OS_W3 +#include "mpsw3.h" +#endif +#include "mps.h" + +#include +#include +#include + + +#define testArenaSIZE ((size_t)64<<20) +#define avLEN 3 +#define exactRootsCOUNT 300 +#define ambigRootsCOUNT 50 +#define collectionsCOUNT 18 +#define rampSIZE 5 +#define initTestFREQ 6000 +/* objNULL needs to be odd so that it's ignored in exactRoots. */ +#define objNULL ((mps_addr_t)0xDECEA5ED) + + +static mps_pool_t pool; +static mps_ap_t ap; +static mps_addr_t exactRoots[exactRootsCOUNT]; +static mps_addr_t ambigRoots[ambigRootsCOUNT]; + + + +static mps_word_t *ww = NULL; +static mps_word_t *tvw; + + +static mps_word_t dylan_make_WV(mps_word_t version, mps_word_t vb, + mps_word_t es, mps_word_t vf) +{ + /* VERSION- ... VB------ reserved ES---VF- */ + return((version << (MPS_WORD_WIDTH - 8)) | + (vb << 16) | + (es << 3) | + vf); +} + + +static mps_res_t init(mps_addr_t addr, size_t size, + mps_addr_t *refs, size_t nr_refs) +{ + + /* Make sure the size is aligned. */ + if ((size & (ALIGN-1)) != 0) return MPS_RES_PARAM; + + if(ww == NULL) { + ww = malloc(sizeof(mps_word_t) * (BASIC_WRAPPER_SIZE + 1)); + if(ww == NULL) return MPS_RES_MEMORY; + tvw = malloc(sizeof(mps_word_t) * BASIC_WRAPPER_SIZE); + if(tvw == NULL) { + free(ww); + return MPS_RES_MEMORY; + } + + /* Build a wrapper wrapper. */ + ww[WW] = (mps_word_t)ww; + ww[WC] = (mps_word_t)ww; /* dummy class */ + ww[WM] = (1 << 2) | 1; /* dummy subtype_mask */ + ww[WF] = ((WS - 1) << 2) | 2; + ww[WV] = dylan_make_WV(2, 0, 0, 0); + ww[WS] = (1 << 2) | 1; + ww[WP] = 1; + + /* Build a wrapper for traceable vectors. */ + tvw[WW] = (mps_word_t)ww; + tvw[WC] = (mps_word_t)ww; /* dummy class */ + tvw[WM] = (1 << 2) | 1; /* dummy subtype_mask */ + tvw[WF] = 0; /* no fixed part */ + tvw[WV] = dylan_make_WV(2, 0, 0, 2); /* traceable variable part */ + tvw[WS] = 1; /* no patterns */ + } + + /* If there is enough room, make a vector, otherwise just */ + /* make a padding object. */ + + if(size >= sizeof(mps_word_t) * 2) { + mps_word_t *p = (mps_word_t *)addr; + mps_word_t i, t = (size / sizeof(mps_word_t)) - 2; + + p[0] = (mps_word_t)tvw; /* install vector wrapper */ + p[1] = (t << 2) | 1; /* tag the vector length */ + for(i = 0; i < t; ++i) { + mps_word_t r = rnd(); + + if(r & 1) + p[2+i] = ((r & ~(mps_word_t)3) | 1); /* random int */ + else + p[2+i] = (mps_word_t)refs[(r >> 1) % nr_refs]; /* random ptr */ + } + } else { + die(MPS_RES_FAIL, "small object"); + } + + return MPS_RES_OK; +} + + +static void dylan_write(mps_addr_t addr, mps_addr_t *refs, size_t nr_refs) +{ + mps_word_t *p = (mps_word_t *)addr; + mps_word_t t = p[1] >> 2; + + /* If the object is a vector, update a random entry. */ + if(p[0] == (mps_word_t)tvw && t > 0) { + mps_word_t r = rnd(); + size_t i = 2 + (rnd() % t); + + if(r & 1) + p[i] = ((r & ~(mps_word_t)3) | 1); /* random int */ + else + p[i] = (mps_word_t)refs[(r >> 1) % nr_refs]; /* random ptr */ + } +} + + +static mps_addr_t make(void) +{ + size_t length = rnd() % (2*avLEN); + size_t size = (length+2) * sizeof(mps_word_t); + mps_addr_t p, userP; + mps_res_t res; + + do { + MPS_RESERVE_BLOCK(res, p, ap, size + headerSIZE); + if(res) + die(res, "MPS_RESERVE_BLOCK"); + userP = (mps_addr_t)((char*)p + headerSIZE); + res = init(userP, size, exactRoots, exactRootsCOUNT); + if(res) + die(res, "dylan_init"); + ((int*)p)[0] = realTYPE; + ((int*)p)[1] = 0xED0ED; + } while(!mps_commit(ap, p, size + headerSIZE)); + + return userP; +} + + +static void *test(void *arg, size_t s) +{ + mps_arena_t arena; + mps_fmt_t format; + mps_root_t exactRoot, ambigRoot; + unsigned long objs; size_t i; + mps_word_t collections, rampSwitch; + mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp(); + int ramping; + mps_ap_t busy_ap; + mps_addr_t busy_init; + + arena = (mps_arena_t)arg; + (void)s; /* unused */ + + die(EnsureHeaderFormat(&format, arena), "fmt_create"); + + die(mps_pool_create(&pool, arena, mps_class_amc(), format), + "pool_create(amc)"); + + die(mps_ap_create(&ap, pool, MPS_RANK_EXACT), "BufferCreate"); + die(mps_ap_create(&busy_ap, pool, MPS_RANK_EXACT), "BufferCreate"); + + for(i=0; i> 1) % exactRootsCOUNT; + if(exactRoots[i] != objNULL) + die(HeaderFormatCheck(exactRoots[i]), "wrapper check"); + exactRoots[i] = make(); + if(exactRoots[(exactRootsCOUNT-1) - i] != objNULL) + dylan_write(exactRoots[(exactRootsCOUNT-1) - i], + exactRoots, exactRootsCOUNT); + } else { + i = (r >> 1) % ambigRootsCOUNT; + ambigRoots[(ambigRootsCOUNT-1) - i] = make(); + /* Create random interior pointers */ + ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1); + } + + if(r % initTestFREQ == 0) + *(int*)busy_init = -1; /* check that the buffer is still there */ + + if(objs % 1024 == 0) { + putchar('.'); + fflush(stdout); + } + + ++objs; + } + + (void)mps_commit(busy_ap, busy_init, 64); + mps_ap_destroy(busy_ap); + mps_ap_destroy(ap); + mps_root_destroy(exactRoot); + mps_root_destroy(ambigRoot); + mps_pool_destroy(pool); + mps_fmt_destroy(format); + + return NULL; +} + + +int main(void) +{ + mps_arena_t arena; + mps_thr_t thread; + void *r; + + die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), + "arena_create\n"); + adjust_collection_freq(0.0); + die(mps_thread_reg(&thread, arena), "thread_reg"); + mps_tramp(&r, test, arena, 0); + mps_thread_dereg(thread); + mps_arena_destroy(arena); + + fflush(stdout); /* synchronize */ + fprintf(stderr, "\nConclusion: Failed to find any defects.\n"); + return 0; +}