From e97e1ddab31d5c9caae455af7b786c2211ea870d Mon Sep 17 00:00:00 2001 From: Reimer Behrends Date: Thu, 20 Sep 2018 10:00:40 +0200 Subject: [PATCH] Initial work on tracking spurious guard errors with unward. --- src/gasman.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ src/hpc/thread.c | 16 ++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/gasman.h b/src/gasman.h index 236eb8bbf98..2343fb9819b 100644 --- a/src/gasman.h +++ b/src/gasman.h @@ -38,6 +38,11 @@ #include "system.h" +#ifdef HPCGAP +#include "hpc/region.h" +#include "hpc/tls.h" +#endif + /**************************************************************************** ** @@ -299,13 +304,64 @@ static inline UInt SIZE_BAG_CONTENTS(const void *ptr) { ** the application must inform {\Gasman} that it has changed the bag, by ** calling 'CHANGED_BAG(old)' in the above example (see "CHANGED_BAG"). */ +#ifdef HPCGAP +#define PURE_FUNC __attribute__((pure)) +static inline PURE_FUNC int ReadCheck(Bag bag) +{ + Region *region; + if (!IS_BAG_REF(bag)) + return 1; + region = REGION(bag); + if (!region) + return 1; + if (region->owner == GetTLS()) + return 1; + if (region->readers[TLS(threadID)]) + return 1; + return 0; +} + +static inline PURE_FUNC int WriteCheck(Bag bag) +{ + Region *region; + if (!IS_BAG_REF(bag)) + return 1; + region = REGION(bag); + return !region || region->owner == GetTLS(); +} +#endif // HPCGAP + static inline Bag *PTR_BAG(Bag bag) +{ + GAP_ASSERT(bag != 0); +#ifdef HPCGAP + extern PURE_FUNC int HandleWriteGuardError(Bag); + extern volatile int GuardDummy; + if (!WriteCheck(bag)) + GuardDummy = HandleWriteGuardError(bag); +#endif + return *(Bag**)bag; +} + +static inline Bag *UNSAFE_PTR_BAG(Bag bag) { GAP_ASSERT(bag != 0); return *(Bag**)bag; } static inline const Bag *CONST_PTR_BAG(Bag bag) +{ + GAP_ASSERT(bag != 0); +#ifdef HPCGAP + extern PURE_FUNC int HandleReadGuardError(Bag); + extern volatile int GuardDummy; + if (!ReadCheck(bag)) + GuardDummy = HandleReadGuardError(bag); +#endif + return *(const Bag**)bag; +} + +static inline const Bag *UNSAFE_CONST_PTR_BAG(Bag bag) { GAP_ASSERT(bag != 0); return *(const Bag**)bag; diff --git a/src/hpc/thread.c b/src/hpc/thread.c index 634f0818b7d..3429a2fbdce 100644 --- a/src/hpc/thread.c +++ b/src/hpc/thread.c @@ -1270,4 +1270,20 @@ void ReadGuardError(Obj o) } #endif +// These are temporary debugging functions. + +Int NumReadErrors = 0; +Int NumWriteErrors = 0; +volatile int GuardDummy; + +PURE_FUNC int HandleReadGuardError(Bag bag) { + NumReadErrors++; + return 0; +} + +PURE_FUNC int HandleWriteGuardError(Bag bag) { + NumWriteErrors++; + return 0; +} + #endif