1 /****************************************************************************
2 **
3 ** This file is part of GAP, a system for computational discrete algebra.
4 **
5 ** Copyright of GAP belongs to its developers, whose names are too numerous
6 ** to list here. Please refer to the COPYRIGHT file for details.
7 **
8 ** SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #ifndef GAP_HPC_GUARD_H
12 #define GAP_HPC_GUARD_H
13
14 #include "hpc/region.h"
15 #include "hpc/tls.h"
16
17 #ifndef HPCGAP
18 #error This header is only meant to be used with HPC-GAP
19 #endif
20
21 #ifdef VERBOSE_GUARDS
22 void WriteGuardError(Bag bag,
23 const char *file, unsigned line, const char *func, const char *expr);
24 void ReadGuardError(Bag bag,
25 const char *file, unsigned line, const char *func, const char *expr);
26 #else
27 void WriteGuardError(Bag bag);
28 void ReadGuardError(Bag bag);
29 #endif
30
31 #ifdef VERBOSE_GUARDS
32 #define WriteGuard(bag) WriteGuardFull(bag, __FILE__, __LINE__, __FUNCTION__, #bag)
WriteGuardFull(Bag bag,const char * file,unsigned line,const char * func,const char * expr)33 static ALWAYS_INLINE Bag WriteGuardFull(Bag bag,
34 const char *file, unsigned line, const char *func, const char *expr)
35 #else
36 static ALWAYS_INLINE Bag WriteGuard(Bag bag)
37 #endif
38 {
39 Region *region;
40 if (!IS_BAG_REF(bag))
41 return bag;
42 region = REGION(bag);
43 if (region && region->owner != GetTLS() && region->alt_owner != GetTLS())
44 WriteGuardError(bag
45 #ifdef VERBOSE_GUARDS
46 , file, line, func, expr
47 #endif
48 );
49 return bag;
50 }
51
ImpliedWriteGuard(Bag bag)52 EXPORT_INLINE Bag ImpliedWriteGuard(Bag bag)
53 {
54 return bag;
55 }
56
CheckWriteAccess(Bag bag)57 EXPORT_INLINE int CheckWriteAccess(Bag bag)
58 {
59 Region *region;
60 if (!IS_BAG_REF(bag))
61 return 1;
62 region = REGION(bag);
63 return !(region && region->owner != GetTLS() && region->alt_owner != GetTLS())
64 || TLS(DisableGuards) >= 2;
65 }
66
CheckExclusiveWriteAccess(Bag bag)67 EXPORT_INLINE int CheckExclusiveWriteAccess(Bag bag)
68 {
69 Region *region;
70 if (!IS_BAG_REF(bag))
71 return 1;
72 region = REGION(bag);
73 if (!region)
74 return 0;
75 return region->owner == GetTLS() || region->alt_owner == GetTLS()
76 || TLS(DisableGuards) >= 2;
77 }
78
79 #ifdef VERBOSE_GUARDS
80 #define ReadGuard(bag) ReadGuardFull(bag, __FILE__, __LINE__, __FUNCTION__, #bag)
ReadGuardFull(Bag bag,const char * file,unsigned line,const char * func,const char * expr)81 static ALWAYS_INLINE Bag ReadGuardFull(Bag bag,
82 const char *file, unsigned line, const char *func, const char *expr)
83 #else
84 static ALWAYS_INLINE Bag ReadGuard(Bag bag)
85 #endif
86 {
87 Region *region;
88 if (!IS_BAG_REF(bag))
89 return bag;
90 region = REGION(bag);
91 if (region && region->owner != GetTLS() &&
92 !region->readers[TLS(threadID)] && region->alt_owner != GetTLS())
93 ReadGuardError(bag
94 #ifdef VERBOSE_GUARDS
95 , file, line, func, expr
96 #endif
97 );
98 return bag;
99 }
100
101
ImpliedReadGuard(Bag bag)102 static ALWAYS_INLINE Bag ImpliedReadGuard(Bag bag)
103 {
104 return bag;
105 }
106
107
CheckReadAccess(Bag bag)108 static ALWAYS_INLINE int CheckReadAccess(Bag bag)
109 {
110 Region *region;
111 if (!IS_BAG_REF(bag))
112 return 1;
113 region = REGION(bag);
114 return !(region && region->owner != GetTLS() &&
115 !region->readers[TLS(threadID)] && region->alt_owner != GetTLS())
116 || TLS(DisableGuards) >= 2;
117 }
118
119 #endif // GAP_HPC_GUARD_H
120