Changes in / [576aadb:61a20af]
- Files:
-
- 6 edited
-
libcfa/src/concurrency/locks.hfa (modified) (1 diff)
-
libcfa/src/containers/lockfree.hfa (modified) (4 diffs)
-
src/AST/DeclReplacer.hpp (modified) (1 diff)
-
src/AST/Util.cpp (modified) (2 diffs)
-
src/Validate/HoistStruct.cpp (modified) (6 diffs)
-
tests/concurrency/waituntil/locks.cfa (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.hfa
r576aadb r61a20af 32 32 #include "select.hfa" 33 33 34 #include <fstream.hfa> 35 34 36 // futex headers 35 37 #include <linux/futex.h> /* Definition of FUTEX_* constants */ -
libcfa/src/containers/lockfree.hfa
r576aadb r61a20af 199 199 200 200 forall( T & ) 201 struct LinkData {202 T * volatile top; // pointer to stack top203 uintptr_t count; // count each push204 };205 206 forall( T & )207 201 union Link { 208 LinkData(T) data; 202 struct { // 32/64-bit x 2 203 T * volatile top; // pointer to stack top 204 uintptr_t count; // count each push 205 }; 209 206 #if __SIZEOF_INT128__ == 16 210 207 __int128 // gcc, 128-bit integer … … 223 220 void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; } 224 221 225 T * top( StackLF(T) & this ) with(this) { return stack. data.top; }222 T * top( StackLF(T) & this ) with(this) { return stack.top; } 226 223 227 224 void push( StackLF(T) & this, T & n ) with(this) { 228 225 *( &n )`next = stack; // atomic assignment unnecessary, or use CAA 229 226 for () { // busy wait 230 if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ (LinkData(T))@{ &n, ( &n )`next->data.count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node227 if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ {&n, ( &n )`next->count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node 231 228 } // for 232 229 } // push … … 235 232 Link(T) t @= stack; // atomic assignment unnecessary, or use CAA 236 233 for () { // busy wait 237 if ( t.data.top == 0p ) return 0p; // empty stack ? 238 Link(T) * next = ( t.data.top )`next; 239 if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ (LinkData(T))@{ next->data.top, t.data.count } }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.data.top; // attempt to update top node 234 if ( t.top == 0p ) return 0p; // empty stack ? 235 if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ {( t.top )`next->top, t.count} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.top; // attempt to update top node 240 236 } // for 241 237 } // pop … … 243 239 bool unsafe_remove( StackLF(T) & this, T * node ) with(this) { 244 240 Link(T) * link = &stack; 245 for () { 246 // TODO: Avoiding some problems with double fields access. 247 LinkData(T) * data = &link->data; 248 T * next = (T *)&(*data).top; 249 if ( next == node ) { 250 data->top = ( node )`next->data.top; 241 for() { 242 T * next = link->top; 243 if( next == node ) { 244 link->top = ( node )`next->top; 251 245 return true; 252 246 } 253 if ( next == 0p ) return false;247 if( next == 0p ) return false; 254 248 link = ( next )`next; 255 249 } -
src/AST/DeclReplacer.hpp
r576aadb r61a20af 18 18 #include <unordered_map> 19 19 20 #include "Node.hpp" 21 20 22 namespace ast { 21 23 class DeclWithType; 24 class TypeDecl; 22 25 class Expr; 23 class Node;24 class TypeDecl;25 }26 26 27 namespace ast { 27 namespace DeclReplacer { 28 using DeclMap = std::unordered_map< const DeclWithType *, const DeclWithType * >; 29 using TypeMap = std::unordered_map< const TypeDecl *, const TypeDecl * >; 30 using ExprMap = std::unordered_map< const DeclWithType *, const Expr * >; 28 31 29 namespace DeclReplacer { 30 31 using DeclMap = std::unordered_map< const DeclWithType *, const DeclWithType * >; 32 using TypeMap = std::unordered_map< const TypeDecl *, const TypeDecl * >; 33 using ExprMap = std::unordered_map< const DeclWithType *, const Expr * >; 34 35 const Node * replace( const Node * node, const DeclMap & declMap, bool debug = false ); 36 const Node * replace( const Node * node, const TypeMap & typeMap, bool debug = false ); 37 const Node * replace( const Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false ); 38 const Node * replace( const Node * node, const ExprMap & exprMap); 39 40 } 41 32 const Node * replace( const Node * node, const DeclMap & declMap, bool debug = false ); 33 const Node * replace( const Node * node, const TypeMap & typeMap, bool debug = false ); 34 const Node * replace( const Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false ); 35 const Node * replace( const Node * node, const ExprMap & exprMap); 36 } 42 37 } 43 38 -
src/AST/Util.cpp
r576aadb r61a20af 83 83 } 84 84 85 /// Check that the MemberExpr has an aggregate type and matching member.86 void memberMatchesAggregate( const MemberExpr * expr ) {87 const Type * aggrType = expr->aggregate->result->stripReferences();88 const AggregateDecl * decl = nullptr;89 if ( auto inst = dynamic_cast<const StructInstType *>( aggrType ) ) {90 decl = inst->base;91 } else if ( auto inst = dynamic_cast<const UnionInstType *>( aggrType ) ) {92 decl = inst->base;93 }94 assertf( decl, "Aggregate of member not correct type." );95 96 for ( auto aggrMember : decl->members ) {97 if ( expr->member == aggrMember ) {98 return;99 }100 }101 assertf( false, "Member not found." );102 }103 104 85 struct InvariantCore { 105 86 // To save on the number of visits: this is a kind of composed core. … … 127 108 } 128 109 129 void previsit( const MemberExpr * node ) {130 previsit( (const ParseNode *)node );131 memberMatchesAggregate( node );132 }133 134 110 void postvisit( const Node * node ) { 135 111 no_strong_cycles.postvisit( node ); -
src/Validate/HoistStruct.cpp
r576aadb r61a20af 18 18 #include <sstream> 19 19 20 #include "AST/DeclReplacer.hpp"21 20 #include "AST/Pass.hpp" 22 21 #include "AST/TranslationUnit.hpp" 23 #include "AST/Vector.hpp"24 22 25 23 namespace Validate { … … 53 51 template<typename AggrDecl> 54 52 AggrDecl const * postAggregate( AggrDecl const * ); 55 template<typename InstType>56 InstType const * preCollectionInstType( InstType const * type );57 53 58 54 ast::AggregateDecl const * parent = nullptr; … … 72 68 } 73 69 74 void extendParams( ast::vector<ast::TypeDecl> & dstParams,75 ast::vector<ast::TypeDecl> const & srcParams ) {76 if ( srcParams.empty() ) return;77 78 ast::DeclReplacer::TypeMap newToOld;79 ast::vector<ast::TypeDecl> params;80 for ( ast::ptr<ast::TypeDecl> const & srcParam : srcParams ) {81 ast::TypeDecl * dstParam = ast::deepCopy( srcParam.get() );82 dstParam->init = nullptr;83 newToOld.emplace( srcParam, dstParam );84 for ( auto assertion : dstParam->assertions ) {85 assertion = ast::DeclReplacer::replace( assertion, newToOld );86 }87 params.emplace_back( dstParam );88 }89 spliceBegin( dstParams, params );90 }91 92 70 template<typename AggrDecl> 93 71 AggrDecl const * HoistStructCore::preAggregate( AggrDecl const * decl ) { … … 96 74 mut->parent = parent; 97 75 mut->name = qualifiedName( mut ); 98 extendParams( mut->params, parent->params ); 99 decl = mut; 76 return mut; 77 } else { 78 GuardValue( parent ) = decl; 79 return decl; 100 80 } 101 GuardValue( parent ) = decl;102 return decl;103 81 } 104 82 … … 134 112 } 135 113 136 ast::AggregateDecl const * commonParent(137 ast::AggregateDecl const * lhs, ast::AggregateDecl const * rhs ) {138 for ( auto outer = lhs ; outer ; outer = outer->parent ) {139 for ( auto inner = rhs ; inner ; inner = inner->parent ) {140 if ( outer == inner ) {141 return outer;142 }143 }144 }145 return nullptr;146 }147 148 template<typename InstType>149 InstType const * HoistStructCore::preCollectionInstType( InstType const * type ) {150 if ( !type->base->parent ) return type;151 if ( type->base->params.empty() ) return type;152 153 InstType * mut = ast::mutate( type );154 ast::AggregateDecl const * parent =155 commonParent( this->parent, mut->base->parent );156 assert( parent );157 158 std::vector<ast::ptr<ast::Expr>> args;159 for ( const ast::ptr<ast::TypeDecl> & param : parent->params ) {160 args.emplace_back( new ast::TypeExpr( param->location,161 new ast::TypeInstType( param )162 ) );163 }164 spliceBegin( mut->params, args );165 return mut;166 }167 168 114 template<typename InstType> 169 115 InstType const * preInstType( InstType const * type ) { … … 175 121 176 122 ast::StructInstType const * HoistStructCore::previsit( ast::StructInstType const * type ) { 177 return preInstType( preCollectionInstType( type ));123 return preInstType( type ); 178 124 } 179 125 180 126 ast::UnionInstType const * HoistStructCore::previsit( ast::UnionInstType const * type ) { 181 return preInstType( preCollectionInstType( type ));127 return preInstType( type ); 182 128 } 183 129 -
tests/concurrency/waituntil/locks.cfa
r576aadb r61a20af 2 2 #include <thread.hfa> 3 3 #include <locks.hfa> 4 #include <fstream.hfa>5 4 #include <mutex_stmt.hfa> 6 5
Note:
See TracChangeset
for help on using the changeset viewer.