From 05af441d05ade5408f7c4532b0f4e5818ecf5e35 Mon Sep 17 00:00:00 2001 From: David Jones Date: Wed, 9 Jul 2003 16:42:29 +0100 Subject: Mps: can now call mps_arena_has_addr during mps_arena_formatted_objects_walk. test walkt0 is witness Copied from Perforce Change: 50108 ServerID: perforce.ravenbrook.com --- mps/code/global.c | 36 ++++++++++++++++++++++++++++++++---- mps/code/mpm.h | 2 ++ mps/code/mpsi.c | 7 +++++-- 3 files changed, 39 insertions(+), 6 deletions(-) (limited to 'mps/code') diff --git a/mps/code/global.c b/mps/code/global.c index db4a9f2fd0d..051ba680480 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -36,6 +36,9 @@ SRCID(global, "$Id$"); static Bool arenaRingInit = FALSE; static RingStruct arenaRing; /* */ +/* forward declarations */ +void arenaEnterLock(Arena, void (*)(Lock)); +void arenaLeaveLock(Arena, void (*)(Lock)); /* ArenaControlPool -- get the control pool */ @@ -421,15 +424,31 @@ void (ArenaEnter)(Arena arena) #else void ArenaEnter(Arena arena) { + arenaEnterLock(arena, LockClaim); +} +#endif + +void arenaEnterLock(Arena arena, void (*lock)(Lock)) +{ + /* This check is safe to do outside the lock. Unless the client + is also calling ArenaDestroy, but that's a protocol violation by + the client if so. */ AVER(CHECKT(Arena, arena)); StackProbe(StackProbeDEPTH); - LockClaim(ArenaGlobals(arena)->lock); + lock(ArenaGlobals(arena)->lock); AVERT(Arena, arena); /* can't AVER it until we've got the lock */ ShieldEnter(arena); } -#endif +/* Same as ArenaEnter, but for the few functions that need to be + reentrant with respect to some part of the MPS. + For example, mps_arena_has_addr. */ + +void ArenaEnterRecursive(Arena arena) +{ + arenaEnterLock(arena, LockClaimRecursive); +} /* ArenaLeave -- leave the state where you can look at MPM data structures */ @@ -441,14 +460,23 @@ void (ArenaLeave)(Arena arena) } #else void ArenaLeave(Arena arena) +{ + arenaLeaveLock(arena, LockReleaseMPM); +} +#endif + +void arenaLeaveLock(Arena arena, void (*unlock)(Lock)) { AVERT(Arena, arena); ShieldLeave(arena); ProtSync(arena); /* */ - LockReleaseMPM(ArenaGlobals(arena)->lock); + unlock(ArenaGlobals(arena)->lock); } -#endif +void ArenaLeaveRecursive(Arena arena) +{ + arenaLeaveLock(arena, LockReleaseRecursive); +} /* mps_exception_info -- pointer to exception info * diff --git a/mps/code/mpm.h b/mps/code/mpm.h index c2b88250774..e29a902ea32 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -463,6 +463,8 @@ extern void (ArenaLeave)(Arena arena); #define ArenaLeave(arena) UNUSED(arena) #endif +extern void ArenaEnterRecursive(Arena arena); +extern void ArenaLeaveRecursive(Arena arena); extern void (ArenaPoll)(Globals globals); #ifdef MPS_PROD_EPCORE diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c index 316ff6cf03e..d855a68de41 100644 --- a/mps/code/mpsi.c +++ b/mps/code/mpsi.c @@ -451,10 +451,13 @@ mps_bool_t mps_arena_has_addr(mps_arena_t mps_arena, mps_addr_t p) Bool b; Arena arena = (Arena)mps_arena; - ArenaEnter(arena); + /* One of the few functions that can be called + during the call to an MPS function. IE this function + can be called when walking the heap. */ + ArenaEnterRecursive(arena); AVERT(Arena, arena); b = ArenaHasAddr(arena, (Addr)p); - ArenaLeave(arena); + ArenaLeaveRecursive(arena); return b; } -- cgit v1.2.1