From 33aeb61e5927bdc538ca953b81f82915eaecbb52 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 13 Oct 2014 21:57:41 +0100 Subject: [PATCH 1/6] Branching master to branch/2014-10-13/format. Copied from Perforce Change: 187249 ServerID: perforce.ravenbrook.com From f65f1db83e44fe5b0f8e8bae0df0c05d52a53e2c Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 13 Oct 2014 22:44:20 +0100 Subject: [PATCH 2/6] Attach the pools using a format to a ring in the format, so that when we destroy the format, we can check that no pools are using it. Copied from Perforce Change: 187253 ServerID: perforce.ravenbrook.com --- mps/code/format.c | 4 ++++ mps/code/mpmst.h | 2 ++ mps/code/pool.c | 8 +++++++- mps/code/poolamc.c | 1 + mps/code/poolams.c | 1 + mps/code/poolawl.c | 1 + mps/code/poollo.c | 1 + mps/code/poolsnc.c | 1 + mps/test/conerr/12.c | 4 ++++ 9 files changed, 22 insertions(+), 1 deletion(-) diff --git a/mps/code/format.c b/mps/code/format.c index 763682a0a50..fc369f6a4ba 100644 --- a/mps/code/format.c +++ b/mps/code/format.c @@ -22,6 +22,7 @@ Bool FormatCheck(Format format) CHECKU(Arena, format->arena); CHECKL(format->serial < format->arena->formatSerial); CHECKD_NOSIG(Ring, &format->arenaRing); + CHECKD_NOSIG(Ring, &format->poolRing); CHECKL(AlignCheck(format->alignment)); /* TODO: Define the concept of the maximum alignment it is possible to request from the MPS, document and provide an interface to it, and then @@ -141,6 +142,7 @@ Res FormatCreate(Format *formatReturn, Arena arena, ArgList args) format->arena = arena; RingInit(&format->arenaRing); + RingInit(&format->poolRing); format->alignment = fmtAlign; format->headerSize = fmtHeaderSize; format->scan = fmtScan; @@ -168,12 +170,14 @@ Res FormatCreate(Format *formatReturn, Arena arena, ArgList args) void FormatDestroy(Format format) { AVERT(Format, format); + AVER(RingIsSingle(&format->poolRing)); RingRemove(&format->arenaRing); format->sig = SigInvalid; RingFinish(&format->arenaRing); + RingFinish(&format->poolRing); ControlFree(format->arena, format, sizeof(FormatStruct)); } diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index ac59492bea5..62d82d658ce 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -110,6 +110,7 @@ typedef struct mps_pool_s { /* generic structure */ RingStruct segRing; /* segs are attached to pool */ Align alignment; /* alignment for units */ Format format; /* format only if class->attr&AttrFMT */ + RingStruct formatRing; /* link in list of pools using format */ PoolFixMethod fix; /* fix method */ double fillMutatorSize; /* bytes filled, mutator buffers */ double emptyMutatorSize; /* bytes emptied, mutator buffers */ @@ -410,6 +411,7 @@ typedef struct mps_fmt_s { Serial serial; /* from arena->formatSerial */ Arena arena; /* owning arena */ RingStruct arenaRing; /* formats are attached to the arena */ + RingStruct poolRing; /* ring of pools using the format */ Align alignment; /* alignment of formatted objects */ mps_fmt_scan_t scan; mps_fmt_skip_t skip; diff --git a/mps/code/pool.c b/mps/code/pool.c index bbdacc68616..05160aba216 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -153,6 +153,7 @@ Res PoolInit(Pool pool, Arena arena, PoolClass class, ArgList args) RingInit(&pool->arenaRing); RingInit(&pool->bufferRing); RingInit(&pool->segRing); + RingInit(&pool->formatRing); pool->bufferSerial = (Serial)0; pool->alignment = MPS_PF_ALIGN; pool->format = NULL; @@ -181,6 +182,7 @@ Res PoolInit(Pool pool, Arena arena, PoolClass class, ArgList args) failInit: pool->sig = SigInvalid; /* Leave arena->poolSerial incremented */ + RingFinish(&pool->formatRing); RingFinish(&pool->segRing); RingFinish(&pool->bufferRing); RingFinish(&pool->arenaRing); @@ -237,10 +239,14 @@ void PoolFinish(Pool pool) /* Do any class-specific finishing. */ (*pool->class->finish)(pool); - /* Detach the pool from the arena, and unsig it. */ + /* Detach the pool from the arena and format, and unsig it. */ RingRemove(&pool->arenaRing); + if (pool->format) { + RingRemove(&pool->formatRing); + } pool->sig = SigInvalid; + RingFinish(&pool->formatRing); RingFinish(&pool->segRing); RingFinish(&pool->bufferRing); RingFinish(&pool->arenaRing); diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index 4e9ed70396d..34d9ee568c3 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -832,6 +832,7 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) ArgRequire(&arg, args, MPS_KEY_FORMAT); pool->format = arg.val.format; + RingAppend(&pool->format->poolRing, &pool->formatRing); if (ArgPick(&arg, args, MPS_KEY_CHAIN)) chain = arg.val.chain; else diff --git a/mps/code/poolams.c b/mps/code/poolams.c index bbb6d70e96a..f94695ad1ef 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -838,6 +838,7 @@ Res AMSInitInternal(AMS ams, Format format, Chain chain, unsigned gen, pool = AMSPool(ams); AVERT(Pool, pool); pool->format = format; + RingAppend(&format->poolRing, &pool->formatRing); pool->alignment = pool->format->alignment; ams->grainShift = SizeLog2(PoolAlignment(pool)); diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 0ab42f36e27..2abbdb06680 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -576,6 +576,7 @@ static Res AWLInit(Pool pool, ArgList args) AVERT(Format, format); pool->format = format; + RingAppend(&format->poolRing, &pool->formatRing); pool->alignment = format->alignment; AVER(FUNCHECK(findDependent)); diff --git a/mps/code/poollo.c b/mps/code/poollo.c index 5b3ddd608f9..55e7104448c 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -494,6 +494,7 @@ static Res LOInit(Pool pool, ArgList args) ArgRequire(&arg, args, MPS_KEY_FORMAT); pool->format = arg.val.format; + RingAppend(&pool->format->poolRing, &pool->formatRing); if (ArgPick(&arg, args, MPS_KEY_CHAIN)) chain = arg.val.chain; else { diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index df2d964340b..c56ce9f74c8 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c @@ -388,6 +388,7 @@ static Res SNCInit(Pool pool, ArgList args) AVERT(Format, format); pool->format = format; + RingAppend(&format->poolRing, &pool->formatRing); snc->freeSegs = NULL; snc->sig = SNCSig; diff --git a/mps/test/conerr/12.c b/mps/test/conerr/12.c index a8f932114ab..f904f1e3267 100644 --- a/mps/test/conerr/12.c +++ b/mps/test/conerr/12.c @@ -4,6 +4,10 @@ TEST_HEADER summary = destroy a format though attached to a pool language = c link = testlib.o +OUTPUT_SPEC + assert = true + assertfile P= format.c + assertcond = RingIsSingle(&format->poolRing) END_HEADER */ From ae805ce16e4a9545b4a1e40c83776ea4ceef61ed Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 14 Oct 2014 10:07:41 +0100 Subject: [PATCH 3/6] Simpler and more robust to add the pool to the formatring in poolinit, after we know that the initialization has succeeded. Copied from Perforce Change: 187261 ServerID: perforce.ravenbrook.com --- mps/code/pool.c | 5 +++++ mps/code/poolamc.c | 1 - mps/code/poolams.c | 1 - mps/code/poolawl.c | 1 - mps/code/poollo.c | 1 - mps/code/poolsnc.c | 1 - 6 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mps/code/pool.c b/mps/code/pool.c index 05160aba216..96f853eb94b 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -178,6 +178,11 @@ Res PoolInit(Pool pool, Arena arena, PoolClass class, ArgList args) /* Add initialized pool to list of pools in arena. */ RingAppend(&globals->poolRing, &pool->arenaRing); + /* Add initialized pool to list of pools using format. */ + if (pool->format) { + RingAppend(&pool->format->poolRing, &pool->formatRing); + } + return ResOK; failInit: diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index 34d9ee568c3..4e9ed70396d 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -832,7 +832,6 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) ArgRequire(&arg, args, MPS_KEY_FORMAT); pool->format = arg.val.format; - RingAppend(&pool->format->poolRing, &pool->formatRing); if (ArgPick(&arg, args, MPS_KEY_CHAIN)) chain = arg.val.chain; else diff --git a/mps/code/poolams.c b/mps/code/poolams.c index f94695ad1ef..bbb6d70e96a 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -838,7 +838,6 @@ Res AMSInitInternal(AMS ams, Format format, Chain chain, unsigned gen, pool = AMSPool(ams); AVERT(Pool, pool); pool->format = format; - RingAppend(&format->poolRing, &pool->formatRing); pool->alignment = pool->format->alignment; ams->grainShift = SizeLog2(PoolAlignment(pool)); diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 2abbdb06680..0ab42f36e27 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -576,7 +576,6 @@ static Res AWLInit(Pool pool, ArgList args) AVERT(Format, format); pool->format = format; - RingAppend(&format->poolRing, &pool->formatRing); pool->alignment = format->alignment; AVER(FUNCHECK(findDependent)); diff --git a/mps/code/poollo.c b/mps/code/poollo.c index 55e7104448c..5b3ddd608f9 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -494,7 +494,6 @@ static Res LOInit(Pool pool, ArgList args) ArgRequire(&arg, args, MPS_KEY_FORMAT); pool->format = arg.val.format; - RingAppend(&pool->format->poolRing, &pool->formatRing); if (ArgPick(&arg, args, MPS_KEY_CHAIN)) chain = arg.val.chain; else { diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index c56ce9f74c8..df2d964340b 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c @@ -388,7 +388,6 @@ static Res SNCInit(Pool pool, ArgList args) AVERT(Format, format); pool->format = format; - RingAppend(&format->poolRing, &pool->formatRing); snc->freeSegs = NULL; snc->sig = SNCSig; From 4ce030ad1305fcbcd82124ae47b89c547120bc6e Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 16 Oct 2014 22:59:00 +0100 Subject: [PATCH 4/6] Use a reference count to discover cases where a format is deleted when a pool is still using it, as suggested by rb . Copied from Perforce Change: 187279 ServerID: perforce.ravenbrook.com --- mps/code/format.c | 6 ++---- mps/code/mpmst.h | 3 +-- mps/code/pool.c | 8 +++----- mps/test/conerr/12.c | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/mps/code/format.c b/mps/code/format.c index fc369f6a4ba..69e7ff1ddbe 100644 --- a/mps/code/format.c +++ b/mps/code/format.c @@ -22,7 +22,6 @@ Bool FormatCheck(Format format) CHECKU(Arena, format->arena); CHECKL(format->serial < format->arena->formatSerial); CHECKD_NOSIG(Ring, &format->arenaRing); - CHECKD_NOSIG(Ring, &format->poolRing); CHECKL(AlignCheck(format->alignment)); /* TODO: Define the concept of the maximum alignment it is possible to request from the MPS, document and provide an interface to it, and then @@ -142,7 +141,7 @@ Res FormatCreate(Format *formatReturn, Arena arena, ArgList args) format->arena = arena; RingInit(&format->arenaRing); - RingInit(&format->poolRing); + format->poolCount = 0; format->alignment = fmtAlign; format->headerSize = fmtHeaderSize; format->scan = fmtScan; @@ -170,14 +169,13 @@ Res FormatCreate(Format *formatReturn, Arena arena, ArgList args) void FormatDestroy(Format format) { AVERT(Format, format); - AVER(RingIsSingle(&format->poolRing)); + AVER(format->poolCount == 0); RingRemove(&format->arenaRing); format->sig = SigInvalid; RingFinish(&format->arenaRing); - RingFinish(&format->poolRing); ControlFree(format->arena, format, sizeof(FormatStruct)); } diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index 62d82d658ce..2885f193d31 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -110,7 +110,6 @@ typedef struct mps_pool_s { /* generic structure */ RingStruct segRing; /* segs are attached to pool */ Align alignment; /* alignment for units */ Format format; /* format only if class->attr&AttrFMT */ - RingStruct formatRing; /* link in list of pools using format */ PoolFixMethod fix; /* fix method */ double fillMutatorSize; /* bytes filled, mutator buffers */ double emptyMutatorSize; /* bytes emptied, mutator buffers */ @@ -411,7 +410,7 @@ typedef struct mps_fmt_s { Serial serial; /* from arena->formatSerial */ Arena arena; /* owning arena */ RingStruct arenaRing; /* formats are attached to the arena */ - RingStruct poolRing; /* ring of pools using the format */ + Count poolCount; /* number of pools using the format */ Align alignment; /* alignment of formatted objects */ mps_fmt_scan_t scan; mps_fmt_skip_t skip; diff --git a/mps/code/pool.c b/mps/code/pool.c index 96f853eb94b..2e59c08a69a 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -153,7 +153,6 @@ Res PoolInit(Pool pool, Arena arena, PoolClass class, ArgList args) RingInit(&pool->arenaRing); RingInit(&pool->bufferRing); RingInit(&pool->segRing); - RingInit(&pool->formatRing); pool->bufferSerial = (Serial)0; pool->alignment = MPS_PF_ALIGN; pool->format = NULL; @@ -180,14 +179,13 @@ Res PoolInit(Pool pool, Arena arena, PoolClass class, ArgList args) /* Add initialized pool to list of pools using format. */ if (pool->format) { - RingAppend(&pool->format->poolRing, &pool->formatRing); + ++ pool->format->poolCount; } return ResOK; failInit: pool->sig = SigInvalid; /* Leave arena->poolSerial incremented */ - RingFinish(&pool->formatRing); RingFinish(&pool->segRing); RingFinish(&pool->bufferRing); RingFinish(&pool->arenaRing); @@ -247,11 +245,11 @@ void PoolFinish(Pool pool) /* Detach the pool from the arena and format, and unsig it. */ RingRemove(&pool->arenaRing); if (pool->format) { - RingRemove(&pool->formatRing); + AVER(pool->format->poolCount > 0); + -- pool->format->poolCount; } pool->sig = SigInvalid; - RingFinish(&pool->formatRing); RingFinish(&pool->segRing); RingFinish(&pool->bufferRing); RingFinish(&pool->arenaRing); diff --git a/mps/test/conerr/12.c b/mps/test/conerr/12.c index f904f1e3267..139abce195b 100644 --- a/mps/test/conerr/12.c +++ b/mps/test/conerr/12.c @@ -7,7 +7,7 @@ TEST_HEADER OUTPUT_SPEC assert = true assertfile P= format.c - assertcond = RingIsSingle(&format->poolRing) + assertcond = format->poolCount == 0 END_HEADER */ From b1ab5ec2dcbe615c3750ea61e26796c2ea030e40 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 25 Oct 2014 19:45:48 +0100 Subject: [PATCH 5/6] Add poolcount to formatdescribe. Copied from Perforce Change: 187396 ServerID: perforce.ravenbrook.com --- mps/code/format.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mps/code/format.c b/mps/code/format.c index 69e7ff1ddbe..da6c33d19a8 100644 --- a/mps/code/format.c +++ b/mps/code/format.c @@ -203,6 +203,7 @@ Res FormatDescribe(Format format, mps_lib_FILE *stream, Count depth) "Format $P ($U) {\n", (WriteFP)format, (WriteFU)format->serial, " arena $P ($U)\n", (WriteFP)format->arena, (WriteFU)format->arena->serial, + " poolCount $U\n", (WriteFU)format->poolCount, " alignment $W\n", (WriteFW)format->alignment, " scan $F\n", (WriteFF)format->scan, " skip $F\n", (WriteFF)format->skip, From 684126cebf34c599179be094b72bbbf4904a71d8 Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Tue, 15 Mar 2016 13:02:40 +0000 Subject: [PATCH 6/6] Updates from review by dl . Copied from Perforce Change: 190105 ServerID: perforce.ravenbrook.com --- mps/code/eventdef.h | 2 +- mps/code/mps.h | 2 ++ mps/code/mpsi.c | 2 +- mps/manual/source/topic/telemetry.rst | 16 ++++++++-------- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/mps/code/eventdef.h b/mps/code/eventdef.h index 0586d432680..5219bd2296a 100644 --- a/mps/code/eventdef.h +++ b/mps/code/eventdef.h @@ -36,7 +36,7 @@ */ #define EVENT_VERSION_MAJOR ((unsigned)1) -#define EVENT_VERSION_MEDIAN ((unsigned)4) +#define EVENT_VERSION_MEDIAN ((unsigned)5) #define EVENT_VERSION_MINOR ((unsigned)0) diff --git a/mps/code/mps.h b/mps/code/mps.h index ccb1173fb42..644868d6238 100644 --- a/mps/code/mps.h +++ b/mps/code/mps.h @@ -527,6 +527,8 @@ extern mps_res_t (mps_reserve)(mps_addr_t *, mps_ap_t, size_t); extern mps_bool_t (mps_commit)(mps_ap_t, mps_addr_t, size_t); extern mps_res_t mps_ap_fill(mps_addr_t *, mps_ap_t, size_t); + +/* mps_ap_fill_with_reservoir_permit is deprecated */ extern mps_res_t mps_ap_fill_with_reservoir_permit(mps_addr_t *, mps_ap_t, size_t); diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c index 5bebe0a55b0..a8a47447cbb 100644 --- a/mps/code/mpsi.c +++ b/mps/code/mpsi.c @@ -1156,7 +1156,7 @@ mps_res_t mps_sac_fill(mps_addr_t *p_o, mps_sac_t mps_sac, size_t size, AVER(p_o != NULL); AVER(TESTT(SAC, sac)); arena = SACArena(sac); - UNUSED(has_reservoir_permit); /* FIXME */ + UNUSED(has_reservoir_permit); /* deprecated */ ArenaEnter(arena); diff --git a/mps/manual/source/topic/telemetry.rst b/mps/manual/source/topic/telemetry.rst index 0f107985c20..2c9136ce7da 100644 --- a/mps/manual/source/topic/telemetry.rst +++ b/mps/manual/source/topic/telemetry.rst @@ -306,14 +306,14 @@ takes the following options: For example, here's the result of passing the output shown above through :program:`mpseventtxt`:: - 000AE03973336E3C 002B VMCreate vm:00000001003FC000 base:00000001003FD000 limit:00000001003FE000 - 000AE0397333BC6D 002D VMMap vm:00000001003FC000 base:00000001003FD000 limit:00000001003FE000 - 000AE0397334DF9F 001A Intern stringId:0000000000000002 string:"Reservoir" - 000AE0397334E0A0 001B Label address:00000001078C85B8["Reservoir"] stringId:0000000000000002 - 000AE03973352375 0015 PoolInit pool:00000001003FD328 arena:00000001003FD000 poolClass:00000001078C85B8["Reservoir"] - 000AE039733592F9 002B VMCreate vm:00000001003FE000 base:00000001003FF000 limit:000000010992F000 - 000AE0397335C8B5 002D VMMap vm:00000001003FE000 base:00000001003FF000 limit:0000000107930000 - 000AE03973361D5A 0005 ArenaCreateVM arena:00000001003FD000 userSize:0000000002000000 chunkSize:0000000002000000 + 000021C9DB3812C7 0075 EventClockSync clock:0000000000001EE3 + 000021C9DB39E2FB 002B VMInit vm:00007FFF5429C4B8 base:000000010BA4A000 limit:000000010BA4B000 + 000021C9DB3A5630 002D VMMap vm:00007FFF5429C4B8 base:000000010BA4A000 limit:000000010BA4B000 + 000021C9DB3E6BAA 001A Intern stringId:0000000000000002 string:"MFS" + 000021C9DB3E6E17 001B Label address:000000010BA0C5D8["MFS"] stringId:0000000000000002 + 000021C9DB3EB6F8 0044 PoolInitMFS pool:000000010BA4A360 arena:000000010BA4A000 extendBy:0000000000001000 extendSelf:False unitSize:0000000000000030 + 000021C9DB3EFE3B 002B VMInit vm:00007FFF5429C3D0 base:000000010BC84000 limit:000000010CC24000 + 000021C9DB3F33F3 002D VMMap vm:00007FFF5429C3D0 base:000000010BC84000 limit:000000010BC85000 .. index::