Changeset 7806f91 for libcfa/src
- Timestamp:
- Jul 25, 2025, 3:29:48 PM (2 months ago)
- Branches:
- master
- Children:
- 1eea589f, 29c6a7d
- Parents:
- 7640ff5
- Location:
- libcfa/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/collections/list.hfa
r7640ff5 r7806f91 80 80 // part), by failing fast. 81 81 82 #if defined( __x86_64 ) 83 // Preferred case: tag in the most-significant bit. Dereference has been shown to segfault consistently. 84 // Maintenance should list more architectures as "ok" here, to let them use the preferred case, when valid. 85 #define ORIGIN_TAG_BITNO ( 8 * sizeof( size_t ) - 1 ) 86 #else 87 // Fallback case: tag in the least-significant bit. Dereference will often give an alignment error, but may not, 88 // e.g. if accessing a char-typed member. 32-bit x86 uses the most- significant bit for real room on the heap. 89 #define ORIGIN_TAG_BITNO 0 82 #ifdef __EXPERIMENTAL_DISABLE_OTAG__ // Perf experimention alt mode 83 84 // With origin tagging disabled, iteration never reports "no more elements." 85 // In this mode, the list API is buggy. 86 // This mode is used to quantify the cost of the normal tagging scheme. 87 88 #define ORIGIN_TAG_SET(p) (p) 89 #define ORIGIN_TAG_CLEAR(p) (p) 90 #define ORIGIN_TAG_QUERY(p) 0 91 #define ORIGIN_TAG_ASGN(p, v) (p) 92 #define ORIGIN_TAG_EITHER(p, v) (p) 93 #define ORIGIN_TAG_NEQ(v1, v2) 0 94 95 #else // Normal 96 97 #if defined( __x86_64 ) 98 // Preferred case: tag in the most-significant bit. Dereference 99 // has been shown to segfault consistently. Maintenance should 100 // list more architectures as "ok" here, to let them use the 101 // preferred case, when valid. 102 #define ORIGIN_TAG_BITNO ( 8 * sizeof( size_t ) - 1 ) 103 #else 104 // Fallback case: tag in the least-significant bit. Dereference 105 // will often give an alignment error, but may not, e.g. if 106 // accessing a char-typed member. 32-bit x86 uses the most- 107 // significant bit for real room on the heap. 108 #define ORIGIN_TAG_BITNO 0 109 #endif 110 111 #define ORIGIN_TAG_MASK (((size_t)1) << ORIGIN_TAG_BITNO) 112 113 #define ORIGIN_TAG_SET(p) ((p) | ORIGIN_TAG_MASK) 114 #define ORIGIN_TAG_CLEAR(p) ((p) & ~ORIGIN_TAG_MASK) 115 #define ORIGIN_TAG_QUERY(p) ((p) & ORIGIN_TAG_MASK) 116 117 #define ORIGIN_TAG_ASGN(p, v) ( \ 118 verify( ! ORIGIN_TAG_QUERY(p) && "p had no tagbit" ), \ 119 ORIGIN_TAG_EITHER((p), (v)) \ 120 ) 121 122 #define ORIGIN_TAG_EITHER(p, v) ( \ 123 verify( ! ORIGIN_TAG_CLEAR(v) && "v is a pure tagbit" ), \ 124 ( (p) | (v) ) \ 125 ) 126 127 #define ORIGIN_TAG_NEQ(v1, v2) ( \ 128 verify( ! ORIGIN_TAG_CLEAR(v1) && "v1 is a pure tagbit" ), \ 129 verify( ! ORIGIN_TAG_CLEAR(v2) && "v2 is a pure tagbit" ), \ 130 ( (v1) ^ (v2) ) \ 131 ) 132 90 133 #endif 91 #define ORIGIN_TAG_MASK (((size_t)1) << ORIGIN_TAG_BITNO) 92 93 #define ORIGIN_TAG_SET( p ) ((p) | ORIGIN_TAG_MASK) 94 #define ORIGIN_TAG_CLEAR( p ) ((p) & ~ORIGIN_TAG_MASK) 95 #define ORIGIN_TAG_QUERY( p ) ((p) & ORIGIN_TAG_MASK) 134 135 136 137 #ifdef __EXPERIMENTAL_LOOSE_SINGLES__ // Perf experimention alt mode 138 139 // In loose-singles mode, the ability to answer an "is listed" query is disabled, as is "to insert an element, 140 // it must not be listed already" checking. The user must know separately whether an element is listed. 141 // Other than inserting it, any list-api action on an unlisted element is undefined. Notably, list iteration 142 // starting from an unlisted element is not defined to respond "no more elements," and may instead continue 143 // iterating from a formerly occupied list position. This mode matches LQ usage. 144 145 #define NOLOOSE(...) 146 #define LOOSEONLY(...) __VA_ARGS__ 147 148 #else // Normal 149 150 #define NOLOOSE(...) __VA_ARGS__ 151 #define LOOSEONLY(...) 152 153 #endif 154 155 156 157 96 158 97 159 forall( tE & ) { … … 102 164 103 165 static inline void ?{}( dlink( tE ) & this ) { 166 NOLOOSE( 104 167 this.next = this.prev = 0p; 168 ) 105 169 } 106 170 … … 129 193 static inline forall( tE &, tLinks & | embedded( tE, tLinks, dlink( tE ) ) ) { 130 194 bool isListed( tE & node ) { 195 NOLOOSE( 131 196 verify( &node != 0p ); 132 197 dlink( tE ) & node_links = node`inner; 133 198 return (node_links.prev != 0p) || (node_links.next != 0p); 199 ) 200 LOOSEONLY( 201 verify(false && "isListed is undefined"); 202 return true; 203 ) 134 204 } 135 205 … … 157 227 158 228 dlink( tE ) & linkToInsert = node`inner; 159 229 NOLOOSE( 160 230 verify( linkToInsert.next == 0p ); 161 231 verify( linkToInsert.prev == 0p ); 232 ) 162 233 163 234 tE & list_pos_elem = *(tE *)ORIGIN_TAG_CLEAR( (size_t)&before ); … … 180 251 181 252 dlink( tE ) & linkToInsert = node`inner; 182 253 NOLOOSE( 183 254 verify( linkToInsert.prev == 0p ); 184 255 verify( linkToInsert.next == 0p ); 256 ) 185 257 186 258 tE & list_pos_elem = *(tE *)ORIGIN_TAG_CLEAR( (size_t)&after ); … … 211 283 before_links.next = &after_raw; 212 284 after_links.prev = &before_raw; 285 286 NOLOOSE( 213 287 asm( "" : : : "memory" ); 214 288 list_pos_links.prev = 0p; 215 289 list_pos_links.next = 0p; 216 290 asm( "" : : : "memory" ); 291 ) 217 292 return node; 218 293 } -
libcfa/src/stdhdr/assert.h
r7640ff5 r7806f91 38 38 #define warnf( expr, fmt, ... ) ({ static bool check_once##__LINE__ = false; if( false == check_once##__LINE__ && false == (expr)) { check_once##__LINE__ = true; __assert_warn_f(__VSTRINGIFY__(expr), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, ## __VA_ARGS__ ); } }) 39 39 #else 40 #define verify(x) 41 #define verifyf(x, ...) 42 #define verifyfail(...) 43 #define warnf( expr, fmt, ... ) 40 #define verify(x) 0 41 #define verifyf(x, ...) 0 42 #define verifyfail(...) 0 43 #define warnf( expr, fmt, ... ) 0 44 44 #endif 45 45
Note:
See TracChangeset
for help on using the changeset viewer.