From 7bf1664f5e087c8e185b86192d4f7dc5ea883af7 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 3 Sep 2015 15:51:37 +0100 Subject: [PATCH] Separate the values "more work to do?" and "amount of work done" in tracepoll. previously, the code used "amount of work done > 0" when it needed "more work to do?" but that's not right, because on the last two calls to traceadvance, no "work" is done (because reclaim work is not measured), but there may still be more work to do. Copied from Perforce Change: 188218 ServerID: perforce.ravenbrook.com --- mps/code/eventdef.h | 2 +- mps/code/global.c | 35 ++++++++++++++++------------------- mps/code/mpm.h | 4 ++-- mps/code/policy.c | 10 +++++----- mps/code/trace.c | 11 +++++++---- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/mps/code/eventdef.h b/mps/code/eventdef.h index 225c21f5f65..cb7b590274c 100644 --- a/mps/code/eventdef.h +++ b/mps/code/eventdef.h @@ -655,7 +655,7 @@ #define EVENT_ArenaPoll_PARAMS(PARAM, X) \ PARAM(X, 0, P, arena) \ PARAM(X, 1, W, start) \ - PARAM(X, 2, W, quanta) + PARAM(X, 2, B, workWasDone) #define EVENT_ArenaSetEmergency_PARAMS(PARAM, X) \ PARAM(X, 0, P, arena) \ diff --git a/mps/code/global.c b/mps/code/global.c index d15e5cd0da7..d9a5bf9c6c7 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -704,7 +704,7 @@ void (ArenaPoll)(Globals globals) { Arena arena; Clock start; - Count quanta; + Bool moreWork, workWasDone = FALSE; Work tracedWork; AVERT(Globals, globals); @@ -721,25 +721,24 @@ void (ArenaPoll)(Globals globals) /* fillMutatorSize has advanced; call TracePoll enough to catch up. */ start = ClockNow(); - quanta = 0; - EVENT3(ArenaPoll, arena, start, 0); + EVENT3(ArenaPoll, arena, start, FALSE); do { - tracedWork = TracePoll(globals); - if (tracedWork > 0) { - quanta += 1; + moreWork = TracePoll(&tracedWork, globals); + if (moreWork) { + workWasDone = TRUE; } - } while (PolicyPollAgain(arena, start, tracedWork)); + } while (PolicyPollAgain(arena, moreWork, tracedWork)); /* Don't count time spent checking for work, if there was no work to do. */ - if(quanta > 0) { + if (workWasDone) { ArenaAccumulateTime(arena, start); } AVER(!PolicyPoll(arena)); - EVENT3(ArenaPoll, arena, start, quanta); + EVENT3(ArenaPoll, arena, start, BOOLOF(workWasDone)); globals->insidePoll = FALSE; } @@ -780,7 +779,7 @@ static Bool arenaShouldCollectWorld(Arena arena, Bool ArenaStep(Globals globals, double interval, double multiplier) { Work work; - Bool stepped; + Bool moreWork, workWasDone = FALSE; Clock start, end, now; Clock clocks_per_sec; Arena arena; @@ -796,8 +795,6 @@ Bool ArenaStep(Globals globals, double interval, double multiplier) end = start + (Clock)(interval * clocks_per_sec); AVER(end >= start); - stepped = FALSE; - if (arenaShouldCollectWorld(arena, interval, multiplier, start, clocks_per_sec)) { @@ -806,24 +803,24 @@ Bool ArenaStep(Globals globals, double interval, double multiplier) res = TraceStartCollectAll(&trace, arena, TraceStartWhyOPPORTUNISM); if (res == ResOK) { arena->lastWorldCollect = start; - stepped = TRUE; + workWasDone = TRUE; } } /* loop while there is work to do and time on the clock. */ do { - work = TracePoll(globals); + moreWork = TracePoll(&work, globals); now = ClockNow(); - if (work > 0) { - stepped = TRUE; + if (moreWork) { + workWasDone = TRUE; } - } while ((work > 0) && (now < end)); + } while (moreWork && now < end); - if (stepped) { + if (workWasDone) { ArenaAccumulateTime(arena, start); } - return stepped; + return workWasDone; } /* ArenaFinalize -- registers an object for finalization diff --git a/mps/code/mpm.h b/mps/code/mpm.h index 3e888ad28de..ad8620b800f 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -399,7 +399,7 @@ extern void TraceDestroyFinished(Trace trace); extern Res TraceAddWhite(Trace trace, Seg seg); extern Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet); extern Res TraceStart(Trace trace, double mortality, double finishingTime); -extern Work TracePoll(Globals globals); +extern Bool TracePoll(Work *workReturn, Globals globals); extern Rank TraceRankForAccess(Arena arena, Seg seg); extern void TraceSegAccess(Arena arena, Seg seg, AccessSet mode); @@ -667,7 +667,7 @@ extern Res PolicyAlloc(Tract *tractReturn, Arena arena, LocusPref pref, extern Bool PolicyStartTrace(Trace *traceReturn, Arena arena); extern double PolicyCollectionTime(Arena arena); extern Bool PolicyPoll(Arena arena); -extern Bool PolicyPollAgain(Arena arena, Clock start, Work tracedWork); +extern Bool PolicyPollAgain(Arena arena, Bool moreWork, Work tracedWork); /* Locus interface */ diff --git a/mps/code/policy.c b/mps/code/policy.c index e3c09c8d6d7..77f91ebacd0 100644 --- a/mps/code/policy.c +++ b/mps/code/policy.c @@ -309,20 +309,20 @@ Bool PolicyPoll(Arena arena) * should return to the mutator. * * start is the clock time when the MPS was entered. - * tracedWork is the amount of work done by the last call to TracePoll. + * moreWork and tracedWork are the results of the last call to TracePoll. */ -Bool PolicyPollAgain(Arena arena, Clock start, Work tracedWork) +Bool PolicyPollAgain(Arena arena, Bool moreWork, Work tracedWork) { Globals globals; double nextPollThreshold; AVERT(Arena, arena); globals = ArenaGlobals(arena); - UNUSED(start); + UNUSED(tracedWork); - if (tracedWork == 0) { - /* No work was done. Sleep until NOW + a bit. */ + if (!moreWork) { + /* No more work to do. Sleep until NOW + a bit. */ nextPollThreshold = globals->fillMutatorSize + ArenaPollALLOCTIME; } else { /* We did one quantum of work; consume one unit of 'time'. */ diff --git a/mps/code/trace.c b/mps/code/trace.c index 378b6bed9a1..47bd74b8283 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -1846,10 +1846,12 @@ Res TraceStartCollectAll(Trace *traceReturn, Arena arena, int why) /* TracePoll -- Check if there's any tracing work to be done * * Consider starting a trace if none is running; advance the running - * trace (if any) by one quantum. Return a measure of the work done. + * trace (if any) by one quantum. If there may be more work to do, + * update *workReturn with a measure of the work done and return TRUE. + * Otherwise return FALSE. */ -Work TracePoll(Globals globals) +Bool TracePoll(Work *workReturn, Globals globals) { Trace trace; Arena arena; @@ -1863,7 +1865,7 @@ Work TracePoll(Globals globals) } else { /* No traces are running: consider starting one now. */ if (!PolicyStartTrace(&trace, arena)) - return (Size)0; + return FALSE; } AVER(arena->busyTraces == TraceSetSingle(trace)); @@ -1877,7 +1879,8 @@ Work TracePoll(Globals globals) work = newWork - oldWork; if (trace->state == TraceFINISHED) TraceDestroyFinished(trace); - return work; + *workReturn = work; + return TRUE; }