Changeset 00675a1
- Timestamp:
- May 10, 2022, 12:25:05 PM (17 months ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 8faa6612
- Parents:
- 3b80db8 (diff), 7edd5c1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 4 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/plot.py
r3b80db8 r00675a1 33 33 "Ops per threads" : Field('Ops' , 0, False), 34 34 "ns per ops/procs" : Field('ns' , 0, False), 35 "Number of threads" : Field(' thrd', 1, False),35 "Number of threads" : Field('' , 1, False), 36 36 "Total Operations(ops)" : Field('Ops' , 0, False), 37 37 "Ops/sec/procs" : Field('Ops' , 0, False), … … 40 40 "Cycle size (# thrds)" : Field('thrd' , 1, False), 41 41 "Duration (ms)" : Field('ms' , 0, False), 42 "Target QPS" : Field('QPS' , 0, False), 43 "Actual QPS" : Field('QPS' , 0, False), 42 "Target QPS" : Field('' , 0, False), 43 "Actual QPS" : Field('' , 0, False), 44 "Average Read Latency" : Field('us' , 0, True), 44 45 "Median Read Latency" : Field('us' , 0, True), 45 46 "Tail Read Latency" : Field('us' , 0, True), 47 "Average Update Latency": Field('us' , 0, True), 46 48 "Median Update Latency" : Field('us' , 0, True), 47 49 "Tail Update Latency" : Field('us' , 0, True), 50 "Update Ratio" : Field('\%' , 0, False), 48 51 } 49 52 … … 92 95 print("Making Plots") 93 96 94 for name, data in s eries.items():97 for name, data in sorted(series.items()): 95 98 _col = next(colors) 96 99 plt.scatter(data['x'], data['y'], color=_col, label=name, marker='x') -
benchmark/process-mutilate.py
r3b80db8 r00675a1 14 14 parser = argparse.ArgumentParser(description='Python Script to convert output from mutilate to rmit like output') 15 15 parser.add_argument('--out', nargs='?', type=argparse.FileType('w'), default=sys.stdout) 16 parser.add_argument('--var', nargs='?', type=str, default='Target QPS') 16 17 try: 17 18 options = parser.parse_args() … … 31 32 32 33 try: 34 latAvs = fields[1] 33 35 lat50s = fields[6] 34 36 lat99s = fields[9] … … 37 39 38 40 try: 41 latAv = locale.atof(latAvs) 39 42 lat50 = locale.atof(lat50s) 40 43 lat99 = locale.atof(lat99s) … … 42 45 raise Warning("Warning: \"{}\" \"{}\"! can't convert to float".format(lat50s, lat99s)) 43 46 44 return lat 50, lat9947 return latAv, lat50, lat99 45 48 46 49 def want0(line): … … 58 61 try: 59 62 if line.startswith("read"): 60 rlat 50, rlat99 = precentile(line)63 rlatAv, rlat50, rlat99 = precentile(line) 61 64 62 65 elif line.startswith("update"): 63 ulat 50, ulat99 = precentile(line)66 ulatAv, ulat50, ulat99 = precentile(line) 64 67 65 68 elif line.startswith("Total QPS"): … … 84 87 85 88 try: 89 out['Average Read Latency'] = rlatAv 86 90 out['Median Read Latency'] = rlat50 87 91 out['Tail Read Latency'] = rlat99 … … 90 94 91 95 try: 96 out['Average Update Latency'] = ulatAv 92 97 out['Median Update Latency'] = ulat50 93 98 out['Tail Update Latency'] = ulat99 … … 112 117 continue 113 118 114 d = { 'Target QPS': int(rate) }119 d = { options.var : int(rate) } 115 120 116 121 w = extract( f, d ) -
libcfa/src/concurrency/io.cfa
r3b80db8 r00675a1 244 244 245 245 remote = true; 246 __STATS__( false, io.calls.helped++; )246 __STATS__( true, io.calls.helped++; ) 247 247 } 248 248 proc->io.target = MAX; -
libcfa/src/concurrency/locks.cfa
r3b80db8 r00675a1 220 220 221 221 //----------------------------------------------------------------------------- 222 // condition variable222 // Synchronization Locks 223 223 forall(L & | is_blocking_lock(L)) { 224 224 225 //----------------------------------------------------------------------------- 226 // condition variable 225 227 void ?{}( condition_variable(L) & this ){ 226 228 this.lock{}; … … 337 339 bool wait( condition_variable(L) & this, L & l, Duration duration ) with(this) { WAIT_TIME( 0 , &l , duration ) } 338 340 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, &l , duration ) } 341 342 //----------------------------------------------------------------------------- 343 // fast_cond_var 344 void ?{}( fast_cond_var(L) & this ){ 345 this.blocked_threads{}; 346 #ifdef __CFA_DEBUG__ 347 this.lock_used = 0p; 348 #endif 349 } 350 void ^?{}( fast_cond_var(L) & this ){ } 351 352 bool notify_one( fast_cond_var(L) & this ) with(this) { 353 bool ret = ! blocked_threads`isEmpty; 354 if ( ret ) { 355 info_thread(L) & popped = try_pop_front( blocked_threads ); 356 on_notify(*popped.lock, popped.t); 357 } 358 return ret; 359 } 360 bool notify_all( fast_cond_var(L) & this ) with(this) { 361 bool ret = ! blocked_threads`isEmpty; 362 while( ! blocked_threads`isEmpty ) { 363 info_thread(L) & popped = try_pop_front( blocked_threads ); 364 on_notify(*popped.lock, popped.t); 365 } 366 return ret; 367 } 368 369 uintptr_t front( fast_cond_var(L) & this ) with(this) { return blocked_threads`isEmpty ? NULL : blocked_threads`first.info; } 370 bool empty ( fast_cond_var(L) & this ) with(this) { return blocked_threads`isEmpty; } 371 372 void wait( fast_cond_var(L) & this, L & l ) { 373 wait( this, l, 0 ); 374 } 375 376 void wait( fast_cond_var(L) & this, L & l, uintptr_t info ) with(this) { 377 // brand cond lock with lock 378 #ifdef __CFA_DEBUG__ 379 if ( lock_used == 0p ) lock_used = &l; 380 else { assert(lock_used == &l); } 381 #endif 382 info_thread( L ) i = { active_thread(), info, &l }; 383 insert_last( blocked_threads, i ); 384 size_t recursion_count = on_wait( *i.lock ); 385 park( ); 386 on_wakeup(*i.lock, recursion_count); 387 } 339 388 } 340 389 -
libcfa/src/concurrency/locks.hfa
r3b80db8 r00675a1 73 73 static inline void on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); } 74 74 75 //----------------------------------------------------------------------------- 76 // MCS Lock 75 77 struct mcs_node { 76 78 mcs_node * volatile next; … … 98 100 } 99 101 102 //----------------------------------------------------------------------------- 103 // Linear backoff Spinlock 100 104 struct linear_backoff_then_block_lock { 101 105 // Spin lock used for mutual exclusion … … 199 203 200 204 //----------------------------------------------------------------------------- 205 // Fast Block Lock 206 207 // High efficiency minimal blocking lock 208 // - No reacquire for cond var 209 // - No recursive acquisition 210 // - No ownership 211 struct fast_block_lock { 212 // Spin lock used for mutual exclusion 213 __spinlock_t lock; 214 215 // List of blocked threads 216 dlist( thread$ ) blocked_threads; 217 218 bool held:1; 219 }; 220 221 static inline void ?{}( fast_block_lock & this ) with(this) { 222 lock{}; 223 blocked_threads{}; 224 held = false; 225 } 226 static inline void ^?{}( fast_block_lock & this ) {} 227 static inline void ?{}( fast_block_lock & this, fast_block_lock this2 ) = void; 228 static inline void ?=?( fast_block_lock & this, fast_block_lock this2 ) = void; 229 230 // if this is called recursively IT WILL DEADLOCK!!!!! 231 static inline void lock(fast_block_lock & this) with(this) { 232 lock( lock __cfaabi_dbg_ctx2 ); 233 if (held) { 234 insert_last( blocked_threads, *active_thread() ); 235 unlock( lock ); 236 park( ); 237 return; 238 } 239 held = true; 240 unlock( lock ); 241 } 242 243 static inline void unlock(fast_block_lock & this) with(this) { 244 lock( lock __cfaabi_dbg_ctx2 ); 245 /* paranoid */ verifyf( held != false, "Attempt to release lock %p that isn't held", &this ); 246 thread$ * t = &try_pop_front( blocked_threads ); 247 held = ( t ? true : false ); 248 unpark( t ); 249 unlock( lock ); 250 } 251 252 static inline void on_notify(fast_block_lock & this, struct thread$ * t ) { unpark(t); } 253 static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; } 254 static inline void on_wakeup(fast_block_lock & this, size_t recursion ) { } 255 256 //----------------------------------------------------------------------------- 201 257 // is_blocking_lock 202 258 trait is_blocking_lock(L & | sized(L)) { … … 226 282 // Synchronization Locks 227 283 forall(L & | is_blocking_lock(L)) { 284 285 //----------------------------------------------------------------------------- 286 // condition_variable 287 288 // The multi-tool condition variable 289 // - can pass timeouts to wait for either a signal or timeout 290 // - can wait without passing a lock 291 // - can have waiters reacquire different locks while waiting on the same cond var 292 // - has shadow queue 293 // - can be signalled outside of critical sections with no locks held 228 294 struct condition_variable { 229 295 // Spin lock used for mutual exclusion … … 258 324 bool wait( condition_variable(L) & this, L & l, Duration duration ); 259 325 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ); 260 } 326 327 //----------------------------------------------------------------------------- 328 // fast_cond_var 329 330 // The trimmed and slim condition variable 331 // - no internal lock so you must hold a lock while using this cond var 332 // - signalling without holding branded lock is UNSAFE! 333 // - only allows usage of one lock, cond var is branded after usage 334 struct fast_cond_var { 335 // List of blocked threads 336 dlist( info_thread(L) ) blocked_threads; 337 338 #ifdef __CFA_DEBUG__ 339 L * lock_used; 340 #endif 341 }; 342 343 344 void ?{}( fast_cond_var(L) & this ); 345 void ^?{}( fast_cond_var(L) & this ); 346 347 bool notify_one( fast_cond_var(L) & this ); 348 bool notify_all( fast_cond_var(L) & this ); 349 350 uintptr_t front( fast_cond_var(L) & this ); 351 352 bool empty ( fast_cond_var(L) & this ); 353 354 void wait( fast_cond_var(L) & this, L & l ); 355 void wait( fast_cond_var(L) & this, L & l, uintptr_t info ); 356 } -
libcfa/src/concurrency/ready_subqueue.hfa
r3b80db8 r00675a1 83 83 /* paranoid */ verify( node->link.ts != 0 ); 84 84 /* paranoid */ verify( this.anchor.ts != 0 ); 85 /* paranoid */ verify( (this.anchor.ts == MAX) == is_empty ); 85 86 return [node, this.anchor.ts]; 86 87 } … … 93 94 // Return the timestamp 94 95 static inline unsigned long long ts(__intrusive_lane_t & this) { 95 // Cannot verify here since it may not be locked96 // Cannot verify 'emptiness' here since it may not be locked 96 97 /* paranoid */ verify(this.anchor.ts != 0); 97 98 return this.anchor.ts; -
src/AST/Convert.cpp
r3b80db8 r00675a1 93 93 }; 94 94 95 96 97 98 95 template<typename T> 96 Getter<T> get() { 97 return Getter<T>{ *this }; 98 } 99 99 100 100 Label makeLabel(Statement * labelled, const ast::Label& label) { … … 1651 1651 // GET_ACCEPT_1(type, FunctionType), 1652 1652 std::move(forall), 1653 std::move(assertions), 1653 1654 std::move(paramVars), 1654 1655 std::move(returnVars), … … 1664 1665 cache.emplace( old, decl ); 1665 1666 1666 decl->assertions = std::move(assertions);1667 1667 decl->withExprs = GET_ACCEPT_V(withExprs, Expr); 1668 1668 decl->stmts = GET_ACCEPT_1(statements, CompoundStmt); -
src/AST/Copy.cpp
r3b80db8 r00675a1 10 10 // Created On : Thr Nov 11 9:16:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Nov 11 9:28:00 202113 // Update Count : 012 // Last Modified On : Tue May 3 16:28:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 77 77 } 78 78 79 void postvisit( const UniqueExpr * node ) { 80 readonlyInsert( &node->object ); 81 } 82 79 83 void postvisit( const MemberExpr * node ) { 80 84 readonlyInsert( &node->member ); -
src/AST/Decl.cpp
r3b80db8 r00675a1 9 9 // Author : Aaron B. Moss 10 10 // Created On : Thu May 9 10:00:00 2019 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Jan 12 16:54:55 202113 // Update Count : 2 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu May 5 12:10:00 2022 13 // Update Count : 24 14 14 // 15 15 … … 53 53 // --- FunctionDecl 54 54 55 FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name, 55 FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name, 56 56 std::vector<ptr<TypeDecl>>&& forall, 57 57 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, … … 74 74 } 75 75 this->type = ftype; 76 } 77 78 FunctionDecl::FunctionDecl( const CodeLocation & location, const std::string & name, 79 std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions, 80 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 81 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage, 82 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs) 83 : DeclWithType( location, name, storage, linkage, std::move(attrs), fs ), 84 params( std::move(params) ), returns( std::move(returns) ), 85 type_params( std::move( forall) ), assertions( std::move( assertions ) ), 86 type( nullptr ), stmts( stmts ) { 87 FunctionType * type = new FunctionType( (isVarArgs) ? VariableArgs : FixedArgs ); 88 for ( auto & param : this->params ) { 89 type->params.emplace_back( param->get_type() ); 90 } 91 for ( auto & ret : this->returns ) { 92 type->returns.emplace_back( ret->get_type() ); 93 } 94 for ( auto & param : this->type_params ) { 95 type->forall.emplace_back( new TypeInstType( param ) ); 96 } 97 for ( auto & assertion : this->assertions ) { 98 type->assertions.emplace_back( 99 new VariableExpr( assertion->location, assertion ) ); 100 } 101 this->type = type; 76 102 } 77 103 -
src/AST/Decl.hpp
r3b80db8 r00675a1 9 9 // Author : Aaron B. Moss 10 10 // Created On : Thu May 9 10:00:00 2019 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Mar 12 18:25:05 202113 // Update Count : 3 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu May 5 12:09:00 2022 13 // Update Count : 33 14 14 // 15 15 … … 135 135 std::vector< ptr<Expr> > withExprs; 136 136 137 // The difference between the two constructors is in how they handle 138 // assertions. The first constructor uses the assertions from the type 139 // parameters, in the style of the old ast, and puts them on the type. 140 // The second takes an explicite list of assertions and builds a list of 141 // references to them on the type. 142 137 143 FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall, 138 144 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 139 145 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 140 146 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false); 141 // : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)), 142 // stmts( stmts ) {} 147 148 FunctionDecl( const CodeLocation & location, const std::string & name, 149 std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions, 150 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 151 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 152 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false); 143 153 144 154 const Type * get_type() const override; -
src/AST/Expr.hpp
r3b80db8 r00675a1 784 784 public: 785 785 ptr<Expr> expr; 786 ptr<ObjectDecl> object;786 readonly<ObjectDecl> object; 787 787 ptr<VariableExpr> var; 788 788 unsigned long long id; -
src/AST/Node.hpp
r3b80db8 r00675a1 10 10 // Created On : Wed May 8 10:27:04 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Mar 25 10:33:00 202213 // Update Count : 712 // Last Modified On : Mon May 9 10:20:00 2022 13 // Update Count : 8 14 14 // 15 15 … … 49 49 50 50 bool unique() const { return strong_count == 1; } 51 bool isManaged() const {return strong_count > 0; } 51 bool isManaged() const { return strong_count > 0; } 52 bool isReferenced() const { return weak_count > 0; } 52 53 53 54 private: -
src/AST/Stmt.cpp
r3b80db8 r00675a1 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 8 13:00:00 2019 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Feb 2 19:01:20 202213 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 3 15:18:20 2022 13 // Update Count : 4 14 14 // 15 15 16 16 #include "Stmt.hpp" 17 17 18 18 #include "Copy.hpp" 19 19 #include "DeclReplacer.hpp" 20 20 #include "Type.hpp" … … 23 23 24 24 // --- CompoundStmt 25 CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids(other.kids) { 25 CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids() { 26 // Statements can have weak references to them, if that happens inserting 27 // the original node into the new list will put the original node in a 28 // bad state, where it cannot be mutated. To avoid this, just perform an 29 // additional shallow copy on the statement. 30 for ( const Stmt * kid : other.kids ) { 31 if ( kid->isReferenced() ) { 32 kids.emplace_back( ast::shallowCopy( kid ) ); 33 } else { 34 kids.emplace_back( kid ); 35 } 36 } 37 26 38 // when cloning a compound statement, we may end up cloning declarations which 27 39 // are referred to by VariableExprs throughout the block. Cloning a VariableExpr -
src/Common/SemanticError.h
r3b80db8 r00675a1 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 19 10:09:17 201813 // Update Count : 3 112 // Last Modified On : Wed May 4 14:08:26 2022 13 // Update Count : 35 14 14 // 15 15 … … 59 59 {"aggregate-forward-decl" , Severity::Warn , "forward declaration of nested aggregate: %s" }, 60 60 {"superfluous-decl" , Severity::Warn , "declaration does not allocate storage: %s" }, 61 {"superfluous-else" , Severity::Warn , "else clause never executed for empty loop conditional" }, 61 62 {"gcc-attributes" , Severity::Warn , "invalid attribute: %s" }, 62 63 {"c++-like-copy" , Severity::Warn , "Constructor from reference is not a valid copy constructor" }, … … 69 70 AggrForwardDecl, 70 71 SuperfluousDecl, 72 SuperfluousElse, 71 73 GccAttributes, 72 74 CppCopy, … … 79 81 ); 80 82 81 #define SemanticWarning(loc, id, ...) SemanticWarningImpl(loc, id, WarningFormats[(int)id].message, __VA_ARGS__)83 #define SemanticWarning(loc, id, ...) SemanticWarningImpl(loc, id, WarningFormats[(int)id].message, ##__VA_ARGS__) 82 84 83 85 void SemanticWarningImpl (CodeLocation loc, Warning warn, const char * const fmt, ...) __attribute__((format(printf, 3, 4))); -
src/ControlStruct/MultiLevelExit.cpp
r3b80db8 r00675a1 594 594 } 595 595 596 // check if loop node and if so add else clause if it exists 597 const WhileDoStmt * whilePtr = dynamic_cast<const WhileDoStmt *>(kid.get()); 598 if ( whilePtr && whilePtr->else_) ret.push_back(whilePtr->else_); 599 const ForStmt * forPtr = dynamic_cast<const ForStmt *>(kid.get()); 600 if ( forPtr && forPtr->else_) ret.push_back(forPtr->else_); 601 596 602 if ( ! break_label.empty() ) { 597 603 ret.push_back( labelledNullStmt( ret.back()->location, break_label ) ); -
src/Parser/parser.yy
r3b80db8 r00675a1 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 14 16:35:29202213 // Update Count : 527 612 // Last Modified On : Wed May 4 17:22:48 2022 13 // Update Count : 5279 14 14 // 15 15 … … 111 111 112 112 void distInl( DeclarationNode * declaration ) { 113 // distribute EXTENSIONacross all declarations113 // distribute INLINE across all declarations 114 114 for ( DeclarationNode *iter = declaration; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 115 115 iter->set_inLine( true ); … … 1221 1221 1222 1222 iteration_statement: 1223 WHILE '(' ')' statement // CFA => while ( 1 )1223 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1224 1224 { $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); } 1225 | WHILE '(' ')' statement ELSE statement // CFA 1226 { 1227 $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); 1228 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1229 } 1225 1230 | WHILE '(' conditional_declaration ')' statement %prec THEN 1226 1231 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); } … … 1229 1234 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1230 1235 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); } 1231 | DO statement WHILE '(' comma_expression ')' ';' %prec THEN 1236 | DO statement WHILE '(' ')' ELSE statement // CFA 1237 { 1238 $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); 1239 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1240 } 1241 | DO statement WHILE '(' comma_expression ')' ';' 1232 1242 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); } 1233 1243 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1234 1244 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); } 1235 | FOR '(' ')' statement // CFA => for ( ;; )1245 | FOR '(' ')' statement %prec THEN // CFA => for ( ;; ) 1236 1246 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); } 1247 | FOR '(' ')' statement ELSE statement // CFA 1248 { 1249 $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); 1250 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1251 } 1237 1252 | FOR '(' for_control_expression_list ')' statement %prec THEN 1238 1253 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); } … … 2318 2333 { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2319 2334 2320 $$ = DeclarationNode::newEnum( nullptr, $7, true, $3 ) 2335 $$ = DeclarationNode::newEnum( nullptr, $7, true, $3 )->addQualifiers( $5 ); 2321 2336 } 2322 2337 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt … … 2327 2342 '{' enumerator_list comma_opt '}' 2328 2343 { 2329 $$ = DeclarationNode::newEnum( $6, $10, true, $3 ) -> addQualifiers( $5 ) ->addQualifiers( $7 );2344 $$ = DeclarationNode::newEnum( $6, $10, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2330 2345 } 2331 2346 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}' … … 2333 2348 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2334 2349 typedefTable.makeTypedef( *$6->name ); 2335 $$ = DeclarationNode::newEnum( $6->name, $9, true, $3 ) -> addQualifiers( $5 ) ->addQualifiers( $7 );2350 $$ = DeclarationNode::newEnum( $6->name, $9, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2336 2351 } 2337 2352 | enum_type_nobody -
src/Validate/Autogen.cpp
r3b80db8 r00675a1 350 350 name, 351 351 std::move( type_params ), 352 std::move( assertions ), 352 353 std::move( params ), 353 354 std::move( returns ), … … 360 361 // Auto-generated routines are inline to avoid conflicts. 361 362 ast::Function::Specs( ast::Function::Inline ) ); 362 decl->assertions = std::move( assertions );363 363 decl->fixUniqueId(); 364 364 return decl; -
tests/unified_locking/.expect/locks.txt
r3b80db8 r00675a1 23 23 Start Test 12: locked condition variable wait/notify with front() 24 24 Done Test 12 25 Start Test 13: fast block lock and fast cond var single wait/notify 26 Done Test 13 -
tests/unified_locking/locks.cfa
r3b80db8 r00675a1 18 18 condition_variable( linear_backoff_then_block_lock ) c_l; 19 19 20 fast_block_lock f; 21 fast_cond_var( fast_block_lock ) f_c_f; 22 20 23 thread T_C_M_WS1 {}; 21 24 … … 99 102 } 100 103 unlock(l); 104 } 105 } 106 107 thread T_F_C_F_WS1 {}; 108 109 void main( T_F_C_F_WS1 & this ) { 110 for (unsigned int i = 0; i < num_times; i++) { 111 lock(f); 112 if(empty(f_c_f) && i != num_times - 1) { 113 wait(f_c_f,f); 114 }else{ 115 notify_one(f_c_f); 116 unlock(f); 117 } 101 118 } 102 119 } … … 322 339 } 323 340 printf("Done Test 12\n"); 324 } 341 342 printf("Start Test 13: fast block lock and fast cond var single wait/notify\n"); 343 { 344 T_F_C_F_WS1 t1[2]; 345 } 346 printf("Done Test 13\n"); 347 348 }
Note: See TracChangeset
for help on using the changeset viewer.