From cf6c484a895cdff351f3ea68afd2d05839a9cfaa Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 9 Sep 2016 11:01:04 +0100 Subject: [PATCH] Lockisheld implementation for generic ("ansi") locks. When CONFIG_THREAD_SINGLE is defined, use the generic lock module rather than compiling out all lock calls via lock.h. (Otherwise test cases that check LockIsHeld will fail.) Copied from Perforce Change: 192254 ServerID: perforce.ravenbrook.com --- mps/code/config.h | 5 +++-- mps/code/lock.h | 21 --------------------- mps/code/lockan.c | 6 ++++++ mps/code/lockix.c | 8 ++++++++ mps/code/lockw3.c | 8 ++++++++ mps/design/config.txt | 3 ++- mps/manual/source/topic/arena.rst | 7 +++++++ 7 files changed, 34 insertions(+), 24 deletions(-) diff --git a/mps/code/config.h b/mps/code/config.h index 5b73c6d8ff3..021acf277c8 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -167,8 +167,9 @@ /* CONFIG_THREAD_SINGLE -- support single-threaded execution only * * This symbol causes the MPS to be built for single-threaded - * execution only, where locks are not needed and so lock operations - * can be defined as no-ops by lock.h. + * execution only, where locks are not needed and so the generic + * ("ANSI") lock module lockan.c can be used instead of the + * platform-specific lock module. */ #if !defined(CONFIG_THREAD_SINGLE) diff --git a/mps/code/lock.h b/mps/code/lock.h index 1b421d9eb40..861ac6c272a 100644 --- a/mps/code/lock.h +++ b/mps/code/lock.h @@ -128,27 +128,6 @@ extern void LockClaimGlobal(void); extern void LockReleaseGlobal(void); -#if defined(LOCK) -/* Nothing to do: functions declared in all lock configurations. */ -#elif defined(LOCK_NONE) -#define LockSize() MPS_PF_ALIGN -#define LockInit(lock) UNUSED(lock) -#define LockFinish(lock) UNUSED(lock) -#define LockClaimRecursive(lock) UNUSED(lock) -#define LockReleaseRecursive(lock) UNUSED(lock) -#define LockClaim(lock) UNUSED(lock) -#define LockRelease(lock) UNUSED(lock) -#define LockIsHeld(lock) ((void)lock, FALSE) -#define LockCheck(lock) ((void)lock, TRUE) -#define LockClaimGlobalRecursive() -#define LockReleaseGlobalRecursive() -#define LockClaimGlobal() -#define LockReleaseGlobal() -#else -#error "No lock configuration." -#endif /* LOCK */ - - #endif /* lock_h */ diff --git a/mps/code/lockan.c b/mps/code/lockan.c index fe5082a6ebf..8b1b61a5243 100644 --- a/mps/code/lockan.c +++ b/mps/code/lockan.c @@ -79,6 +79,12 @@ void (LockReleaseRecursive)(Lock lock) --lock->claims; } +Bool (LockIsHeld)(Lock lock) +{ + AVERT(Lock, lock); + return lock->claims > 0; +} + /* Global locking is performed by normal locks. * A separate lock structure is used for recursive and diff --git a/mps/code/lockix.c b/mps/code/lockix.c index 30fecce488c..4c42d754ba2 100644 --- a/mps/code/lockix.c +++ b/mps/code/lockix.c @@ -45,6 +45,7 @@ SRCID(lockix, "$Id$"); +#if defined(LOCK) /* LockStruct -- the MPS lock structure * @@ -260,6 +261,13 @@ void (LockReleaseGlobal)(void) } +#elif defined(LOCK_NONE) +#include "lockan.c" +#else +#error "No lock configuration." +#endif + + /* C. COPYRIGHT AND LICENSE * * Copyright (C) 2001-2016 Ravenbrook Limited . diff --git a/mps/code/lockw3.c b/mps/code/lockw3.c index 09dea1286fb..a471687514e 100644 --- a/mps/code/lockw3.c +++ b/mps/code/lockw3.c @@ -31,6 +31,7 @@ SRCID(lockw3, "$Id$"); +#if defined(LOCK) /* .lock.win32: Win32 lock structure; uses CRITICAL_SECTION */ typedef struct LockStruct { @@ -165,6 +166,13 @@ void (LockReleaseGlobal)(void) } +#elif defined(LOCK_NONE) +#include "lockan.c" +#else +#error "No lock configuration." +#endif + + /* C. COPYRIGHT AND LICENSE * * Copyright (C) 2001-2016 Ravenbrook Limited . diff --git a/mps/design/config.txt b/mps/design/config.txt index 458ccdfe890..3bf1d96e29c 100644 --- a/mps/design/config.txt +++ b/mps/design/config.txt @@ -542,7 +542,8 @@ platform instead. _`.opt.thread`: ``CONFIG_THREAD_SINGLE`` causes the MPS to be built for single-threaded execution only, where locks are not needed and so -lock operations can be defined as no-ops by ``lock.h``. +the generic ("ANSI") lock module ``lockan.c`` can be used instead of +the platform-specific lock module. _`.opt.poll`: ``CONFIG_POLL_NONE`` causes the MPS to be built without support for polling. This means that garbage collections will only diff --git a/mps/manual/source/topic/arena.rst b/mps/manual/source/topic/arena.rst index 4fce7a968bb..035f12308ce 100644 --- a/mps/manual/source/topic/arena.rst +++ b/mps/manual/source/topic/arena.rst @@ -983,6 +983,13 @@ Arena introspection and debugging mps_arena_postmortem(arena); } + .. warning:: + + This function only gives a reliable result in single-threaded + programs, and in multi-threaded programs where all threads but + one are known to be stopped (as they are when the debugger is + decoding the call stack in the use case described above). + .. c:function:: mps_bool_t mps_arena_has_addr(mps_arena_t arena, mps_addr_t addr)