diff options
| author | Nick Barnes | 2001-10-31 14:40:56 +0000 |
|---|---|---|
| committer | Nick Barnes | 2001-10-31 14:40:56 +0000 |
| commit | 7acfca905d76140f4cc0b09c9a12de237de364cd (patch) | |
| tree | 3ed8babfa3a73d30f29e08ca5d5adcda4ca4e826 /mps/code/amcss.c | |
| parent | b7ce4893f9902d57cd67ac9a92fa6c3d5a8fc833 (diff) | |
| download | emacs-7acfca905d76140f4cc0b09c9a12de237de364cd.tar.gz emacs-7acfca905d76140f4cc0b09c9a12de237de364cd.zip | |
Branch imports for masters.
Copied from Perforce
Change: 23678
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code/amcss.c')
| -rw-r--r-- | mps/code/amcss.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/mps/code/amcss.c b/mps/code/amcss.c new file mode 100644 index 00000000000..29ab71d2a5a --- /dev/null +++ b/mps/code/amcss.c | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | /* impl.c.amcss: POOL CLASS AMC STRESS TEST | ||
| 2 | * | ||
| 3 | * $HopeName: MMsrc!amcss.c(trunk.36) $ | ||
| 4 | * Copyright (C) 2001 Harlequin Limited. All rights reserved. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include "fmtdy.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 genCOUNT 2 | ||
| 26 | #define collectionsCOUNT 37 | ||
| 27 | #define rampSIZE 9 | ||
| 28 | #define initTestFREQ 6000 | ||
| 29 | |||
| 30 | /* testChain -- generation parameters for the test */ | ||
| 31 | |||
| 32 | static mps_gen_param_s testChain[genCOUNT] = { | ||
| 33 | { 150, 0.85 }, { 170, 0.45 } }; | ||
| 34 | |||
| 35 | |||
| 36 | /* objNULL needs to be odd so that it's ignored in exactRoots. */ | ||
| 37 | #define objNULL ((mps_addr_t)0xDECEA5ED) | ||
| 38 | |||
| 39 | static mps_pool_t pool; | ||
| 40 | static mps_ap_t ap; | ||
| 41 | static mps_addr_t exactRoots[exactRootsCOUNT]; | ||
| 42 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; | ||
| 43 | |||
| 44 | |||
| 45 | static mps_addr_t make(void) | ||
| 46 | { | ||
| 47 | size_t length = rnd() % (2*avLEN); | ||
| 48 | size_t size = (length+2) * sizeof(mps_word_t); | ||
| 49 | mps_addr_t p; | ||
| 50 | mps_res_t res; | ||
| 51 | |||
| 52 | do { | ||
| 53 | MPS_RESERVE_BLOCK(res, p, ap, size); | ||
| 54 | if(res) | ||
| 55 | die(res, "MPS_RESERVE_BLOCK"); | ||
| 56 | res = dylan_init(p, size, exactRoots, exactRootsCOUNT); | ||
| 57 | if(res) | ||
| 58 | die(res, "dylan_init"); | ||
| 59 | } while(!mps_commit(ap, p, size)); | ||
| 60 | |||
| 61 | return p; | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pol, | ||
| 66 | void *p, size_t s) | ||
| 67 | { | ||
| 68 | testlib_unused(object); testlib_unused(fmt); testlib_unused(pol); | ||
| 69 | testlib_unused(s); | ||
| 70 | (*(unsigned long *)p)++; | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | /* test -- the body of the test */ | ||
| 75 | |||
| 76 | static void *test(void *arg, size_t s) | ||
| 77 | { | ||
| 78 | mps_arena_t arena; | ||
| 79 | mps_fmt_t format; | ||
| 80 | mps_chain_t chain; | ||
| 81 | mps_root_t exactRoot, ambigRoot; | ||
| 82 | unsigned long objs; size_t i; | ||
| 83 | mps_word_t collections, rampSwitch; | ||
| 84 | mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp(); | ||
| 85 | int ramping; | ||
| 86 | mps_ap_t busy_ap; | ||
| 87 | mps_addr_t busy_init; | ||
| 88 | |||
| 89 | arena = (mps_arena_t)arg; | ||
| 90 | (void)s; /* unused */ | ||
| 91 | |||
| 92 | die(dylan_fmt(&format, arena), "fmt_create"); | ||
| 93 | die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); | ||
| 94 | |||
| 95 | die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain), | ||
| 96 | "pool_create(amc)"); | ||
| 97 | |||
| 98 | die(mps_ap_create(&ap, pool, MPS_RANK_EXACT), "BufferCreate"); | ||
| 99 | die(mps_ap_create(&busy_ap, pool, MPS_RANK_EXACT), "BufferCreate 2"); | ||
| 100 | |||
| 101 | for(i = 0; i < exactRootsCOUNT; ++i) | ||
| 102 | exactRoots[i] = objNULL; | ||
| 103 | for(i = 0; i < ambigRootsCOUNT; ++i) | ||
| 104 | ambigRoots[i] = (mps_addr_t)rnd(); | ||
| 105 | |||
| 106 | die(mps_root_create_table_masked(&exactRoot, arena, | ||
| 107 | MPS_RANK_EXACT, (mps_rm_t)0, | ||
| 108 | &exactRoots[0], exactRootsCOUNT, | ||
| 109 | (mps_word_t)1), | ||
| 110 | "root_create_table(exact)"); | ||
| 111 | die(mps_root_create_table(&ambigRoot, arena, | ||
| 112 | MPS_RANK_AMBIG, (mps_rm_t)0, | ||
| 113 | &ambigRoots[0], ambigRootsCOUNT), | ||
| 114 | "root_create_table(ambig)"); | ||
| 115 | |||
| 116 | /* create an ap, and leave it busy */ | ||
| 117 | die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy"); | ||
| 118 | |||
| 119 | collections = 0; | ||
| 120 | rampSwitch = rampSIZE; | ||
| 121 | mps_ap_alloc_pattern_begin(ap, ramp); | ||
| 122 | mps_ap_alloc_pattern_begin(busy_ap, ramp); | ||
| 123 | ramping = 1; | ||
| 124 | objs = 0; | ||
| 125 | while(collections < collectionsCOUNT) { | ||
| 126 | unsigned long c; | ||
| 127 | size_t r; | ||
| 128 | |||
| 129 | c = mps_collections(arena); | ||
| 130 | |||
| 131 | if(collections != c) { | ||
| 132 | collections = c; | ||
| 133 | printf("\nCollection %lu, %lu objects.\n", | ||
| 134 | c, objs); | ||
| 135 | for(r = 0; r < exactRootsCOUNT; ++r) | ||
| 136 | cdie(exactRoots[r] == objNULL || dylan_check(exactRoots[r]), | ||
| 137 | "all roots check"); | ||
| 138 | if(collections == collectionsCOUNT / 2) { | ||
| 139 | unsigned long object_count = 0; | ||
| 140 | mps_arena_park(arena); | ||
| 141 | mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0); | ||
| 142 | mps_arena_release(arena); | ||
| 143 | printf("stepped on %lu objects.\n", object_count); | ||
| 144 | } | ||
| 145 | if(collections == rampSwitch) { | ||
| 146 | rampSwitch += rampSIZE; | ||
| 147 | if(ramping) { | ||
| 148 | mps_ap_alloc_pattern_end(ap, ramp); | ||
| 149 | mps_ap_alloc_pattern_end(busy_ap, ramp); | ||
| 150 | /* kill half of the roots */ | ||
| 151 | for(i = 0; i < exactRootsCOUNT; i += 2) { | ||
| 152 | if(exactRoots[i] != objNULL) { | ||
| 153 | cdie(dylan_check(exactRoots[i]), "ramp kill check"); | ||
| 154 | exactRoots[i] = objNULL; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | /* Every other time, switch back immediately. */ | ||
| 158 | if(collections & 1) ramping = 0; | ||
| 159 | } | ||
| 160 | if(!ramping) { | ||
| 161 | mps_ap_alloc_pattern_begin(ap, ramp); | ||
| 162 | mps_ap_alloc_pattern_begin(busy_ap, ramp); | ||
| 163 | ramping = 1; | ||
| 164 | } | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | r = (size_t)rnd(); | ||
| 169 | if(r & 1) { | ||
| 170 | i = (r >> 1) % exactRootsCOUNT; | ||
| 171 | if(exactRoots[i] != objNULL) | ||
| 172 | cdie(dylan_check(exactRoots[i]), "dying root check"); | ||
| 173 | exactRoots[i] = make(); | ||
| 174 | if(exactRoots[(exactRootsCOUNT-1) - i] != objNULL) | ||
| 175 | dylan_write(exactRoots[(exactRootsCOUNT-1) - i], | ||
| 176 | exactRoots, exactRootsCOUNT); | ||
| 177 | } else { | ||
| 178 | i = (r >> 1) % ambigRootsCOUNT; | ||
| 179 | ambigRoots[(ambigRootsCOUNT-1) - i] = make(); | ||
| 180 | /* Create random interior pointers */ | ||
| 181 | ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1); | ||
| 182 | } | ||
| 183 | |||
| 184 | if(r % initTestFREQ == 0) | ||
| 185 | *(int*)busy_init = -1; /* check that the buffer is still there */ | ||
| 186 | |||
| 187 | if(objs % 1024 == 0) { | ||
| 188 | putchar('.'); | ||
| 189 | fflush(stdout); | ||
| 190 | } | ||
| 191 | |||
| 192 | ++objs; | ||
| 193 | } | ||
| 194 | |||
| 195 | (void)mps_commit(busy_ap, busy_init, 64); | ||
| 196 | mps_ap_destroy(busy_ap); | ||
| 197 | mps_ap_destroy(ap); | ||
| 198 | mps_root_destroy(exactRoot); | ||
| 199 | mps_root_destroy(ambigRoot); | ||
| 200 | mps_pool_destroy(pool); | ||
| 201 | mps_chain_destroy(chain); | ||
| 202 | mps_fmt_destroy(format); | ||
| 203 | |||
| 204 | return NULL; | ||
| 205 | } | ||
| 206 | |||
| 207 | |||
| 208 | int main(int argc, char **argv) | ||
| 209 | { | ||
| 210 | mps_arena_t arena; | ||
| 211 | mps_thr_t thread; | ||
| 212 | void *r; | ||
| 213 | |||
| 214 | randomize(argc, argv); | ||
| 215 | |||
| 216 | die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE), | ||
| 217 | "arena_create"); | ||
| 218 | die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit"); | ||
| 219 | die(mps_thread_reg(&thread, arena), "thread_reg"); | ||
| 220 | mps_tramp(&r, test, arena, 0); | ||
| 221 | mps_thread_dereg(thread); | ||
| 222 | mps_arena_destroy(arena); | ||
| 223 | |||
| 224 | fflush(stdout); /* synchronize */ | ||
| 225 | fprintf(stderr, "\nConclusion: Failed to find any defects.\n"); | ||
| 226 | return 0; | ||
| 227 | } | ||