diff --git a/src/boehm_gc.c b/src/boehm_gc.c index f7431e6459..e511abedbf 100644 --- a/src/boehm_gc.c +++ b/src/boehm_gc.c @@ -334,6 +334,9 @@ void RetypeBagIntern(Bag bag, UInt new_type) if (old_type == new_type) return; +#if defined(HPCGAP) && defined(USE_HPC_GUARDS) + WriteGuard(bag); +#endif /* change the size-type word */ header->type = new_type; { @@ -456,6 +459,9 @@ UInt ResizeBag(Bag bag, UInt new_size) CollectBags(0, 0); #endif +#if defined(HPCGAP) && defined(USE_HPC_GUARDS) + WriteGuard(bag); +#endif BagHeader * header = BAG_HEADER(bag); /* get type and old size of the bag */ diff --git a/src/gasman.h b/src/gasman.h index 3f566c84be..d0856e45ca 100644 --- a/src/gasman.h +++ b/src/gasman.h @@ -144,6 +144,46 @@ EXPORT_INLINE UInt TNUM_BAG(Bag bag) return BAG_HEADER(bag)->type; } +/**************************************************************************** +** +*F ReadCheck() . . . . . . . . . . . . . is the bag readable in HPCGAP? +*F WriteCheck() . . . . . . . . . . . . is the bag writable in HPCGAP? +*F HandleReadGuardError() . . . . . . . . . . signal read access error +*F HandleWriteGuardError() . . . . . . . . . signal write access error +** +** These funtion handle access checks in HPCGAP, i.e. whether a bag can +** safely be read or modified without causing race conditions. These are +** called in functions such as PTR_BAG() and CONST_PTR_BAG(), which should +** implicitly or explicitly guard all object accesses. In order to access +** objects without triggering checks, alternative functions UNSAFE_PTR_BAG() +** and UNSAFE_CONST_PTR_BAG() are provided. +*/ +#ifdef HPCGAP +extern int ExtendedGuardCheck(Bag) PURE_FUNC; + +EXPORT_INLINE int ReadCheck(Bag bag) +{ + Region *region; + region = REGION(bag); + if (!region) + return 1; + if (region->owner == GetTLS()) + return 1; + if (region->readers[TLS(threadID)]) + return 1; + return ExtendedGuardCheck(bag); +} + +EXPORT_INLINE int WriteCheck(Bag bag) +{ + Region * region; + region = REGION(bag); + return !region || region->owner == GetTLS() || ExtendedGuardCheck(bag); +} + +extern void HandleReadGuardError(Bag) NORETURN; +extern void HandleWriteGuardError(Bag) NORETURN; +#endif // HPCGAP /**************************************************************************** ** @@ -298,33 +338,6 @@ EXPORT_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 -extern int ExtendedGuardCheck(Bag) PURE_FUNC; - -EXPORT_INLINE int ReadCheck(Bag bag) -{ - Region *region; - region = REGION(bag); - if (!region) - return 1; - if (region->owner == GetTLS()) - return 1; - if (region->readers[TLS(threadID)]) - return 1; - return ExtendedGuardCheck(bag); -} - -EXPORT_INLINE int WriteCheck(Bag bag) -{ - Region * region; - region = REGION(bag); - return !region || region->owner == GetTLS() || ExtendedGuardCheck(bag); -} - -extern void HandleReadGuardError(Bag) NORETURN; -extern void HandleWriteGuardError(Bag) NORETURN; -#endif // HPCGAP - EXPORT_INLINE Bag *PTR_BAG(Bag bag) { GAP_ASSERT(bag != 0);