- Timestamp:
- Jun 7, 2018, 4:40:05 PM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- b067d9b
- Parents:
- b4e1876 (diff), 08b5a7e (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. - Location:
- src
- Files:
-
- 13 edited
-
Common/SemanticError.cc (modified) (2 diffs)
-
Parser/DeclarationNode.cc (modified) (2 diffs)
-
Parser/TypedefTable.cc (modified) (5 diffs)
-
Parser/TypedefTable.h (modified) (2 diffs)
-
Parser/lex.ll (modified) (2 diffs)
-
Parser/parser.yy (modified) (5 diffs)
-
libcfa/bits/locks.h (modified) (2 diffs)
-
libcfa/concurrency/kernel (modified) (2 diffs)
-
libcfa/concurrency/kernel.c (modified) (12 diffs)
-
libcfa/concurrency/preemption.c (modified) (3 diffs)
-
libcfa/stdhdr/assert.h (modified) (1 diff)
-
prelude/sync-builtins.cf (modified) (2 diffs)
-
tests/preempt_longrun/processor.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Common/SemanticError.cc
rb4e1876 r7951100 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 16 15:01:20201813 // Update Count : 912 // Last Modified On : Thu Jun 7 08:05:26 2018 13 // Update Count : 10 14 14 // 15 15 … … 97 97 void SemanticError( CodeLocation location, std::string error ) { 98 98 SemanticErrorThrow = true; 99 throw SemanticErrorException( location, error);99 throw SemanticErrorException( location, error ); 100 100 } 101 101 -
src/Parser/DeclarationNode.cc
rb4e1876 r7951100 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 6 15:57:50201813 // Update Count : 107 612 // Last Modified On : Thu Jun 7 12:08:55 2018 13 // Update Count : 1079 14 14 // 15 15 … … 545 545 type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier 546 546 } else { // not polymorphic 547 type->aggregate.params = q->type->forall; // make polymorphic type 548 // change implicit typedef from TYPEDEFname to TYPEGENname 549 typedefTable.changeKind( *type->aggregate.name, TYPEGENname ); 547 type->aggregate.params = q->type->forall; // set forall qualifier 550 548 } // if 551 549 } else { // not polymorphic -
src/Parser/TypedefTable.cc
rb4e1876 r7951100 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jun 1 16:54:18201813 // Update Count : 1 5512 // Last Modified On : Thu Jun 7 13:17:56 2018 13 // Update Count : 192 14 14 // 15 15 … … 17 17 #include "TypedefTable.h" 18 18 #include <cassert> // for assert 19 #include <iostream> 19 20 20 21 #if 0 21 #include <iostream>22 22 #define debugPrint( code ) code 23 23 #else … … 27 27 using namespace std; // string, iostream 28 28 29 debugPrint( 30 static const char *kindName( int kind ) { 31 switch ( kind ) { 32 case IDENTIFIER: return "identifier"; 33 case TYPEDEFname: return "typedef"; 34 case TYPEGENname: return "typegen"; 35 default: 36 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl; 37 abort(); 38 } // switch 39 } // kindName 40 ) 41 29 42 TypedefTable::~TypedefTable() { 30 43 if ( ! SemanticErrorThrow && kindTable.currentScope() != 0 ) { 31 std::cerr << "scope failure " << kindTable.currentScope() << endl; 44 cerr << "Error: cfa-cpp internal error, scope failure " << kindTable.currentScope() << endl; 45 abort(); 32 46 } // if 33 47 } // TypedefTable::~TypedefTable … … 44 58 } // TypedefTable::isKind 45 59 46 void TypedefTable::changeKind( const string & identifier, int kind ) {47 KindTable::iterator posn = kindTable.find( identifier );48 if ( posn != kindTable.end() ) posn->second = kind; // exists => update49 } // TypedefTable::changeKind50 51 60 // SKULLDUGGERY: Generate a typedef for the aggregate name so the aggregate does not have to be qualified by 52 61 // "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed if the 53 62 // name is explicitly used. 54 void TypedefTable::makeTypedef( const string & name ) { 63 void TypedefTable::makeTypedef( const string & name, int kind ) { 64 // Check for existence is necessary to handle: 65 // struct Fred {}; 66 // void Fred(); 67 // void fred() { 68 // struct Fred act; // do not add as type in this scope 69 // Fred(); 70 // } 55 71 if ( ! typedefTable.exists( name ) ) { 56 typedefTable.addToEnclosingScope( name, TYPEDEFname, "MTD" );72 typedefTable.addToEnclosingScope( name, kind, "MTD" ); 57 73 } // if 58 74 } // TypedefTable::makeTypedef 59 75 60 void TypedefTable::addToScope( const st d::string & identifier, int kind, const char * locn __attribute__((unused)) ) {76 void TypedefTable::addToScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 61 77 auto scope = kindTable.currentScope(); 62 debugPrint( cerr << "Adding at " << locn << " " << identifier << " as kind " << kind<< " scope " << scope << endl );78 debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl ); 63 79 auto ret = kindTable.insertAt( scope, identifier, kind ); 64 80 if ( ! ret.second ) ret.first->second = kind; // exists => update 65 81 } // TypedefTable::addToScope 66 82 67 void TypedefTable::addToEnclosingScope( const st d::string & identifier, int kind, const char * locn __attribute__((unused)) ) {83 void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 68 84 assert( kindTable.currentScope() >= 1 ); 69 85 auto scope = kindTable.currentScope() - 1; 70 debugPrint( cerr << "Adding +1 at " << locn << " " << identifier << " as kind " << kind<< " scope " << scope << endl );86 debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl ); 71 87 auto ret = kindTable.insertAt( scope, identifier, kind ); 72 88 if ( ! ret.second ) ret.first->second = kind; // exists => update … … 93 109 debugPrint( cerr << endl << "[" << scope << "]" ); 94 110 } // while 95 debugPrint( cerr << " " << (*i).first << ":" << (*i).second);111 debugPrint( cerr << " " << (*i).first << ":" << kindName( (*i).second ) ); 96 112 } // for 97 113 while ( scope > 0 ) { -
src/Parser/TypedefTable.h
rb4e1876 r7951100 10 10 // Created On : Sat May 16 15:24:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 31 23:23:47 201813 // Update Count : 8 312 // Last Modified On : Thu Jun 7 12:10:17 2018 13 // Update Count : 85 14 14 // 15 15 … … 30 30 bool exists( const std::string & identifier ); 31 31 int isKind( const std::string & identifier ) const; 32 void changeKind( const std::string & identifier, int kind ); 33 void makeTypedef( const std::string & name ); 32 void makeTypedef( const std::string & name, int kind = TYPEDEFname ); 34 33 void addToScope( const std::string & identifier, int kind, const char * ); 35 34 void addToEnclosingScope( const std::string & identifier, int kind, const char * ); -
src/Parser/lex.ll
rb4e1876 r7951100 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Wed Jun 6 17:31:09201813 * Update Count : 67 712 * Last Modified On : Thu Jun 7 08:27:40 2018 13 * Update Count : 679 14 14 */ 15 15 … … 452 452 453 453 %% 454 454 455 // ----end of lexer---- 455 456 456 457 void yyerror( const char * errmsg ) { 458 SemanticErrorThrow = true; 457 459 cout << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1 458 460 << ": " << ErrorHelpers::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl; -
src/Parser/parser.yy
rb4e1876 r7951100 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 6 14:53:38201813 // Update Count : 352 212 // Last Modified On : Thu Jun 7 10:07:12 2018 13 // Update Count : 3527 14 14 // 15 15 … … 1826 1826 | aggregate_key attribute_list_opt no_attr_identifier 1827 1827 { 1828 typedefTable.makeTypedef( *$3 );// create typedef1829 if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update1828 typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); // create typedef 1829 //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update 1830 1830 forall = false; // reset 1831 1831 } … … 1834 1834 | aggregate_key attribute_list_opt type_name 1835 1835 { 1836 typedefTable.makeTypedef( *$3->type->symbolic.name ); // create typedef1837 if ( forall ) typedefTable.changeKind( *$3->type->symbolic.name, TYPEGENname ); // possibly update1836 typedefTable.makeTypedef( *$3->type->symbolic.name, forall ? TYPEGENname : TYPEDEFname ); // create typedef 1837 //if ( forall ) typedefTable.changeKind( *$3->type->symbolic.name, TYPEGENname ); // possibly update 1838 1838 forall = false; // reset 1839 1839 } … … 1848 1848 aggregate_key attribute_list_opt no_attr_identifier 1849 1849 { 1850 typedefTable.makeTypedef( *$3 );1851 if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update1850 typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); 1851 //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update 1852 1852 forall = false; // reset 1853 1853 $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 ); … … 3264 3264 3265 3265 %% 3266 3266 3267 // ----end of grammar---- 3267 3268 -
src/libcfa/bits/locks.h
rb4e1876 r7951100 18 18 #include "bits/debug.h" 19 19 #include "bits/defs.h" 20 #include <assert.h> 21 22 #ifdef __cforall 23 extern "C" { 24 #include <pthread.h> 25 } 26 #endif 20 27 21 28 // pause to prevent excess processor bus usage … … 112 119 __atomic_clear( &this.lock, __ATOMIC_RELEASE ); 113 120 } 121 122 123 #ifdef __CFA_WITH_VERIFY__ 124 extern bool __cfaabi_dbg_in_kernel(); 125 #endif 126 127 struct __bin_sem_t { 128 int_fast8_t counter; 129 pthread_mutex_t lock; 130 pthread_cond_t cond; 131 }; 132 133 static inline void ?{}(__bin_sem_t & this) with( this ) { 134 counter = 0; 135 pthread_mutex_init(&lock, NULL); 136 pthread_cond_init (&cond, NULL); 137 } 138 139 static inline void ^?{}(__bin_sem_t & this) with( this ) { 140 pthread_mutex_destroy(&lock); 141 pthread_cond_destroy (&cond); 142 } 143 144 static inline void wait(__bin_sem_t & this) with( this ) { 145 verify(__cfaabi_dbg_in_kernel()); 146 pthread_mutex_lock(&lock); 147 if(counter != 0) { // this must be a loop, not if! 148 pthread_cond_wait(&cond, &lock); 149 } 150 counter = 1; 151 pthread_mutex_unlock(&lock); 152 } 153 154 static inline void post(__bin_sem_t & this) with( this ) { 155 verify(__cfaabi_dbg_in_kernel()); 156 pthread_mutex_lock(&lock); 157 bool needs_signal = counter == 0; 158 counter = 1; 159 pthread_mutex_unlock(&lock); 160 if (!needs_signal) 161 pthread_cond_signal(&cond); 162 } 114 163 #endif -
src/libcfa/concurrency/kernel
rb4e1876 r7951100 133 133 // Idle lock 134 134 sem_t idleLock; 135 // __bin_sem_t idleLock; 135 136 136 137 // Link lists fields 137 struct {138 struct __dbg_node_proc { 138 139 struct processor * next; 139 140 struct processor * prev; … … 182 183 183 184 // Link lists fields 184 struct {185 struct __dbg_node_cltr { 185 186 cluster * next; 186 187 cluster * prev; -
src/libcfa/concurrency/kernel.c
rb4e1876 r7951100 17 17 #include <stddef.h> 18 18 #include <errno.h> 19 #include <string.h> 19 20 extern "C" { 20 21 #include <stdio.h> … … 50 51 thread_desc * mainThread; 51 52 52 struct { __dllist_t(cluster) list; __spinlock_t lock; } global_clusters; 53 extern "C" { 54 struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters; 55 } 53 56 54 57 //----------------------------------------------------------------------------- … … 150 153 151 154 void ^?{}(processor & this) with( this ){ 152 if( ! do_terminate) {155 if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) { 153 156 __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this); 154 157 terminate(&this); 155 verify( this.do_terminate);158 verify( __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 156 159 verify( kernelTLS.this_processor != &this); 157 160 P( terminated ); … … 199 202 200 203 thread_desc * readyThread = NULL; 201 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ )204 for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ ) 202 205 { 203 206 readyThread = nextThread( this->cltr ); … … 218 221 else 219 222 { 220 spin(this, &spin_count); 223 // spin(this, &spin_count); 224 halt(this); 221 225 } 222 226 } … … 545 549 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 546 550 547 global_clusters.list{ __get };548 global_clusters.lock{};551 __cfa_dbg_global_clusters.list{ __get }; 552 __cfa_dbg_global_clusters.lock{}; 549 553 550 554 // Initialize the main cluster … … 627 631 // When its coroutine terminates, it return control to the mainThread 628 632 // which is currently here 629 mainProcessor->do_terminate = true;633 __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE); 630 634 returnToKernel(); 635 mainThread->self_cor.state = Halted; 631 636 632 637 // THE SYSTEM IS NOW COMPLETELY STOPPED … … 644 649 ^(mainThread){}; 645 650 646 ^( global_clusters.list){};647 ^( global_clusters.lock){};651 ^(__cfa_dbg_global_clusters.list){}; 652 ^(__cfa_dbg_global_clusters.lock){}; 648 653 649 654 __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n"); … … 655 660 656 661 void halt(processor * this) with( *this ) { 662 verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 663 657 664 with( *cltr ) { 658 665 lock (proc_list_lock __cfaabi_dbg_ctx2); … … 664 671 __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this); 665 672 666 verify( ({int sval = 0; sem_getvalue(&this->idleLock, &sval); sval; }) < 200); 673 // #ifdef __CFA_WITH_VERIFY__ 674 // int sval = 0; 675 // sem_getvalue(&this->idleLock, &sval); 676 // verifyf(sval < 200, "Binary semaphore reached value %d : \n", sval); 677 // #endif 678 679 verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 667 680 int __attribute__((unused)) ret = sem_wait(&idleLock); 668 verify(ret > 0 || errno == EINTR); 681 // verifyf(ret >= 0 || errno == EINTR, "Sem_wait returned %d (errno %d : %s\n", ret, errno, strerror(errno)); 682 683 // wait( idleLock ); 669 684 670 685 __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this); … … 681 696 __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this); 682 697 int __attribute__((unused)) ret = sem_post(&this->idleLock); 683 verify(ret > 0 || errno == EINTR); 684 verify( ({int sval = 0; sem_getvalue(&this->idleLock, &sval); sval; }) < 200); 698 // verifyf(ret >= 0 || errno == EINTR, "Sem_post returned %d (errno %d : %s\n", ret, errno, strerror(errno)); 699 700 // #ifdef __CFA_WITH_VERIFY__ 701 // int sval = 0; 702 // sem_getvalue(&this->idleLock, &sval); 703 // verifyf(sval < 200, "Binary semaphore reached value %d\n", sval); 704 // #endif 705 706 // post( this->idleLock ); 685 707 } 686 708 … … 798 820 // Global Queues 799 821 void doregister( cluster & cltr ) { 800 lock ( global_clusters.lock __cfaabi_dbg_ctx2);801 push_front( global_clusters.list, cltr );802 unlock ( global_clusters.lock );822 lock ( __cfa_dbg_global_clusters.lock __cfaabi_dbg_ctx2); 823 push_front( __cfa_dbg_global_clusters.list, cltr ); 824 unlock ( __cfa_dbg_global_clusters.lock ); 803 825 } 804 826 805 827 void unregister( cluster & cltr ) { 806 lock ( global_clusters.lock __cfaabi_dbg_ctx2);807 remove( global_clusters.list, cltr );808 unlock( global_clusters.lock );828 lock ( __cfa_dbg_global_clusters.lock __cfaabi_dbg_ctx2); 829 remove( __cfa_dbg_global_clusters.list, cltr ); 830 unlock( __cfa_dbg_global_clusters.lock ); 809 831 } 810 832 -
src/libcfa/concurrency/preemption.c
rb4e1876 r7951100 265 265 // kill wrapper : signal a processor 266 266 void terminate(processor * this) { 267 this->do_terminate = true; 268 wake(this); 267 disable_interrupts(); 268 __atomic_store_n(&this->do_terminate, true, __ATOMIC_SEQ_CST); 269 wake( this ); 269 270 sigval_t value = { PREEMPT_TERMINATE }; 271 enable_interrupts( __cfaabi_dbg_ctx ); 270 272 pthread_sigqueue( this->kernel_thread, SIGUSR1, value ); 271 273 } … … 369 371 choose(sfp->si_value.sival_int) { 370 372 case PREEMPT_NORMAL : ;// Normal case, nothing to do here 371 case PREEMPT_TERMINATE: verify( kernelTLS.this_processor->do_terminate);373 case PREEMPT_TERMINATE: verify( __atomic_load_n( &kernelTLS.this_processor->do_terminate, __ATOMIC_SEQ_CST ) ); 372 374 default: 373 375 abort( "internal error, signal value is %d", sfp->si_value.sival_int ); … … 488 490 } 489 491 492 #ifdef __CFA_WITH_VERIFY__ 493 bool __cfaabi_dbg_in_kernel() { 494 return !kernelTLS.preemption_state.enabled; 495 } 496 #endif 497 490 498 // Local Variables: // 491 499 // mode: c // -
src/libcfa/stdhdr/assert.h
rb4e1876 r7951100 33 33 #define verify(x) assert(x) 34 34 #define verifyf(x, ...) assertf(x, __VA_ARGS__) 35 #define __CFA_WITH_VERIFY__ 35 36 #else 36 37 #define verify(x) -
src/prelude/sync-builtins.cf
rb4e1876 r7951100 248 248 #endif 249 249 250 _Bool __atomic_load_n(const volatile _Bool *, int); 251 void __atomic_load(const volatile _Bool *, volatile _Bool *, int); 250 252 char __atomic_load_n(const volatile char *, int); 251 253 char __atomic_load_1(const volatile char *, int); … … 285 287 286 288 void __atomic_store_n(volatile _Bool *, _Bool, int); 287 void __atomic_store_1(volatile _Bool *, _Bool, int);288 289 void __atomic_store(volatile _Bool *, _Bool *, int); 289 290 void __atomic_store_n(volatile char *, char, int); -
src/tests/preempt_longrun/processor.c
rb4e1876 r7951100 2 2 #include <thread> 3 3 #include <time> 4 5 #include <unistd.h> 4 6 5 7 #ifndef PREEMPTION_RATE … … 15 17 int main(int argc, char* argv[]) { 16 18 processor * p[15]; 19 write(STDERR_FILENO, "Preparing\n", sizeof("Preparing\n")); 17 20 for ( int pi = 0; pi < 15; pi++ ) { 18 21 p[pi] = new(); 19 22 } 23 write(STDERR_FILENO, "Starting\n", sizeof("Starting\n")); 20 24 for ( int i = 0; i < N; i++) { 21 25 int pi = i % 15; … … 23 27 p[pi] = new(); 24 28 } 29 write(STDERR_FILENO, "Stopping\n", sizeof("Stopping\n")); 25 30 for ( int pi = 0; pi < 15; pi++ ) { 26 31 delete( p[pi] ); 27 32 } 33 write(STDERR_FILENO, "Done\n", sizeof("Done\n")); 28 34 }
Note:
See TracChangeset
for help on using the changeset viewer.