diff --git a/mps/qa/function/12.c b/mps/qa/function/12.c index 0d3d09de169..950e9a6eeb1 100644 --- a/mps/qa/function/12.c +++ b/mps/qa/function/12.c @@ -1,14 +1,43 @@ -/* test ** unfinished ** collection between reserve and commit, then midway thru commit +/* test lots of APs with interleaved reserve and 2-stage commit language c link testlib.o newfmt.o */ +/* + This test needs some explanation. The object 'cells' contains + NCELL references to other objects. NAPS allocation points + are created. At each step, we choose one and nudge it on + a little. Each allocation point goes through the following + cycle of steps: reserve, init, begin commit, end commit. + At the init step, each reference in the reserved object is + set to point randomly to one of the objects referenced by + cells or (with probability PNULL) to NULL. If commit fails, + the object is thrown away. If it succeeds, it is written into + a random reference in cells. Repeat. + + Because it has to deal directly with reserve and commit, + this test can't use the nice functions provided by newfmt + all the time. +*/ + #include "testlib.h" #include "mpscamc.h" #include "newfmt.h" void *stackpointer; +#define NCELLS 100 +#define NAPS 100 +#define PNULL (ranint(100)<25) +#define NUMREFS (ranint(20)) +#define BLAH 0 + +mps_ap_t ap[NAPS]; +mycell *p[NAPS]; +size_t s[NAPS]; +int nrefs[NAPS]; +int ap_state[NAPS]; + static void test(void) { mps_space_t space; @@ -17,12 +46,17 @@ static void test(void) mps_root_t root; mps_fmt_t format; - mps_ap_t apA; - mps_ap_t apB; + mycell *cells; - mps_addr_t p; + int h,i,j,k,l; + mycell *pobj; + size_t bytes; + size_t alignment; + mps_addr_t q; + int nextid = 1000000; - int i; +/* turn on comments about copying and scanning */ + formatcomments = BLAH; cdie(mps_space_create(&space), "create space"); @@ -37,49 +71,113 @@ static void test(void) mps_fmt_create_A(&format, space, &fmtA), "create format"); - formatcomments = 0; - cdie( mps_pool_create(&pool, space, mps_class_amc(), format), "create pool"); - cdie( - mps_ap_create(&apA, pool, MPS_RANK_EXACT), "create apA"); - - cdie( - mps_ap_create(&apB, pool, MPS_RANK_EXACT), "create apB"); - - - die(mps_reserve(&p, apA, MPS_PF_ALIGN), "Reserve: "); - - for (i=1; i<1000; i++) + for (i=0; iinit = apA->alloc; - - for (i=1; i<1000; i++) + for(h=0; h<100; h++) { - allocone(apB, 100); + comment("%i of 100", h); + + for(j=0; j<1000; j++) + { + i = ranint(NAPS); + + switch (ap_state[i]) + { + case 0: + nrefs[i] = NUMREFS; + bytes = offsetof(struct data, ref)+nrefs[i]*sizeof(struct refitem); + alignment = MPS_PF_ALIGN; + bytes = (bytes+alignment-1)&~(alignment-1); + s[i] = bytes; + die(mps_reserve(&q, ap[i], s[i]), "reserve: "); + p[i] = q; + p[i]->data.tag = 0xD033E2A6; + p[i]->data.id = nextid; + ap_state[i] = 1; + commentif(BLAH, "%i: reserve %li at %p", i, nextid, q); + nextid +=1; + break; + case 1: + commentif(BLAH, "%i: init %li", i, p[i]->data.id); + p[i]->data.tag = MCdata; + p[i]->data.numrefs = nrefs[i]; + p[i]->data.size = s[i]; + ap_state[i] = 2; + for (k=0; kdata.ref[k].addr = NULL; + p[i]->data.ref[k].id = 0; + } + else + { + l = ranint(NCELLS); + pobj = getref(cells, l); + p[i]->data.ref[k].addr = pobj; + p[i]->data.ref[k].id = (pobj==NULL ? 0 : pobj->data.id); + } + commentif(BLAH, " ref %i -> %li", k, p[i]->data.ref[k].id); + } + break; + case 2: + commentif(BLAH, "%i: begin commit %li", i, p[i]->data.id); + ap[i]->init = ap[i]->alloc; + ap_state[i] = 3; + break; + case 3: + commentif(BLAH, "%i: end commit %li", i, p[i]->data.id); + q=p[i]; + if (ap[i]->limit != 0 || mps_ap_trip(ap[i], p[i], s[i])) + { + l = ranint(NCELLS); + setref(cells, l, q); + commentif(BLAH, "%i -> %i", i, l); + } + ap_state[i] = 0; + break; + } + } + checkfrom(cells); } - apA->limit != 0 || mps_ap_trip(apA, p, MPS_PF_ALIGN); + commentif(BLAH, "Finished main loop"); -/* that's the end of commit! */ - - (void) mps_commit(apA, p, MPS_PF_ALIGN); - - mps_ap_destroy(apA); - comment("Destroyed apA."); - - mps_ap_destroy(apB); - comment("Destroyed apB."); + for (i=0; idata.tag = MCdata; + p[i]->data.numrefs = 0; + p[i]->data.size = s[i]; + case 2: + commentif(BLAH, "%i begin commit", i); + ap[i]->init = ap[i]->alloc; + case 3: + commentif(BLAH, "% end commit", i); + (void) (ap[i]->limit != 0 || mps_ap_trip(ap[i], p[i], s[i])); + } + mps_ap_destroy(ap[i]); + } mps_pool_destroy(pool); comment("Destroyed pool.");